using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BleedingMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("BleedingMod")] [assembly: AssemblyTitle("BleedingMod")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 BleedingMod { [BepInPlugin("com.tambistudios.bleeding", "Bleeding", "0.1.0")] public class BleedingPlugin : BaseUnityPlugin { public const string MOD_GUID = "com.tambistudios.bleeding"; public const string MOD_NAME = "Bleeding"; public const string MOD_VERSION = "0.1.0"; public static BleedingPlugin Instance; public static ManualLogSource Logger; public const float THRESHOLD_NORMAL = 20f; public const float THRESHOLD_LOW = 30f; public const float THRESHOLD_HIGH = 10f; public const float DURATION_NORMAL = 30f; public const float DURATION_LOW = 20f; public const float DURATION_HIGH = 60f; internal static readonly Color ColRed = new Color(0.85f, 0.05f, 0.05f, 1f); internal static readonly Color ColBrt = new Color(1f, 0.25f, 0.25f, 1f); private Texture2D _guiTex; private Texture2D _dropTex; private float _pulseTimer; private float _flashTimer; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Instance = this; Logger = ((BaseUnityPlugin)this).Logger; new Harmony("com.tambistudios.bleeding").PatchAll(); Logger.LogInfo((object)"[Bleeding 0.1.0] Loaded."); } public static float GetFallThreshold() { try { float fallDamageMultiplier = Ascents.fallDamageMultiplier; if (fallDamageMultiplier <= 0.001f) { return -1f; } if (fallDamageMultiplier <= 0.6f) { return 30f; } if (fallDamageMultiplier <= 1.5f) { return 20f; } return 10f; } catch { return 20f; } } public static float GetBleedDuration() { try { float fallDamageMultiplier = Ascents.fallDamageMultiplier; if (fallDamageMultiplier <= 0.001f) { return 30f; } if (fallDamageMultiplier <= 0.6f) { return 20f; } if (fallDamageMultiplier <= 1.5f) { return 30f; } return 60f; } catch { return 30f; } } private void Update() { //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_0062: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)((Component)localCharacter).GetComponent() == (Object)null) { ((Component)localCharacter).gameObject.AddComponent(); } if (Input.GetKeyDown((KeyCode)285) && (Object)(object)localCharacter != (Object)null) { Rigidbody componentInChildren = ((Component)localCharacter).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { Vector3 linearVelocity = componentInChildren.linearVelocity; linearVelocity.y = 22f; componentInChildren.linearVelocity = linearVelocity; Logger.LogInfo((object)"[Bleeding] DEBUG: launched up ~25m"); } } BleedingTracker localInstance = BleedingTracker.LocalInstance; if ((Object)(object)localInstance != (Object)null && localInstance.isBleeding) { float num = 0.8f + localInstance.severity * 0.35f; _pulseTimer += Time.deltaTime * num; } else { _pulseTimer = 0f; } if (_flashTimer > 0f) { _flashTimer = Mathf.Max(0f, _flashTimer - Time.deltaTime); } } private static Texture2D LoadDropTexture() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown try { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "assets", "blood.png"); if (File.Exists(path)) { byte[] array = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; if (ImageConversion.LoadImage(val, array)) { Logger.LogInfo((object)"[Bleeding] Loaded blood.png from assets."); return val; } } } catch (Exception ex) { Logger.LogWarning((object)("[Bleeding] LoadDropTexture: " + ex.Message)); } Logger.LogInfo((object)"[Bleeding] assets/blood.png not found, using procedural drop."); return MakeDropTexture(64); } private static Texture2D MakeDropTexture(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //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) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; float num = (float)size * 0.5f; float num2 = (float)size * 0.42f; float num3 = (float)size * 0.3f; float num4 = (float)size * 0.94f; Color32[] array = (Color32[])(object)new Color32[size * size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num5 = (float)j + 0.5f; float num6 = (float)i + 0.5f; float num7 = num5 - num; float num8 = num6 - num2; bool flag = num7 * num7 + num8 * num8 <= num3 * num3; float num9 = ((num6 >= num2 && num6 <= num4) ? ((num4 - num6) / (num4 - num2) * num3) : 0f); bool num10 = num6 > num2 && num6 <= num4 && Mathf.Abs(num5 - num) <= num9; float num11 = Mathf.Sqrt(num7 * num7 + num8 * num8); float num12 = Mathf.Clamp01(1f - (num11 - num3 + 1.5f) / 1.5f); byte b = (num10 ? byte.MaxValue : (flag ? byte.MaxValue : ((byte)(num12 * 255f)))); array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array); val.Apply(); return val; } internal void TriggerHurtEffect(Character local) { _flashTimer = 1f; try { Type typeFromHandle = typeof(IllegalScreenEffect); FieldInfo field = typeFromHandle.GetField("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo method = typeFromHandle.GetMethod("AddStatus", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(float) }, null); IllegalScreenEffect[] array = Object.FindObjectsOfType(); foreach (IllegalScreenEffect obj in array) { object? obj2 = field?.GetValue(obj); if (!((Object)((obj2 is Character) ? obj2 : null) != (Object)(object)local)) { method?.Invoke(obj, new object[2] { "Injury", 1f }); Logger.LogInfo((object)"[Bleeding] Game hurt screen effect triggered."); break; } } } catch (Exception ex) { Logger.LogWarning((object)("[Bleeding] HurtEffect err: " + ex.Message)); } } private void OnGUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0046: 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_0029: Expected O, but got Unknown //IL_0031: 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_00f1: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) if ((int)Event.current.type != 7) { return; } if ((Object)(object)_guiTex == (Object)null) { _guiTex = new Texture2D(1, 1); _guiTex.SetPixel(0, 0, Color.white); _guiTex.Apply(); } Color color = GUI.color; BleedingTracker localInstance = BleedingTracker.LocalInstance; bool num = (Object)(object)localInstance != (Object)null && localInstance.isBleeding; float num2 = _pulseTimer % 1f; float num3 = ((num2 < 0.2f) ? (num2 / 0.2f) : (1f - (num2 - 0.2f) / 0.8f)); if (num) { float num4 = Mathf.Min(localInstance.severity, 5f); float num5 = 0.2f + num4 * 0.03f; GUI.color = new Color(0.6f, 0f, 0f, num5 + num3 * 0.04f); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_guiTex); } if (_flashTimer > 0f) { GUI.color = new Color(0.55f, 0f, 0f, _flashTimer * 0.5f); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_guiTex); } if (num) { if ((Object)(object)_dropTex == (Object)null) { _dropTex = LoadDropTexture(); } if ((Object)(object)_dropTex != (Object)null) { GUI.color = Color.white; GUI.DrawTexture(new Rect((float)Screen.width - 112f, 16f, 96f, 96f), (Texture)(object)_dropTex); } } GUI.color = color; } } public class BleedingTracker : MonoBehaviour { public static BleedingTracker LocalInstance; public static bool s_isBleeding = false; public static float s_severity = 0f; public static float s_bleedStart = -999f; private float _peakFallSpeed; private bool _wasFalling; private Character _char; private Rigidbody _rb; private bool _loggedInit; public bool isBleeding { get { return s_isBleeding; } set { s_isBleeding = value; } } public float severity { get { return s_severity; } set { s_severity = value; } } public float bleedStart { get { return s_bleedStart; } set { s_bleedStart = value; } } private void Awake() { _char = ((Component)this).GetComponent(); _rb = ((Component)this).GetComponentInChildren(); } private void Update() { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_char == (Object)null || (Object)(object)Character.localCharacter != (Object)(object)_char) { return; } LocalInstance = this; if (!_loggedInit) { _loggedInit = true; BleedingPlugin.Logger.LogInfo((object)("[Bleeding] Tracker active. rb=" + (((Object)(object)_rb != (Object)null) ? ((Object)_rb).name : "NULL"))); } if (s_isBleeding && Time.time - s_bleedStart >= BleedingPlugin.GetBleedDuration()) { s_isBleeding = false; s_severity = 0f; s_bleedStart = -999f; BleedingPlugin.Logger.LogInfo((object)"[Bleeding] Naturally healed."); } if ((Object)(object)_rb == (Object)null) { return; } float y = _rb.linearVelocity.y; if (y < -4f) { _wasFalling = true; _peakFallSpeed = Mathf.Max(_peakFallSpeed, 0f - y); } else { if (!_wasFalling || !(y > -2f)) { return; } float num = _peakFallSpeed * _peakFallSpeed / 19.62f; float fallThreshold = BleedingPlugin.GetFallThreshold(); BleedingPlugin.Logger.LogInfo((object)$"[Bleeding] Impact detected: peakSpeed={_peakFallSpeed:F1} m/s, fallH≈{num:F1}m, thresh={fallThreshold}m"); if (fallThreshold > 0f && num >= fallThreshold) { float num2 = Mathf.Min(num / fallThreshold, 5f); if (!s_isBleeding) { s_bleedStart = Time.time; } s_isBleeding = true; s_severity = Mathf.Max(s_severity, num2); BleedingPlugin.Logger.LogInfo((object)$"[Bleeding] Bleeding triggered! Severity={s_severity:F2}"); BleedingPlugin.Instance?.TriggerHurtEffect(_char); } _wasFalling = false; _peakFallSpeed = 0f; } } public void CureBleeding() { if (s_isBleeding) { s_isBleeding = false; s_severity = 0f; s_bleedStart = -999f; BleedingPlugin.Logger.LogInfo((object)"[Bleeding] Cured by item."); } } } [HarmonyPatch(typeof(Character), "Awake")] internal static class Patch_Character_Awake { [HarmonyPostfix] private static void Postfix(Character __instance) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } [HarmonyPatch(typeof(Character), "CanRegenStamina")] internal static class Patch_CanRegenStamina { [HarmonyPostfix] private static void Postfix(Character __instance, ref bool __result) { if (__instance.IsLocal) { BleedingTracker component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && component.isBleeding) { __result = false; } } } } [HarmonyPatch(typeof(Action_ClearAllStatus), "RunAction")] internal static class Patch_ClearAllStatus { private static readonly FieldInfo _itemField = AccessTools.Field(typeof(Action_ClearAllStatus), "item"); [HarmonyPostfix] private static void Postfix(Action_ClearAllStatus __instance) { try { object? obj = _itemField?.GetValue(__instance); object? obj2 = ((obj is Item) ? obj : null); Character val = ((obj2 != null) ? ((Item)obj2).holderCharacter : null); if (!((Object)(object)val == (Object)null) && val.IsLocal) { ((Component)val).GetComponent()?.CureBleeding(); } } catch (Exception ex) { BleedingPlugin.Logger.LogWarning((object)("[Bleeding] ClearAllStatus patch error: " + ex.Message)); } } } }