using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.Json;
using BloodLabMod.Core;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(BloodLabMod.Core.BloodLabMod), "BloodLabMod", "1.0.0", "fxleons")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BloodLabMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5e16ae1fe7ffb66e8ea5b08c010a9eba18f1c329")]
[assembly: AssemblyProduct("BloodLabMod")]
[assembly: AssemblyTitle("BloodLabMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
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;
}
}
[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 BloodLabMod.Core
{
public class BloodDroplet : MonoBehaviour
{
private Rigidbody rb;
public float Volume { get; private set; }
public Vector3 LastNormal { get; private set; }
public Vector3 Position => transform.position;
public bool IsSettled { get; private set; }
public void Initialize(Vector3 initialVelocity, float volume)
{
if (rb == null)
{
rb = gameObject.GetComponent<Rigidbody>();
}
if (rb == null)
{
rb = gameObject.AddComponent<Rigidbody>();
}
rb.useGravity = true;
rb.velocity = initialVelocity;
rb.mass = Mathf.Clamp(volume * 0.1f, 0.01f, 5f);
Volume = Mathf.Clamp(volume, 0.001f, 1f);
IsSettled = false;
LastNormal = Vector3.up;
}
public void Simulate(float dt)
{
if (rb != null && !IsSettled && rb.velocity.sqrMagnitude < 0.01f && transform.position.y < 10f)
{
IsSettled = true;
if (Physics.Raycast(transform.position, -Vector3.up, out var hit, 0.5f))
{
LastNormal = hit.normal;
}
rb.isKinematic = true;
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.contacts.Length != 0)
{
LastNormal = collision.contacts[0].normal;
}
if (rb != null)
{
rb.velocity = rb.velocity * 0.3f + collision.contacts[0].normal * -0.2f;
}
}
}
public class BloodLabMod : MelonMod
{
private static bool initialized;
public override void OnApplicationStart()
{
if (!initialized)
{
initialized = true;
MelonLogger.Msg("BloodLabMod initializing...");
ConfigManager.Load();
PoolManager.Initialize();
WoundManager.Initialize();
DropletManager.Initialize();
PuddleManager.Initialize();
DecalManager.Initialize();
WeaponBloodManager.Initialize();
PlayerBloodManager.Initialize();
HookManager.Initialize();
}
}
public override void OnUpdate()
{
WoundManager.UpdateAll(Time.deltaTime);
DropletManager.UpdateAll(Time.deltaTime);
PuddleManager.UpdateAll(Time.deltaTime);
WeaponBloodManager.UpdateAll(Time.deltaTime);
PlayerBloodManager.UpdateAll(Time.deltaTime);
}
}
public class BloodPuddle
{
private Vector3 normal;
private float volume;
private GameObject decalGO;
private float age;
public Vector3 Position { get; private set; }
public bool IsExpired => age > ConfigManager.Settings.DecalLifetime * 2f;
public BloodPuddle(Vector3 position, Vector3 normal, float initialVolume)
{
Position = position;
this.normal = normal;
volume = initialVolume;
age = 0f;
SpawnDecal();
}
private void SpawnDecal()
{
GameObject gameObject = Resources.Load<GameObject>("BloodPrefabs/BloodPuddle");
if (gameObject != null)
{
decalGO = GameObject.Instantiate(gameObject);
decalGO.transform.position = Position + normal * 0.01f;
decalGO.transform.rotation = Quaternion.LookRotation(normal);
UpdateVisual();
}
}
public void AddVolume(float v)
{
volume += v;
UpdateVisual();
}
public void Update(float dt)
{
age += dt;
if (decalGO != null)
{
Renderer component = decalGO.GetComponent<Renderer>();
if (component != null && component.material != null)
{
Color bloodColor = ConfigManager.Settings.BloodColor;
float t = Mathf.Clamp01(age * ConfigManager.Settings.BloodDryingSpeed);
component.material.color = Color.Lerp(bloodColor, Color.black, t);
}
}
}
private void UpdateVisual()
{
if (decalGO != null)
{
float num = Mathf.Clamp(0.1f + volume * 0.5f, 0.1f, 5f);
decalGO.transform.localScale = new Vector3(num, 1f, num);
}
}
public void Destroy()
{
if (decalGO != null)
{
GameObject.Destroy(decalGO);
}
}
}
public class BloodWound
{
private float bleedIntensity;
private float lifeTimer;
private float maxLife;
public Transform Parent { get; private set; }
public Vector3 LocalPosition { get; private set; }
public Vector3 Normal { get; private set; }
public float Damage { get; private set; }
public string BodyPart { get; private set; }
public bool IsFinished
{
get
{
if (bleedIntensity <= 0f)
{
return lifeTimer > maxLife;
}
return false;
}
}
public BloodWound(Transform parent, Vector3 localPos, Vector3 normal, float damage, string bodyPart)
{
Parent = parent;
LocalPosition = localPos;
Normal = normal;
Damage = damage;
BodyPart = bodyPart;
bleedIntensity = Mathf.Clamp01(damage * 0.1f);
maxLife = Mathf.Max(30f, damage * 10f) * ConfigManager.Settings.BleedingDurationMultiplier;
lifeTimer = 0f;
DropletManager.SpawnGore(Parent.TransformPoint(LocalPosition), Normal, Mathf.Clamp01(bleedIntensity));
}
public void Update(float dt)
{
lifeTimer += dt;
if (bleedIntensity > 0f)
{
float amount = bleedIntensity * dt * (1f - lifeTimer / maxLife);
DropletManager.SpawnDrip(Parent.TransformPoint(LocalPosition), Normal, amount);
bleedIntensity = Mathf.Max(0f, bleedIntensity - dt * 0.01f);
}
}
}
public static class BodyPartIdentifier
{
public static string Identify(Transform root, Transform hitTransform)
{
if (hitTransform == null)
{
return "unknown";
}
string text = hitTransform.name.ToLower();
if (text.Contains("head") || text.Contains("skull"))
{
return "head";
}
if (text.Contains("spine") || text.Contains("chest") || text.Contains("torso"))
{
return "torso";
}
if (text.Contains("arm") || text.Contains("hand") || text.Contains("shoulder"))
{
return "arm";
}
if (text.Contains("leg") || text.Contains("thigh") || text.Contains("foot"))
{
return "leg";
}
return "limb";
}
}
public static class ConfigManager
{
public class Config
{
public float BloodMultiplier = 1f;
public float PlayerBloodMultiplier = 1f;
public float NPCBloodMultiplier = 1f;
public float BleedingDurationMultiplier = 1f;
public int MaxDroplets = 500;
public int MaxPuddles = 200;
public bool PerformanceMode;
public float DecalLifetime = 300f;
public Color BloodColor = new Color(0.6f, 0.05f, 0.03f, 1f);
public float DripFrequency = 1f;
public float BloodDryingSpeed = 0.01f;
}
public static Config Settings = new Config();
private static string configPath = Path.Combine(Application.dataPath, "BloodLabModConfig.json");
public static void Load()
{
if (File.Exists(configPath))
{
try
{
Settings = JsonUtility.FromJson<Config>(File.ReadAllText(configPath)) ?? new Config();
return;
}
catch
{
Settings = new Config();
return;
}
}
Save();
}
public static void Save()
{
try
{
string contents = JsonUtility.ToJson(Settings, pretty: true);
File.WriteAllText(configPath, contents);
}
catch
{
}
}
}
public struct DamageInfo
{
public Transform Target;
public Vector3 HitPoint;
public Vector3 HitNormal;
public float Damage;
public string BodyPart;
public GameObject Source;
}
public static class DecalManager
{
public static void Initialize()
{
}
public static void SpawnWallSplat(Vector3 pos, Vector3 normal, float size, float intensity)
{
GameObject gameObject = Resources.Load<GameObject>("BloodPrefabs/BloodDecal");
if (gameObject != null)
{
GameObject gameObject2 = GameObject.Instantiate(gameObject);
gameObject2.transform.position = pos + normal * 0.01f;
gameObject2.transform.rotation = Quaternion.LookRotation(normal);
gameObject2.transform.localScale = Vector3.one * Mathf.Clamp(size * intensity, 0.2f, 6f);
Renderer component = gameObject2.GetComponent<Renderer>();
if (component != null && component.material != null)
{
component.material.color = ConfigManager.Settings.BloodColor;
}
GameObject.Destroy(gameObject2, ConfigManager.Settings.DecalLifetime);
}
}
}
public static class DropletManager
{
private static List<BloodDroplet> droplets = new List<BloodDroplet>();
public static void Initialize()
{
}
public static void SpawnGore(Vector3 pos, Vector3 normal, float intensity)
{
int num = Mathf.CeilToInt(Mathf.Clamp(5f * intensity * ConfigManager.Settings.BloodMultiplier, 1f, 50f));
for (int i = 0; i < num; i++)
{
SpawnDroplet(pos + UnityEngine.Random.insideUnitSphere * 0.05f, UnityEngine.Random.onUnitSphere * 0.5f + -normal * 1f, intensity);
}
}
public static void SpawnDrip(Vector3 pos, Vector3 normal, float amount)
{
if (droplets.Count <= ConfigManager.Settings.MaxDroplets && !(amount <= 0.0001f))
{
SpawnDroplet(pos + normal * 0.01f, -normal * UnityEngine.Random.Range(0.1f, 0.3f), amount);
}
}
private static void SpawnDroplet(Vector3 pos, Vector3 velocity, float volume)
{
GameObject gameObject = PoolManager.Get("BloodPrefabs/BloodDroplet");
if (gameObject != null)
{
gameObject.transform.position = pos;
gameObject.transform.rotation = UnityEngine.Random.rotation;
gameObject.SetActive(v: true);
BloodDroplet bloodDroplet = gameObject.GetComponent<BloodDroplet>();
if (bloodDroplet == null)
{
bloodDroplet = gameObject.AddComponent<BloodDroplet>();
}
bloodDroplet.Initialize(velocity, volume);
droplets.Add(bloodDroplet);
}
}
public static void UpdateAll(float dt)
{
for (int num = droplets.Count - 1; num >= 0; num--)
{
BloodDroplet bloodDroplet = droplets[num];
bloodDroplet.Simulate(dt);
if (bloodDroplet.IsSettled)
{
droplets.RemoveAt(num);
PuddleManager.SeedPuddle(bloodDroplet.Position, bloodDroplet.Volume, bloodDroplet.LastNormal);
PoolManager.Release("BloodPrefabs/BloodDroplet", bloodDroplet.gameObject);
}
}
}
}
public class ExampleDamageReceiver : MonoBehaviour
{
public Transform target;
public void SimulateHit(Vector3 worldPos, Vector3 normal, float damage)
{
if (target != null)
{
string bodyPart = BodyPartIdentifier.Identify(target, transform);
HookManager.OnEntityHit(target, worldPos, normal, damage, bodyPart, gameObject);
}
}
}
public static class HookManager
{
public static void Initialize()
{
}
public static void OnEntityHit(Transform entity, Vector3 hitWorldPos, Vector3 hitNormal, float damage, string bodyPart, GameObject hitSource)
{
Vector3 localPos = entity.InverseTransformPoint(hitWorldPos);
WoundManager.CreateWound(entity, localPos, hitNormal, damage, bodyPart);
DropletManager.SpawnGore(hitWorldPos, hitNormal, damage * ConfigManager.Settings.BloodMultiplier);
if (hitSource == null)
{
DecalManager.SpawnWallSplat(hitWorldPos, hitNormal, 1f + damage * 0.5f, Mathf.Clamp01(damage * 0.2f));
}
if (hitSource != null)
{
WeaponBloodManager.AddBloodToWeapon(hitSource.transform, damage * 0.1f);
}
}
}
public static class PlayerBloodManager
{
private static Dictionary<Transform, List<BloodWound>> playerWounds = new Dictionary<Transform, List<BloodWound>>();
public static void Initialize()
{
}
public static void RegisterPlayer(Transform player)
{
if (!playerWounds.ContainsKey(player))
{
playerWounds[player] = new List<BloodWound>();
}
}
public static void AddWound(Transform player, Vector3 localPos, Vector3 normal, float damage, string bodyPart)
{
BloodWound item = WoundManager.CreateWound(player, localPos, normal, damage, bodyPart);
if (!playerWounds.ContainsKey(player))
{
playerWounds[player] = new List<BloodWound>();
}
playerWounds[player].Add(item);
}
public static void UpdateAll(float dt)
{
}
}
public static class PoolManager
{
private static Dictionary<string, Queue<GameObject>> pools = new Dictionary<string, Queue<GameObject>>();
private static GameObject root;
public static void Initialize()
{
root = new GameObject("BloodLab_Pools");
UnityEngine.Object.DontDestroyOnLoad(root);
}
public static GameObject Get(string resourcePath, int initialSize = 10)
{
if (!pools.ContainsKey(resourcePath))
{
pools[resourcePath] = new Queue<GameObject>();
}
Queue<GameObject> queue = pools[resourcePath];
if (queue.Count == 0)
{
GameObject gameObject = Resources.Load<GameObject>(resourcePath);
if (gameObject == null)
{
return null;
}
GameObject gameObject2 = UnityEngine.Object.Instantiate(gameObject, root.transform);
gameObject2.SetActive(v: false);
return gameObject2;
}
return queue.Dequeue();
}
public static void Release(string resourcePath, GameObject obj)
{
if (obj != null)
{
obj.SetActive(v: false);
if (!pools.ContainsKey(resourcePath))
{
pools[resourcePath] = new Queue<GameObject>();
}
pools[resourcePath].Enqueue(obj);
obj.transform.SetParent(root.transform, worldPositionStays: false);
}
}
}
public static class PuddleManager
{
private static List<BloodPuddle> puddles = new List<BloodPuddle>();
public static void Initialize()
{
}
public static void SeedPuddle(Vector3 worldPos, float volume, Vector3 normal)
{
float num = 1f;
BloodPuddle bloodPuddle = null;
float num2 = float.MaxValue;
foreach (BloodPuddle puddle in puddles)
{
float num3 = Vector3.Distance(puddle.Position, worldPos);
if (num3 < num2 && num3 < num)
{
num2 = num3;
bloodPuddle = puddle;
}
}
if (bloodPuddle != null)
{
bloodPuddle.AddVolume(volume);
}
else if (puddles.Count <= ConfigManager.Settings.MaxPuddles)
{
BloodPuddle item = new BloodPuddle(worldPos, normal, volume);
puddles.Add(item);
}
}
public static void UpdateAll(float dt)
{
for (int num = puddles.Count - 1; num >= 0; num--)
{
BloodPuddle bloodPuddle = puddles[num];
bloodPuddle.Update(dt);
if (bloodPuddle.IsExpired)
{
bloodPuddle.Destroy();
puddles.RemoveAt(num);
}
}
}
}
public static class WeaponBloodManager
{
private static Dictionary<Transform, float> weaponBlood = new Dictionary<Transform, float>();
public static void Initialize()
{
}
public static void AddBloodToWeapon(Transform weapon, float amount)
{
if (!weaponBlood.ContainsKey(weapon))
{
weaponBlood[weapon] = 0f;
}
weaponBlood[weapon] += amount;
}
public static void UpdateAll(float dt)
{
foreach (Transform item in new List<Transform>(weaponBlood.Keys))
{
weaponBlood[item] = Mathf.Max(0f, weaponBlood[item] - dt * 0.001f * ConfigManager.Settings.BloodDryingSpeed);
}
}
}
public static class WoundManager
{
private static List<BloodWound> wounds = new List<BloodWound>();
public static void Initialize()
{
}
public static BloodWound CreateWound(Transform parent, Vector3 localPos, Vector3 normal, float damage, string bodyPart)
{
BloodWound bloodWound = new BloodWound(parent, localPos, normal, damage, bodyPart);
wounds.Add(bloodWound);
return bloodWound;
}
public static void UpdateAll(float dt)
{
for (int num = wounds.Count - 1; num >= 0; num--)
{
BloodWound bloodWound = wounds[num];
bloodWound.Update(dt);
if (bloodWound.IsFinished)
{
wounds.RemoveAt(num);
}
}
}
public static IEnumerable<BloodWound> GetWoundsFor(Transform t)
{
foreach (BloodWound wound in wounds)
{
if (wound.Parent == t)
{
yield return wound;
}
}
}
}
}
namespace UnityEngine
{
public struct Vector3
{
public float x;
public float y;
public float z;
public static Vector3 zero => new Vector3(0f, 0f, 0f);
public static Vector3 one => new Vector3(1f, 1f, 1f);
public static Vector3 up => new Vector3(0f, 1f, 0f);
public float sqrMagnitude => x * x + y * y + z * z;
public Vector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public static Vector3 operator -(Vector3 a)
{
return new Vector3(0f - a.x, 0f - a.y, 0f - a.z);
}
public static Vector3 operator +(Vector3 a, Vector3 b)
{
return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
public static Vector3 operator -(Vector3 a, Vector3 b)
{
return new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
}
public static Vector3 operator *(Vector3 a, float s)
{
return new Vector3(a.x * s, a.y * s, a.z * s);
}
public static float Distance(Vector3 a, Vector3 b)
{
float num = a.x - b.x;
float num2 = a.y - b.y;
float num3 = a.z - b.z;
return (float)Math.Sqrt(num * num + num2 * num2 + num3 * num3);
}
}
[StructLayout(LayoutKind.Sequential, Size = 1)]
public struct Quaternion
{
public static Quaternion identity => default(Quaternion);
public static Quaternion LookRotation(Vector3 v)
{
return identity;
}
}
public class Object
{
public string name = "Object";
public static void DontDestroyOnLoad(Object obj)
{
}
public static GameObject Instantiate(GameObject prefab, Transform parent)
{
return GameObject.Instantiate(prefab, parent);
}
}
public static class Application
{
public static string dataPath => Directory.GetCurrentDirectory();
}
public static class ObjectEx
{
public static void DontDestroyOnLoad(Object obj)
{
}
public static GameObject Instantiate(GameObject prefab, Transform parent)
{
return GameObject.Instantiate(prefab, parent);
}
}
public class Component : Object
{
public Transform transform = new Transform();
public GameObject gameObject = new GameObject();
}
public class GameObject : Object
{
public Transform transform = new Transform();
public bool activeSelf = true;
private List<Component> components = new List<Component>();
public GameObject()
{
transform = new Transform();
transform.parent = null;
transform.gameObject = this;
}
public GameObject(string name)
{
base.name = name;
transform = new Transform();
transform.gameObject = this;
}
public void SetActive(bool v)
{
activeSelf = v;
}
public T GetComponent<T>() where T : Component
{
foreach (Component component in components)
{
if (component as T != null)
{
return (T)component;
}
}
return null;
}
public T AddComponent<T>() where T : Component, new()
{
T val = new T
{
gameObject = this,
transform = transform
};
components.Add(val);
return val;
}
public static T Instantiate<T>(T prefab) where T : GameObject
{
return (T)Activator.CreateInstance(typeof(T));
}
public static GameObject Instantiate(GameObject prefab)
{
return new GameObject(prefab?.name ?? "GO");
}
public new static GameObject Instantiate(GameObject prefab, Transform parent)
{
return new GameObject(prefab?.name ?? "GO")
{
transform =
{
parent = parent
}
};
}
public static void Destroy(GameObject go)
{
}
public static void Destroy(GameObject go, float t)
{
}
}
public class Transform : Object
{
public Vector3 position = Vector3.zero;
public Quaternion rotation = Quaternion.identity;
public Transform parent;
public Vector3 localScale = new Vector3(1f, 1f, 1f);
public GameObject gameObject;
public Vector3 TransformPoint(Vector3 p)
{
return position + p;
}
public Vector3 InverseTransformPoint(Vector3 p)
{
return new Vector3(p.x - position.x, p.y - position.y, p.z - position.z);
}
public void SetParent(Transform p, bool worldPositionStays = true)
{
parent = p;
}
}
public class MonoBehaviour : Component
{
}
public class Rigidbody : Component
{
public bool useGravity;
public bool isKinematic;
public Vector3 velocity;
public float mass;
}
public class Renderer : Component
{
public Material material = new Material();
}
public class Material
{
public Color color = new Color(1f, 0f, 0f, 1f);
}
public struct Color
{
public float r;
public float g;
public float b;
public float a;
public static Color black => new Color(0f, 0f, 0f, 1f);
public Color(float r, float g, float b, float a)
{
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
public static Color Lerp(Color a, Color b, float t)
{
return new Color(a.r * (1f - t) + b.r * t, a.g * (1f - t) + b.g * t, a.b * (1f - t) + b.b * t, a.a * (1f - t) + b.a * t);
}
}
public static class Resources
{
public static T Load<T>(string path) where T : class
{
return null;
}
}
public static class Time
{
public static float deltaTime => 0.016f;
}
public static class Random
{
private static readonly System.Random rnd = new System.Random(0);
public static Vector3 insideUnitSphere => new Vector3((float)(rnd.NextDouble() - 0.5), (float)(rnd.NextDouble() - 0.5), (float)(rnd.NextDouble() - 0.5));
public static Vector3 onUnitSphere => insideUnitSphere;
public static Quaternion rotation => Quaternion.identity;
public static float Range(float a, float b)
{
return a + (float)rnd.NextDouble() * (b - a);
}
}
public static class Mathf
{
public static int CeilToInt(float v)
{
return (int)Math.Ceiling(v);
}
public static float Clamp01(float v)
{
if (!(v < 0f))
{
if (!(v > 1f))
{
return v;
}
return 1f;
}
return 0f;
}
public static float Clamp(float v, float a, float b)
{
if (!(v < a))
{
if (!(v > b))
{
return v;
}
return b;
}
return a;
}
public static float Max(float a, float b)
{
if (!(a > b))
{
return b;
}
return a;
}
public static float Lerp(float a, float b, float t)
{
return a + (b - a) * t;
}
}
public class Collision
{
public ContactPoint[] contacts = new ContactPoint[0];
}
public struct ContactPoint
{
public Vector3 normal;
}
public struct RaycastHit
{
public Vector3 point;
public Vector3 normal;
}
public static class Physics
{
public static bool Raycast(Vector3 origin, Vector3 dir, out RaycastHit hit, float max)
{
hit = default(RaycastHit);
return false;
}
}
public static class JsonUtility
{
public static T FromJson<T>(string json)
{
return JsonSerializer.Deserialize<T>(json);
}
public static string ToJson<T>(T obj, bool pretty = false)
{
return JsonSerializer.Serialize(obj);
}
}
}
namespace MelonLoader
{
[AttributeUsage(AttributeTargets.Assembly)]
public sealed class MelonInfoAttribute : Attribute
{
public MelonInfoAttribute(Type t, string name, string version, string author)
{
}
}
public class MelonMod
{
public virtual void OnApplicationStart()
{
}
public virtual void OnUpdate()
{
}
}
public static class MelonLogger
{
public static void Msg(string s)
{
Console.WriteLine(s);
}
}
}