using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.PuppetMasta;
using InjuriesMod.Core;
using InjuriesMod.Modules;
using MelonLoader;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(ModClass), "Brain Injuries", "2.2.0", "PolskiAnt", "https://thunderstore.io/c/bonelab/p/PolskiAnt/BrainInjuries/")]
[assembly: AssemblyTitle("Brain Injuries")]
[assembly: AssemblyDescription("Adds a little realism to the game (PATCH 6)")]
[assembly: MelonColor(255, 200, 30, 20)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("InjuriesMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("InjuriesMod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace InjuriesMod.Patches
{
[HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")]
public static class DamagePatch
{
private static readonly Random rnd = new Random();
public static void Prefix(SubBehaviourHealth __instance, int m, Attack attack)
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Invalid comparison between Unknown and I4
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Invalid comparison between Unknown and I4
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Invalid comparison between Unknown and I4
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Invalid comparison between Unknown and I4
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Invalid comparison between Unknown and I4
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Invalid comparison between Unknown and I4
if (__instance.muscles == null || m >= ((Il2CppArrayBase<StunGroup>)(object)__instance.muscles).Count)
{
return;
}
PuppetMaster puppetMaster = ((SubBehaviourBase)__instance).behaviour.puppetMaster;
if ((Object)(object)puppetMaster == (Object)null)
{
return;
}
ReactionContext reactionContext = new ReactionContext(puppetMaster);
if (!reactionContext.IsValid())
{
return;
}
string text = ((object)((Il2CppArrayBase<StunGroup>)(object)__instance.muscles)[m]/*cast due to .constrained prefix*/).ToString();
if (!DeathTracker.PriorityDeathCause.ContainsKey(reactionContext.Ptr))
{
DeathTracker.LastHitBone[reactionContext.Ptr] = ((text == "Head" && (int)attack.attackType != 2 && (int)attack.attackType != 1) ? "Unknown" : text);
}
if (text == "Head" && (int)attack.attackType == 2 && ModClass.HeadBluntResistEnabled)
{
attack.damage *= 0.7f;
}
if (text == "Head")
{
DeathTracker.LastAttackType[reactionContext.Ptr] = attack.attackType;
DeathTracker.LastAttackDamage[reactionContext.Ptr] = attack.damage;
if (attack.damage > 5f && ((int)attack.attackType == 2 || (int)attack.attackType == 1))
{
DeathTracker.PriorityDeathCause[reactionContext.Ptr] = "Head";
}
if (attack.damage > 2f && attack.damage <= 5f && (int)attack.attackType == 2 && ModClass.UnconsciousEnabled && !DeathTracker.AlreadyDead.Contains(reactionContext.Ptr) && !DeathTracker.UnconsciousNPCs.Contains(reactionContext.Ptr) && rnd.Next(101) <= 50)
{
DeathTracker.UnconsciousNPCs.Add(reactionContext.Ptr);
DeathTracker.UnconsciousStartTime[reactionContext.Ptr] = Time.time;
MelonCoroutines.Start(ModuleD_Consciousness.Unconscious(reactionContext.Puppet));
}
}
if (text == "Spine" && ModClass.TorsoArmorEnabled)
{
attack.damage *= 0.5f;
}
}
}
[HarmonyPatch(typeof(PuppetMaster), "Kill", new Type[] { })]
public static class DeathPatch
{
public static void Postfix(PuppetMaster __instance)
{
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null)
{
return;
}
ReactionContext reactionContext = new ReactionContext(__instance);
if (!reactionContext.IsValid() || DeathTracker.AlreadyDead.Contains(reactionContext.Ptr))
{
return;
}
DeathTracker.AlreadyDead.Add(reactionContext.Ptr);
string value;
string value2;
string text = (DeathTracker.PriorityDeathCause.TryGetValue(reactionContext.Ptr, out value) ? value : ((!DeathTracker.LastHitBone.TryGetValue(reactionContext.Ptr, out value2)) ? "Unknown" : value2));
if (!ModClass.BrainInjuriesEnabled)
{
text = "Disabled";
}
if (DeathTracker.UnconsciousNPCs.Contains(reactionContext.Ptr))
{
((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC died while unconscious.");
PhysicsHelper.ApplyProfile(reactionContext.Puppet);
DeathTracker.UnconsciousNPCs.Remove(reactionContext.Ptr);
return;
}
((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC died | cause: " + text);
if (!(text != "Head"))
{
AttackType value3;
AttackType attackType = (AttackType)((!DeathTracker.LastAttackType.TryGetValue(reactionContext.Ptr, out value3)) ? 64 : ((int)value3));
float value4;
float damage = (DeathTracker.LastAttackDamage.TryGetValue(reactionContext.Ptr, out value4) ? value4 : 0f);
MelonCoroutines.Start(ModuleA_Impact.HandleImpact(reactionContext.Puppet, attackType, damage));
}
}
}
[HarmonyPatch(typeof(PuppetMaster))]
public static class PuppetMasterLifecyclePatches
{
[HarmonyPatch("OnEnable")]
[HarmonyPostfix]
public static void OnEnablePostfix(PuppetMaster __instance)
{
if (!((Object)(object)__instance == (Object)null) && !(((Il2CppObjectBase)__instance).Pointer == IntPtr.Zero))
{
IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer;
if (DeathTracker.TryRegisterSpawn(pointer, out var currentGeneration))
{
PhysicsHelper.EnsureBindPoseCached(__instance);
MelonLogger.Msg($"[Diag] NPC spawned: {pointer}, Gen Token: {currentGeneration}");
}
}
}
[HarmonyPatch("OnDisable")]
[HarmonyPrefix]
public static void OnDisablePrefix(PuppetMaster __instance)
{
if ((Object)(object)__instance != (Object)null && ((Il2CppObjectBase)__instance).Pointer != IntPtr.Zero)
{
PhysicsHelper.ResetProfile(__instance);
DeathTracker.ClearNPC(((Il2CppObjectBase)__instance).Pointer);
}
}
[HarmonyPatch("OnDestroy")]
[HarmonyPrefix]
public static void OnDestroyPrefix(PuppetMaster __instance)
{
if ((Object)(object)__instance != (Object)null && ((Il2CppObjectBase)__instance).Pointer != IntPtr.Zero)
{
PhysicsHelper.ResetProfile(__instance);
DeathTracker.ClearNPC(((Il2CppObjectBase)__instance).Pointer);
}
}
}
}
namespace InjuriesMod.Modules
{
public static class JointSpaceHelper
{
public static Quaternion GetCurrentRelativeRotation(ConfigurableJoint joint, Quaternion initialLocalRotation)
{
//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_0009: 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_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0024: 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_002a: 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_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: 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_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: 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_005b: 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_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
Vector3 axis = ((Joint)joint).axis;
Vector3 val = Vector3.Cross(((Joint)joint).axis, joint.secondaryAxis);
Vector3 normalized = ((Vector3)(ref val)).normalized;
val = Vector3.Cross(normalized, axis);
Vector3 normalized2 = ((Vector3)(ref val)).normalized;
Quaternion val2 = Quaternion.LookRotation(normalized, normalized2);
Quaternion localRotation = ((Component)joint).transform.localRotation;
Quaternion val3 = Quaternion.Inverse(val2);
val3 *= Quaternion.Inverse(localRotation) * initialLocalRotation;
return val3 * val2;
}
}
public static class ModuleA_Impact
{
public enum ImmediateReaction
{
FlaccidParalysis,
None,
Posturing,
ForwardBuckle,
Fencing
}
public enum PostureTendency
{
None,
Flexor,
Extensor,
Mixed
}
public static IEnumerator HandleImpact(PuppetMaster puppet, AttackType attackType, float damage)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (!ModClass.BrainInjuriesEnabled)
{
yield break;
}
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid())
{
yield break;
}
ImmediateReaction reaction = ChooseImmediateReaction(attackType, damage);
if (!ModClass.BrainInjuriesEnabled)
{
reaction = ImmediateReaction.None;
}
((MelonBase)ModClass.Instance).LoggerInstance.Msg($"[ModuleA] Reaction: {reaction}");
if (ModClass.SeizuresEnabled)
{
if (1 == 0)
{
}
float num = (((int)attackType == 1) ? ModClass.SeizureChancePiercing : (((int)attackType != 2) ? 0f : ModClass.SeizureChanceBlunt));
if (1 == 0)
{
}
float seizureChance = num;
if (seizureChance > 0f && DeathTracker.Rng.NextDouble() * 100.0 < (double)seizureChance)
{
ModuleC_Seizures.Start(ctx.Ptr, Random.Range(0.5f, 0.9f), Random.Range(5f, 10f));
}
}
yield return MelonCoroutines.Start(RunImmediateReaction(ctx.Puppet, reaction, attackType, damage));
}
private static PostureTendency ChoosePostureTendency(AttackType attackType)
{
int[] array = new int[3] { 35, 25, 40 };
PostureTendency[] array2 = new PostureTendency[3]
{
PostureTendency.Flexor,
PostureTendency.Extensor,
PostureTendency.Mixed
};
float num = 0f;
float[] array3 = new float[array2.Length];
for (int i = 0; i < array2.Length; i++)
{
float multiplier = ModClass.GetMultiplier(ModClass.PosturingSettings[array2[i]]);
array3[i] = (float)array[i] * multiplier;
num += array3[i];
}
if (num <= 0f)
{
return PostureTendency.None;
}
double num2 = DeathTracker.Rng.NextDouble() * (double)num;
float num3 = 0f;
for (int j = 0; j < array3.Length; j++)
{
num3 += array3[j];
if (num2 < (double)num3)
{
return array2[j];
}
}
return array2[0];
}
private static ImmediateReaction ChooseImmediateReaction(AttackType attackType, float damage)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Invalid comparison between Unknown and I4
if ((int)attackType == 1)
{
int[] baseWeights = new int[4] { 40, 15, 25, 20 };
return WeightedRandom(new ImmediateReaction[4]
{
ImmediateReaction.FlaccidParalysis,
ImmediateReaction.None,
ImmediateReaction.Posturing,
ImmediateReaction.ForwardBuckle
}, baseWeights);
}
if ((int)attackType == 2)
{
if (damage >= 5f)
{
int[] baseWeights2 = new int[5] { 25, 35, 15, 10, 15 };
return WeightedRandom(new ImmediateReaction[5]
{
ImmediateReaction.FlaccidParalysis,
ImmediateReaction.Posturing,
ImmediateReaction.Fencing,
ImmediateReaction.None,
ImmediateReaction.ForwardBuckle
}, baseWeights2);
}
if (damage >= 2f)
{
int[] baseWeights3 = new int[5] { 15, 15, 45, 15, 10 };
return WeightedRandom(new ImmediateReaction[5]
{
ImmediateReaction.FlaccidParalysis,
ImmediateReaction.Posturing,
ImmediateReaction.Fencing,
ImmediateReaction.None,
ImmediateReaction.ForwardBuckle
}, baseWeights3);
}
int[] baseWeights4 = new int[5] { 20, 5, 0, 60, 15 };
return WeightedRandom(new ImmediateReaction[5]
{
ImmediateReaction.FlaccidParalysis,
ImmediateReaction.Posturing,
ImmediateReaction.Fencing,
ImmediateReaction.None,
ImmediateReaction.ForwardBuckle
}, baseWeights4);
}
int[] baseWeights5 = new int[3] { 45, 45, 10 };
return WeightedRandom(new ImmediateReaction[3]
{
ImmediateReaction.FlaccidParalysis,
ImmediateReaction.None,
ImmediateReaction.ForwardBuckle
}, baseWeights5);
}
private static ImmediateReaction WeightedRandom(ImmediateReaction[] options, int[] baseWeights)
{
float num = 0f;
float[] array = new float[options.Length];
for (int i = 0; i < options.Length; i++)
{
float multiplier = ModClass.GetMultiplier(ModClass.UserSettings[options[i]]);
array[i] = (float)baseWeights[i] * multiplier;
num += array[i];
}
if (num <= 0f)
{
return ImmediateReaction.None;
}
double num2 = DeathTracker.Rng.NextDouble() * (double)num;
float num3 = 0f;
for (int j = 0; j < array.Length; j++)
{
num3 += array[j];
if (num2 < (double)num3)
{
return options[j];
}
}
return options[^1];
}
private static IEnumerator RunImmediateReaction(PuppetMaster puppet, ImmediateReaction reaction, AttackType attackType, float damage)
{
//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)
ReactionContext ctx = new ReactionContext(puppet);
if (ctx.IsValid())
{
switch (reaction)
{
case ImmediateReaction.Posturing:
{
PostureTendency tendency = ChoosePostureTendency(attackType);
float intensity = Random.Range(0.6f, 1f);
yield return RunPosturing(onsetDelay: (Random.value < 0.5f) ? 0f : Random.Range(0.1f, 0.4f), blendInTime: Mathf.Lerp(0.5f, 0.15f, intensity), holdTime: Mathf.Lerp(2f, 8f, intensity), puppet: ctx.Puppet, tendency: tendency, intensity: intensity, decayTime: 6f);
break;
}
case ImmediateReaction.FlaccidParalysis:
yield return FlaccidParalysis(ctx.Puppet);
break;
case ImmediateReaction.ForwardBuckle:
yield return ForwardBuckle(ctx.Puppet);
break;
case ImmediateReaction.Fencing:
yield return Fencing(ctx.Puppet);
break;
case ImmediateReaction.None:
yield return Collapse(ctx.Puppet);
break;
}
}
}
private static IEnumerator RunPosturing(PuppetMaster puppet, PostureTendency tendency, float intensity, float onsetDelay, float blendInTime, float holdTime, float decayTime)
{
if (tendency == PostureTendency.None || intensity <= 0f)
{
yield break;
}
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid())
{
yield break;
}
Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
if (onsetDelay > 0f)
{
float delayTimer = 0f;
while (delayTimer < onsetDelay)
{
if (ctx.IsValid())
{
delayTimer += Time.deltaTime;
yield return null;
continue;
}
yield break;
}
}
if (!ctx.IsValid())
{
yield break;
}
Quaternion flexElbow = Quaternion.Euler(50f, 0f, 0f);
Quaternion flexWrist = Quaternion.Euler(50f, 0f, 0f);
Quaternion flexShoulder = Quaternion.Euler(0f, 0f, 0f);
Quaternion extendKneeSubtle = Quaternion.Euler(-8f, 0f, 0f);
Quaternion extendAnkleSubtle = Quaternion.Euler(-20f, 0f, 0f);
Quaternion extElbow = Quaternion.Euler(-50f, 0f, 0f);
Quaternion extWrist = Quaternion.Euler(-40f, 0f, 0f);
Quaternion extShoulder = Quaternion.Euler(-15f, 0f, -15f);
Quaternion extendKnee = Quaternion.Euler(15f, 0f, 0f);
Quaternion extendAnkle = Quaternion.Euler(20f, 0f, 0f);
float totalDuration = blendInTime + holdTime + decayTime;
float e = 0f;
try
{
while (e < totalDuration && ctx.IsValid())
{
ModuleC_Seizures.Tick(ctx.Ptr);
float strength = ((e < blendInTime) ? (Mathf.Clamp01(e / blendInTime) * intensity) : ((!(e < blendInTime + holdTime)) ? Mathf.Lerp(intensity, 0f, (e - blendInTime - holdTime) / decayTime) : intensity));
if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var bindPose))
{
bindPose = PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
}
Dictionary<string, Quaternion> livePose = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, bindPose);
foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle == null)
{
continue;
}
string name = muscle.name.ToLower();
ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)joint == (Object)null || !livePose.TryGetValue(muscle.name, out var currentPose))
{
continue;
}
bool isKnee = name.Contains("knee");
bool isAnkle = name.Contains("ankle");
bool isElbow = name.Contains("elbow");
bool isWrist = name.Contains("wrist");
bool isShoulder = name.Contains("shoulder");
bool isLeg = isKnee || isAnkle || name.Contains("hip");
Quaternion offset = Quaternion.identity;
bool matched = true;
switch (tendency)
{
case PostureTendency.Flexor:
if (isElbow)
{
offset = flexElbow;
}
else if (isWrist)
{
offset = flexWrist;
}
else if (isShoulder)
{
offset = flexShoulder;
}
else if (isKnee)
{
offset = extendKneeSubtle;
}
else if (isAnkle)
{
offset = extendAnkleSubtle;
}
else
{
matched = false;
}
break;
case PostureTendency.Extensor:
if (isElbow)
{
offset = extElbow;
}
else if (isWrist)
{
offset = extWrist;
}
else if (isShoulder)
{
offset = extShoulder;
}
else if (isKnee)
{
offset = extendKnee;
}
else if (isAnkle)
{
offset = extendAnkle;
}
else
{
matched = false;
}
break;
case PostureTendency.Mixed:
if (isElbow)
{
offset = flexElbow;
}
else if (isWrist)
{
offset = flexWrist;
}
else if (isShoulder)
{
offset = flexShoulder;
}
else if (isKnee)
{
offset = extendKnee;
}
else if (isAnkle)
{
offset = extendAnkle;
}
else
{
matched = false;
}
break;
}
if (matched)
{
(float, float) modifiers = ModuleC_Seizures.GetModifiers(ctx.Ptr, muscle.name);
float seizureMultiplier = modifiers.Item1;
float seizureAngleOffset = modifiers.Item2;
Quaternion target = currentPose * Quaternion.Slerp(Quaternion.identity, offset, strength);
target *= Quaternion.Euler(seizureAngleOffset, 0f, 0f);
joint.targetRotation = target;
float legFactor = (isLeg ? 1.5f : 0.7f);
float absoluteMaxForce = (isLeg ? Mathf.Lerp(20f, 400f, strength) : Mathf.Lerp(15f, 200f, strength));
float finalStrength = strength * legFactor * seizureMultiplier;
PhysicsHelper.SetJointDrive(joint, 2300f * finalStrength, 800f * finalStrength, absoluteMaxForce);
muscle.props.muscleWeight = finalStrength;
}
}
e += Time.deltaTime;
yield return null;
bindPose = null;
}
}
finally
{
if ((Object)(object)ctx.Puppet != (Object)null && (Object)(object)ctx.Root != (Object)null)
{
PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
}
}
}
private static IEnumerator ForwardBuckle(PuppetMaster puppet)
{
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid())
{
yield break;
}
Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var _))
{
PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
}
if (!ctx.IsValid())
{
yield break;
}
Rigidbody chestRb = null;
foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (m != null && m.name.ToLower().Contains("chest"))
{
chestRb = ((Component)m.transform).GetComponent<Rigidbody>();
break;
}
}
if ((Object)(object)chestRb != (Object)null)
{
Vector3 forwardDir = -((Component)chestRb).transform.right;
chestRb.AddForce(forwardDir * 5.5f, (ForceMode)2);
}
float fallDuration = Random.Range(1f, 1.3f);
float e1 = 0f;
try
{
while (e1 < fallDuration && ctx.IsValid())
{
ModuleC_Seizures.Tick(ctx.Ptr);
float bendProgress = Mathf.Clamp01(e1 / 0.45f);
float easeBend = bendProgress * bendProgress;
float currentSpring = Mathf.Lerp(900f, 20f, bendProgress);
float currentDamping = Mathf.Lerp(150f, 5f, bendProgress);
float muscleWeight = Mathf.Lerp(0.85f, 0.05f, bendProgress);
foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle == null)
{
continue;
}
string name = muscle.name.ToLower();
ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)joint == (Object)null)
{
continue;
}
var (seizureMultiplier, seizureAngleOffset) = ModuleC_Seizures.GetModifiers(ctx.Ptr, muscle.name);
_ = Quaternion.identity;
Quaternion targetOffset;
if (name.Contains("spine"))
{
targetOffset = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(-75f, 0f, 0f), easeBend);
}
else if (name.Contains("chest"))
{
targetOffset = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(-60f, 0f, 0f), easeBend);
}
else
{
if (!name.Contains("hip"))
{
if (name.Contains("knee"))
{
float kneeSpring = ((e1 < 0.35f) ? 400f : currentSpring);
PhysicsHelper.SetJointDrive(joint, kneeSpring * seizureMultiplier, currentDamping, kneeSpring * seizureMultiplier);
muscle.props.muscleWeight = ((e1 < 0.35f) ? 0.9f : muscleWeight) * seizureMultiplier;
}
continue;
}
targetOffset = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(150f, 0f, 0f), easeBend);
}
joint.targetRotation = targetOffset * Quaternion.Euler(seizureAngleOffset, 0f, 0f);
PhysicsHelper.SetJointDrive(joint, currentSpring * seizureMultiplier, currentDamping, currentSpring * seizureMultiplier);
muscle.props.muscleWeight = muscleWeight * seizureMultiplier;
}
e1 += Time.deltaTime;
yield return null;
}
}
finally
{
PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
}
}
private static IEnumerator FlaccidParalysis(PuppetMaster puppet)
{
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid())
{
yield break;
}
Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var localRotations))
{
localRotations = PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
}
float jerkDuration = Random.Range(0.02f, 0.05f);
float jerkStrength = Random.Range(0.8f, 1.5f);
Dictionary<string, Quaternion> currentPoseBeforeJerk = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, localRotations);
MelonCoroutines.Start(SuppressHitReaction(ctx.Puppet));
Dictionary<string, Quaternion> jerkOffsets = new Dictionary<string, Quaternion>();
foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle != null)
{
Vector3 randEuler = new Vector3(Random.Range(-40f, 40f), Random.Range(-50f, 50f), Random.Range(-30f, 30f));
Quaternion cp;
Quaternion basePose = (currentPoseBeforeJerk.TryGetValue(muscle.name, out cp) ? cp : Quaternion.identity);
jerkOffsets[muscle.name] = basePose * Quaternion.Euler(randEuler);
}
}
ApplyImpactImpulse(ctx.Puppet);
float e0 = 0f;
try
{
while (e0 < jerkDuration)
{
if (!ctx.IsValid())
{
yield break;
}
float t = Mathf.Clamp01(e0 / jerkDuration);
foreach (Muscle muscle2 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle2 != null)
{
ConfigurableJoint joint = ((Component)muscle2.transform).GetComponent<ConfigurableJoint>();
if (!((Object)(object)joint == (Object)null) && jerkOffsets.TryGetValue(muscle2.name, out var offset) && currentPoseBeforeJerk.TryGetValue(muscle2.name, out var basePose2))
{
joint.targetRotation = Quaternion.Slerp(basePose2, offset, t);
PhysicsHelper.SetJointDrive(joint, 2500f * jerkStrength, 400f * jerkStrength, 60f);
muscle2.props.muscleWeight = jerkStrength;
}
}
}
e0 += Time.deltaTime;
yield return null;
}
if (!ctx.IsValid())
{
yield break;
}
float fallTime = Random.Range(0.8f, 1.2f);
float fallStrengthTorso = 0.2f;
float fallStrengthLegs = 0f;
float e1 = 0f;
while (e1 < fallTime)
{
if (!ctx.IsValid())
{
yield break;
}
float localT = e1 / fallTime;
foreach (Muscle muscle3 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle3 != null)
{
string name = muscle3.name.ToLower();
ConfigurableJoint joint2 = ((Component)muscle3.transform).GetComponent<ConfigurableJoint>();
if (!((Object)(object)joint2 == (Object)null))
{
bool isLeg = name.Contains("knee") || name.Contains("ankle") || name.Contains("hip");
float baseStrength = (isLeg ? fallStrengthLegs : fallStrengthTorso);
float currentStrength = Mathf.Lerp(baseStrength, baseStrength * 0.3f, localT);
float absoluteMaxForce = (isLeg ? 2f : 20f);
PhysicsHelper.SetJointDrive(joint2, 300f * currentStrength, 100f * currentStrength, absoluteMaxForce);
muscle3.props.muscleWeight = currentStrength;
}
}
}
e1 += Time.deltaTime;
yield return null;
}
if (!ctx.IsValid())
{
yield break;
}
Dictionary<string, Quaternion> frozenTargets = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, localRotations);
float freezeTime = 0.4f;
float legDecay = 4f;
float torsoDecay = 8f;
float e2 = 0f;
float totalDuration = freezeTime + torsoDecay;
float rampIn = 0.1f;
while (e2 < totalDuration && ctx.IsValid())
{
ModuleC_Seizures.Tick(ctx.Ptr);
foreach (Muscle muscle4 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle4 == null)
{
continue;
}
string name2 = muscle4.name.ToLower();
ConfigurableJoint joint3 = ((Component)muscle4.transform).GetComponent<ConfigurableJoint>();
if (!((Object)(object)joint3 == (Object)null))
{
bool isLeg2 = name2.Contains("knee") || name2.Contains("ankle") || name2.Contains("hip");
float decayDuration = (isLeg2 ? legDecay : torsoDecay);
float localElapsed = Mathf.Max(0f, e2 - freezeTime);
float strength = ((e2 < freezeTime) ? Mathf.Clamp01(e2 / rampIn) : Mathf.Clamp01(1f - localElapsed / decayDuration));
var (seizureMultiplier, seizureAngleOffset) = ModuleC_Seizures.GetModifiers(ctx.Ptr, muscle4.name);
if (frozenTargets.TryGetValue(muscle4.name, out var frozenTarget))
{
joint3.targetRotation = frozenTarget * Quaternion.Euler(seizureAngleOffset, 0f, 0f);
}
float absoluteMaxForce2 = (isLeg2 ? 40f : 25f);
float legFactor = (isLeg2 ? 0.35f : 0.45f);
float finalStrength = strength * legFactor * seizureMultiplier;
PhysicsHelper.SetJointDrive(joint3, 300f * finalStrength, 300f * finalStrength, absoluteMaxForce2);
}
}
e2 += Time.deltaTime;
yield return null;
}
}
finally
{
PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
}
}
private static IEnumerator Collapse(PuppetMaster puppet)
{
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid())
{
yield break;
}
Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
MelonCoroutines.Start(SuppressHitReaction(ctx.Puppet));
if (!ctx.IsValid())
{
yield break;
}
foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle != null)
{
muscle.name.ToLower();
ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
if (!((Object)(object)joint == (Object)null))
{
PhysicsHelper.SetJointDrive(joint, 0f, 0f, 0f);
muscle.props.muscleWeight = 0f;
}
}
}
PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
}
private static IEnumerator Fencing(PuppetMaster puppet)
{
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid())
{
yield break;
}
Dictionary<string, float> originalWeights = PhysicsHelper.SaveMuscleWeights(ctx.Puppet);
if (!DeathTracker.BindPoseRotations.TryGetValue(ctx.Ptr, out var bindPose))
{
bindPose = PhysicsHelper.SaveInitialLocalRotations(ctx.Puppet);
}
float bs = Random.Range(0.25f, 0.35f);
float d = Random.Range(0.6f, 0.8f);
float rt = Random.Range(0.8f, 1.5f);
float e = 0f;
float suppressWindow = 0.3f;
bool leftIsExtended = Random.value < 0.5f;
Quaternion extendedElbow = Quaternion.Euler(-10f, 0f, 0f);
Quaternion extendedShoulder = Quaternion.Euler(70f, 0f, -30f);
Quaternion extendedWrist = Quaternion.Euler(-10f, 0f, 0f);
Quaternion flexedElbow = Quaternion.Euler(110f, 0f, 0f);
Quaternion flexedShoulder = Quaternion.Euler(20f, 0f, 15f);
Quaternion flexedWrist = Quaternion.Euler(60f, 0f, 0f);
try
{
while (e < bs + d + rt && ctx.IsValid())
{
float progress = PhysicsHelper.GetProgress(e, bs, d, rt);
float strength = PhysicsHelper.GetStrength(e, bs, d, rt);
if (e < suppressWindow)
{
foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (m == null)
{
continue;
}
string mName = m.name.ToLower();
if (!mName.Contains("elbow") && !mName.Contains("shoulder") && !mName.Contains("wrist"))
{
Rigidbody rb = ((Component)m.transform).GetComponent<Rigidbody>();
if (!((Object)(object)rb == (Object)null))
{
rb.angularVelocity = Vector3.ClampMagnitude(rb.angularVelocity, 2f);
}
}
}
}
Dictionary<string, Quaternion> currentPose = PhysicsHelper.SaveMuscleCurrentPose(ctx.Puppet, bindPose);
foreach (Muscle muscle in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (muscle == null)
{
continue;
}
string name = muscle.name.ToLower();
ConfigurableJoint joint = ((Component)muscle.transform).GetComponent<ConfigurableJoint>();
if (!((Object)(object)joint == (Object)null) && currentPose.TryGetValue(muscle.name, out var basePose))
{
bool thisArmExtended = (name.Contains("_l") ? leftIsExtended : (!leftIsExtended));
Quaternion offset = Quaternion.identity;
bool matched = true;
if (name.Contains("elbow"))
{
offset = (thisArmExtended ? extendedElbow : flexedElbow);
}
else if (name.Contains("shoulder"))
{
offset = (thisArmExtended ? extendedShoulder : flexedShoulder);
}
else if (name.Contains("wrist"))
{
offset = (thisArmExtended ? extendedWrist : flexedWrist);
}
else
{
matched = false;
}
if (matched)
{
Quaternion target = basePose * Quaternion.Slerp(Quaternion.identity, offset, progress);
joint.targetRotation = target;
PhysicsHelper.SetJointDrive(joint, 2300f * strength, 700f * strength, 900f * strength);
muscle.props.muscleWeight = strength;
}
}
}
e += Time.deltaTime;
yield return null;
}
}
finally
{
PhysicsHelper.RestoreAndResetJoints(ctx.Puppet, originalWeights);
}
}
private static void ApplyImpactImpulse(PuppetMaster puppet)
{
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: 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_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
ReactionContext reactionContext = new ReactionContext(puppet);
if (!reactionContext.IsValid())
{
return;
}
Rigidbody val = null;
Rigidbody val2 = null;
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)reactionContext.Puppet.muscles)
{
if (item != null)
{
string text = item.name.ToLower();
if (text.Contains("head"))
{
val = ((Component)item.transform).GetComponent<Rigidbody>();
}
if (text.Contains("chest"))
{
val2 = ((Component)item.transform).GetComponent<Rigidbody>();
}
}
}
Vector3 val3 = new Vector3(Random.Range(-1f, 1f), Random.Range(-0.2f, 0.3f), Random.Range(-1f, 1f));
Vector3 normalized = ((Vector3)(ref val3)).normalized;
float num = Random.Range(5f, 10f);
if ((Object)(object)val != (Object)null)
{
val.AddForce(normalized * num * 0.2f, (ForceMode)1);
}
if ((Object)(object)val2 != (Object)null)
{
val2.AddForce(normalized * num, (ForceMode)1);
}
}
private static IEnumerator SuppressHitReaction(PuppetMaster puppet, float duration = 0.3f)
{
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid())
{
yield break;
}
float elapsed = 0f;
float maxReasonableSpin = 2f;
while (elapsed < duration && ctx.IsValid())
{
foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (m != null)
{
Rigidbody rb = ((Component)m.transform).GetComponent<Rigidbody>();
if (!((Object)(object)rb == (Object)null))
{
Vector3 av = rb.angularVelocity;
rb.angularVelocity = Vector3.ClampMagnitude(av, maxReasonableSpin);
}
}
}
elapsed += Time.fixedDeltaTime;
yield return (object)new WaitForFixedUpdate();
}
}
}
internal class ModuleC_Seizures
{
public struct SeizureData
{
public float intensity;
public float frequency;
public float elapsed;
public float duration;
}
private static readonly Dictionary<IntPtr, SeizureData> _active = new Dictionary<IntPtr, SeizureData>();
public static void Start(IntPtr ptr, float intensity, float duration)
{
if (ModClass.SeizuresEnabled)
{
_active[ptr] = new SeizureData
{
intensity = Mathf.Clamp01(intensity),
frequency = Mathf.Lerp(3f, 8f, intensity) * 0.8f,
elapsed = 0f,
duration = duration
};
((MelonBase)ModClass.Instance).LoggerInstance.Msg($"[ModuleC] Seizure start | instensity: {intensity} | duration: {duration}");
}
}
public static void Tick(IntPtr ptr)
{
if (_active.TryGetValue(ptr, out var value))
{
value.elapsed += Time.deltaTime;
if (value.elapsed >= value.duration)
{
_active.Remove(ptr);
MelonLogger.Msg("[ModuleC] Seizure ended");
}
else
{
_active[ptr] = value;
}
}
}
public static void Stop(IntPtr ptr)
{
_active.Remove(ptr);
}
public static void Clear(IntPtr ptr)
{
_active.Remove(ptr);
}
public static bool IsActive(IntPtr ptr)
{
return _active.ContainsKey(ptr);
}
public static (float strengthMultiplier, float angleOffset) GetModifiers(IntPtr ptr, string muscleName)
{
if (!ModClass.SeizuresEnabled)
{
return (strengthMultiplier: 1f, angleOffset: 0f);
}
if (!_active.TryGetValue(ptr, out var value))
{
return (strengthMultiplier: 1f, angleOffset: 0f);
}
float num = 1f - Mathf.Clamp01((value.elapsed - value.duration * 0.6f) / (value.duration * 0.4f));
float num2 = value.intensity * num;
float num3 = (float)(muscleName.GetHashCode() % 100) * 0.063f;
float item = 1f + num2 * 2f;
float item2 = Mathf.Sin(value.elapsed * value.frequency * (float)Math.PI * 2f + num3) * 20f * num2;
return (strengthMultiplier: item, angleOffset: item2);
}
public static void ClearAll()
{
_active.Clear();
}
}
internal class ModuleD_Consciousness
{
public static IEnumerator Unconscious(PuppetMaster puppet, float duration = 20f)
{
ReactionContext ctx = new ReactionContext(puppet);
if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr))
{
yield break;
}
BehaviourBaseNav behaviour = null;
AIBrain brain = null;
Animator animator = null;
AIManager manager = null;
try
{
Transform mainTransform = (((Object)(object)ctx.Puppet != (Object)null) ? ((Component)ctx.Puppet).transform : null);
if ((Object)(object)mainTransform != (Object)null)
{
brain = ((Component)mainTransform).GetComponentInParent<AIBrain>();
}
if ((Object)(object)brain != (Object)null)
{
GameObject brainGO = ((Component)brain).gameObject;
behaviour = brain.behaviour;
if ((Object)(object)behaviour == (Object)null)
{
behaviour = brainGO.GetComponentInChildren<BehaviourBaseNav>(true);
}
animator = brainGO.GetComponentInChildren<Animator>(true);
manager = brainGO.GetComponentInChildren<AIManager>(true);
}
else
{
object obj;
if (!((Object)(object)ctx.Root != (Object)null))
{
if (mainTransform == null)
{
obj = null;
}
else
{
Transform root = mainTransform.root;
obj = ((root != null) ? ((Component)root).gameObject : null);
}
}
else
{
obj = ((Component)ctx.Root).gameObject;
}
GameObject topRoot = (GameObject)obj;
if ((Object)(object)topRoot != (Object)null)
{
behaviour = topRoot.GetComponentInChildren<BehaviourBaseNav>(true);
animator = topRoot.GetComponentInChildren<Animator>(true);
manager = topRoot.GetComponentInChildren<AIManager>(true);
}
}
}
catch (Exception ex)
{
Exception ex2 = ex;
((MelonBase)ModClass.Instance).LoggerInstance.Error($"[Unconscious] Exception while fetching components: {ex2}");
}
if ((Object)(object)brain != (Object)null)
{
((Behaviour)brain).enabled = false;
}
if ((Object)(object)animator != (Object)null)
{
((Behaviour)animator).enabled = false;
}
PhysicsHelper.SaveProfile(ctx.Puppet);
if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr))
{
yield break;
}
ctx.Puppet.angularLimitsEnabled = true;
ctx.Puppet.angularLimits = true;
ctx.Puppet.animationDisabledbyStates = true;
ctx.Puppet.mappingWeight = 0f;
ctx.Puppet.ActivateRagdoll(Object.op_Implicit((Object)(object)manager));
JointDrive val;
foreach (Muscle m in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (m != null)
{
m.props.muscleWeight = 0f;
ConfigurableJoint joint = ((Component)m.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)joint != (Object)null)
{
val = default(JointDrive);
((JointDrive)(ref val)).positionSpring = 0f;
((JointDrive)(ref val)).positionDamper = 5f;
JointDrive drive = (joint.angularXDrive = (joint.slerpDrive = val));
joint.angularYZDrive = drive;
}
}
}
((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC unconcious!");
float elapsedGuard = 0f;
val = default(JointDrive);
((JointDrive)(ref val)).positionSpring = 1f;
((JointDrive)(ref val)).positionDamper = 100400f;
((JointDrive)(ref val)).maximumForce = 0f;
JointDrive zeroDrive = val;
try
{
while (elapsedGuard < duration)
{
if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr))
{
yield break;
}
if (!DeathTracker.UnconsciousNPCs.Contains(ctx.Ptr))
{
PhysicsHelper.ApplyProfile(ctx.Puppet);
yield break;
}
if ((Object)(object)behaviour != (Object)null)
{
behaviour.locoState = (LocoState)5;
}
if ((Object)(object)brain != (Object)null && (Object)(object)brain.behaviour != (Object)null)
{
brain.behaviour.mentalState = (MentalState)0;
}
foreach (Muscle m2 in (Il2CppArrayBase<Muscle>)(object)ctx.Puppet.muscles)
{
if (m2 != null)
{
ConfigurableJoint joint2 = ((Component)m2.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)joint2 != (Object)null)
{
joint2.slerpDrive = zeroDrive;
joint2.angularXDrive = zeroDrive;
joint2.angularYZDrive = zeroDrive;
}
}
}
elapsedGuard += Time.deltaTime;
yield return (object)new WaitForFixedUpdate();
}
if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr) || (int)ctx.Puppet.state == 1 || !DeathTracker.UnconsciousNPCs.Contains(ctx.Ptr))
{
yield break;
}
((MelonBase)ModClass.Instance).LoggerInstance.Msg("NPC woke up!");
if ((Object)(object)animator != (Object)null)
{
((Behaviour)animator).enabled = true;
}
if ((Object)(object)manager != (Object)null)
{
((Behaviour)manager).enabled = true;
}
if ((Object)(object)brain != (Object)null)
{
((Behaviour)brain).enabled = true;
}
if ((Object)(object)behaviour != (Object)null)
{
behaviour.locoState = (LocoState)3;
}
if ((Object)(object)brain != (Object)null && (Object)(object)brain.behaviour != (Object)null)
{
brain.behaviour.mentalState = (MentalState)2;
}
float recoverTime = 1.5f;
float elapsed = 0f;
while (elapsed < recoverTime)
{
if (!ctx.IsValid() || DeathTracker.AlreadyDead.Contains(ctx.Ptr) || !DeathTracker.UnconsciousNPCs.Contains(ctx.Ptr))
{
yield break;
}
float t = elapsed / recoverTime;
ctx.Puppet.mappingWeight = t;
PhysicsHelper.ApplyProfile(ctx.Puppet, t);
elapsed += Time.deltaTime;
yield return null;
}
if (ctx.IsValid())
{
ctx.Puppet.mappingWeight = 1f;
PhysicsHelper.ApplyProfile(ctx.Puppet);
}
}
finally
{
CleanupTracker(ctx.Ptr);
}
}
private static void CleanupTracker(IntPtr ptr)
{
DeathTracker.UnconsciousNPCs.Remove(ptr);
DeathTracker.UnconsciousStartTime.Remove(ptr);
DeathTracker.Profiles.Remove(ptr);
}
}
public static class PhysicsHelper
{
public static void EnsureBindPoseCached(PuppetMaster puppet)
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero || DeathTracker.BindPoseRotations.ContainsKey(((Il2CppObjectBase)puppet).Pointer))
{
return;
}
Dictionary<string, Quaternion> dictionary = new Dictionary<string, Quaternion>();
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
dictionary[item.name] = item.transform.localRotation;
}
}
DeathTracker.BindPoseRotations[((Il2CppObjectBase)puppet).Pointer] = dictionary;
}
public static Dictionary<string, Quaternion> SaveMuscleCurrentPose(PuppetMaster puppet, Dictionary<string, Quaternion> initialLocalRotations)
{
//IL_0066: 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)
Dictionary<string, Quaternion> dictionary = new Dictionary<string, Quaternion>();
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
if (!((Object)(object)component == (Object)null) && initialLocalRotations.TryGetValue(item.name, out var value))
{
dictionary[item.name] = JointSpaceHelper.GetCurrentRelativeRotation(component, value);
}
}
}
return dictionary;
}
public static Dictionary<string, Quaternion> SaveInitialLocalRotations(PuppetMaster puppet)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
Dictionary<string, Quaternion> dictionary = new Dictionary<string, Quaternion>();
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
dictionary[item.name] = item.transform.localRotation;
}
}
return dictionary;
}
public static void SetJointDrive(ConfigurableJoint joint, float spring, float damper, float maxForce)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: 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_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
JointDrive val = default(JointDrive);
((JointDrive)(ref val)).positionSpring = spring;
((JointDrive)(ref val)).positionDamper = damper;
((JointDrive)(ref val)).maximumForce = maxForce;
JointDrive angularYZDrive = (joint.angularXDrive = (joint.slerpDrive = val));
joint.angularYZDrive = angularYZDrive;
}
public static void ApplyToSpine(PuppetMaster puppet, float progress, float strength, Quaternion spineRot, Quaternion headRot, Quaternion chestRot, Quaternion hipRot)
{
//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_006c: 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_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item == null)
{
continue;
}
string text = item.name.ToLower();
ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)component == (Object)null)
{
continue;
}
Quaternion identity = Quaternion.identity;
if (text.Contains("spine"))
{
identity = spineRot;
}
else if (text.Contains("chest"))
{
identity = chestRot;
}
else if (text.Contains("head"))
{
identity = headRot;
}
else
{
if (!text.Contains("hip"))
{
continue;
}
identity = hipRot;
}
component.targetRotation = Quaternion.Slerp(Quaternion.identity, identity, progress);
SetJointDrive(component, 3000f * strength, 800f * strength, 3000f * strength);
item.props.muscleWeight = strength;
}
}
public static void ApplyToMuscles(PuppetMaster puppet, float progress, float strength, Quaternion elbowRot, Quaternion wristRot, Quaternion shoulderRot, Quaternion kneeRot, Quaternion ankleRot, string sideFilter = null, bool includeLegs = true, bool includeArms = true)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
ModuleC_Seizures.Tick(((Il2CppObjectBase)puppet).Pointer);
foreach (Muscle item3 in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item3 == null)
{
continue;
}
string text = item3.name.ToLower();
if (sideFilter != null && !text.Contains(sideFilter))
{
continue;
}
ConfigurableJoint component = ((Component)item3.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)component == (Object)null)
{
continue;
}
Quaternion identity = Quaternion.identity;
bool flag = text.Contains("knee") || text.Contains("ankle") || text.Contains("hip");
bool flag2 = text.Contains("wrist") || text.Contains("shoulder") || text.Contains("elbow");
if ((flag && !includeLegs) || (flag2 && !includeArms))
{
continue;
}
if (text.Contains("elbow"))
{
identity = elbowRot;
}
else if (text.Contains("wrist"))
{
identity = wristRot;
}
else if (text.Contains("shoulder"))
{
identity = shoulderRot;
}
else if (text.Contains("knee"))
{
identity = kneeRot;
}
else
{
if (!text.Contains("ankle"))
{
continue;
}
identity = ankleRot;
}
(float strengthMultiplier, float angleOffset) modifiers = ModuleC_Seizures.GetModifiers(((Il2CppObjectBase)puppet).Pointer, item3.name);
float item = modifiers.strengthMultiplier;
float item2 = modifiers.angleOffset;
Quaternion val = Quaternion.Slerp(Quaternion.identity, identity, progress);
val *= Quaternion.Euler(item2, 0f, 0f);
component.targetRotation = val;
float num = strength * item;
float num2 = (flag ? 0.35f : 1f);
SetJointDrive(component, 3000f * num, 800f * num * num2, 3000f * num * num2);
item3.props.muscleWeight = num;
}
}
public static float GetProgress(float e, float bs, float d, float rt)
{
return (e < bs) ? Mathf.Clamp01(e / bs) : 1f;
}
public static float GetStrength(float e, float bs, float d, float rt)
{
if (e < bs)
{
return Mathf.Clamp01(e / bs);
}
if (e < bs + d)
{
return 1f;
}
return 1f - Mathf.Clamp01((e - bs - d) / rt);
}
public static void RestoreAndResetJoints(PuppetMaster puppet, Dictionary<string, float> originalWeights)
{
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero)
{
return;
}
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
if (originalWeights.TryGetValue(item.name, out var value))
{
item.props.muscleWeight = value;
}
ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
if (!((Object)(object)component == (Object)null))
{
SetJointDrive(component, 0f, 0f, 0f);
component.targetRotation = Quaternion.identity;
}
}
}
}
public static Dictionary<string, float> SaveMuscleWeights(PuppetMaster puppet)
{
Dictionary<string, float> dictionary = new Dictionary<string, float>();
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
dictionary[item.name] = item.props.muscleWeight;
}
}
return dictionary;
}
public static void SaveProfile(PuppetMaster puppet)
{
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero)
{
return;
}
NPCMuscleProfile nPCMuscleProfile = new NPCMuscleProfile();
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
nPCMuscleProfile.MaxForces[item.name] = item._maxForce;
nPCMuscleProfile.MuscleWeights[item.name] = item.props.muscleWeight;
nPCMuscleProfile.MuscleDampers[item.name] = item.props.muscleDamper;
ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)component != (Object)null)
{
nPCMuscleProfile.Drives[item.name] = component.slerpDrive;
}
}
}
DeathTracker.Profiles[((Il2CppObjectBase)puppet).Pointer] = nPCMuscleProfile;
}
public static void ApplyProfile(PuppetMaster puppet, float t = 1f)
{
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero || !DeathTracker.Profiles.TryGetValue(((Il2CppObjectBase)puppet).Pointer, out var value))
{
return;
}
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item == null)
{
continue;
}
if (value.MaxForces.TryGetValue(item.name, out var value2))
{
item._maxForce = Mathf.Lerp(0f, value2, t);
}
if (value.MuscleWeights.TryGetValue(item.name, out var value3))
{
item.props.muscleWeight = Mathf.Lerp(0f, value3, t);
}
if (value.MuscleDampers.TryGetValue(item.name, out var value4))
{
item.props.muscleDamper = Mathf.Lerp(0f, value4, t);
}
if (t >= 1f)
{
ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)component != (Object)null && value.Drives.TryGetValue(item.name, out var value5))
{
component.slerpDrive = value5;
component.angularXDrive = value5;
component.angularYZDrive = value5;
}
}
}
}
public static void ResetProfile(PuppetMaster puppet)
{
if (!DeathTracker.Profiles.TryGetValue(((Il2CppObjectBase)puppet).Pointer, out var value))
{
return;
}
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
if (value.MaxForces.TryGetValue(item.name, out var value2))
{
item._maxForce = value2;
}
if (value.MuscleWeights.TryGetValue(item.name, out var value3))
{
item.props.muscleWeight = value3;
}
if (value.MuscleDampers.TryGetValue(item.name, out var value4))
{
item.props.muscleDamper = value4;
}
}
}
}
public static string ShowStats(PuppetMaster puppet)
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)puppet == (Object)null || ((Il2CppObjectBase)puppet).Pointer == IntPtr.Zero)
{
return "Puppet NULL";
}
float value = -1f;
float value2 = -1f;
float mappingWeight = puppet.mappingWeight;
float value3 = -1f;
float value4 = -1f;
float value5 = -1f;
foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles)
{
if (item != null)
{
value = item.props.muscleWeight;
value2 = item.props.muscleDamper;
value3 = item._maxForce;
ConfigurableJoint component = ((Component)item.transform).GetComponent<ConfigurableJoint>();
if ((Object)(object)component != (Object)null)
{
JointDrive slerpDrive = component.slerpDrive;
value4 = ((JointDrive)(ref slerpDrive)).positionSpring;
slerpDrive = component.slerpDrive;
value5 = ((JointDrive)(ref slerpDrive)).positionDamper;
}
break;
}
}
return $"[Diag] mWeight={value}, mDamper={value2}, maxForce={value3} | mapWeight={mappingWeight}, DriveSpring={value4}, DriveDamper={value5}";
}
}
}
namespace InjuriesMod.Core
{
public class NPCMuscleProfile
{
public Dictionary<string, float> MaxForces = new Dictionary<string, float>();
public Dictionary<string, float> MuscleWeights = new Dictionary<string, float>();
public Dictionary<string, float> MuscleDampers = new Dictionary<string, float>();
public Dictionary<string, JointDrive> Drives = new Dictionary<string, JointDrive>();
}
public static class DeathTracker
{
public static Dictionary<IntPtr, NPCMuscleProfile> Profiles = new Dictionary<IntPtr, NPCMuscleProfile>();
public static Dictionary<IntPtr, int> PointerGeneration = new Dictionary<IntPtr, int>();
public static Dictionary<IntPtr, int> LastRegisteredFrame = new Dictionary<IntPtr, int>();
public static HashSet<IntPtr> AlreadyDead = new HashSet<IntPtr>();
public static HashSet<IntPtr> UnconsciousNPCs = new HashSet<IntPtr>();
public static Dictionary<IntPtr, float> UnconsciousStartTime = new Dictionary<IntPtr, float>();
public static Dictionary<IntPtr, string> LastHitBone = new Dictionary<IntPtr, string>();
public static Dictionary<IntPtr, string> PriorityDeathCause = new Dictionary<IntPtr, string>();
public static Dictionary<IntPtr, AttackType> LastAttackType = new Dictionary<IntPtr, AttackType>();
public static Dictionary<IntPtr, float> LastAttackDamage = new Dictionary<IntPtr, float>();
public static Dictionary<IntPtr, Dictionary<string, Quaternion>> BindPoseRotations = new Dictionary<IntPtr, Dictionary<string, Quaternion>>();
public static Random Rng = new Random();
public static bool TryRegisterSpawn(IntPtr ptr, out int currentGeneration)
{
currentGeneration = -1;
if (ptr == IntPtr.Zero)
{
return false;
}
int frameCount = Time.frameCount;
if (LastRegisteredFrame.TryGetValue(ptr, out var value) && value == frameCount)
{
currentGeneration = ((!PointerGeneration.TryGetValue(ptr, out var value2)) ? 1 : value2);
return false;
}
LastRegisteredFrame[ptr] = frameCount;
if (PointerGeneration.TryGetValue(ptr, out var value3))
{
currentGeneration = value3 + 1;
}
else
{
currentGeneration = 1;
}
PointerGeneration[ptr] = currentGeneration;
return true;
}
public static void ClearNPC(IntPtr ptr)
{
if (!(ptr == IntPtr.Zero) && (AlreadyDead.Contains(ptr) || LastHitBone.ContainsKey(ptr) || UnconsciousNPCs.Contains(ptr) || LastAttackType.ContainsKey(ptr) || BindPoseRotations.ContainsKey(ptr) || Profiles.ContainsKey(ptr)))
{
((MelonBase)ModClass.Instance).LoggerInstance.Msg($"Clearing NPC data (ptr: {ptr})");
ModuleC_Seizures.Clear(ptr);
AlreadyDead.Remove(ptr);
UnconsciousNPCs.Remove(ptr);
UnconsciousStartTime.Remove(ptr);
LastHitBone.Remove(ptr);
PriorityDeathCause.Remove(ptr);
LastAttackType.Remove(ptr);
LastAttackDamage.Remove(ptr);
BindPoseRotations.Remove(ptr);
Profiles.Remove(ptr);
}
}
public static void ClearAll()
{
AlreadyDead.Clear();
UnconsciousNPCs.Clear();
UnconsciousStartTime.Clear();
LastHitBone.Clear();
PriorityDeathCause.Clear();
LastAttackType.Clear();
LastAttackDamage.Clear();
BindPoseRotations.Clear();
Profiles.Clear();
}
}
public class ModClass : MelonMod
{
public enum FrequencyScale
{
None,
Rare,
Default,
Common,
Always
}
public static ModClass Instance;
public static bool UnconsciousEnabled = true;
public static bool BrainInjuriesEnabled = true;
public static bool TorsoArmorEnabled = true;
public static bool HeadBluntResistEnabled = true;
public static bool SeizuresEnabled = true;
public static float SeizureChanceBlunt = 20f;
public static float SeizureChancePiercing = 8f;
public static Dictionary<ModuleA_Impact.ImmediateReaction, FrequencyScale> UserSettings = new Dictionary<ModuleA_Impact.ImmediateReaction, FrequencyScale>
{
{
ModuleA_Impact.ImmediateReaction.FlaccidParalysis,
FrequencyScale.Default
},
{
ModuleA_Impact.ImmediateReaction.Posturing,
FrequencyScale.Default
},
{
ModuleA_Impact.ImmediateReaction.ForwardBuckle,
FrequencyScale.Default
},
{
ModuleA_Impact.ImmediateReaction.Fencing,
FrequencyScale.Default
},
{
ModuleA_Impact.ImmediateReaction.None,
FrequencyScale.Default
}
};
public static Dictionary<ModuleA_Impact.PostureTendency, FrequencyScale> PosturingSettings = new Dictionary<ModuleA_Impact.PostureTendency, FrequencyScale>
{
{
ModuleA_Impact.PostureTendency.Flexor,
FrequencyScale.Default
},
{
ModuleA_Impact.PostureTendency.Extensor,
FrequencyScale.Default
},
{
ModuleA_Impact.PostureTendency.Mixed,
FrequencyScale.Default
},
{
ModuleA_Impact.PostureTendency.None,
FrequencyScale.Default
}
};
public override void OnInitializeMelon()
{
Harmony.CreateAndPatchAll(typeof(ModClass).Assembly, (string)null);
SetupBoneMenu();
Instance = this;
((MelonBase)this).LoggerInstance.Msg("Mod loaded!");
}
public static float GetMultiplier(FrequencyScale scale)
{
if (1 == 0)
{
}
float result = scale switch
{
FrequencyScale.None => 0f,
FrequencyScale.Rare => 0.5f,
FrequencyScale.Default => 1f,
FrequencyScale.Common => 2f,
FrequencyScale.Always => 10f,
_ => 1f,
};
if (1 == 0)
{
}
return result;
}
private static void SetupBoneMenu()
{
//IL_0037: 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_0055: 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_00b7: 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_013e: 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_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0271: Unknown result type (might be due to invalid IL or missing references)
//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
//IL_034d: Unknown result type (might be due to invalid IL or missing references)
Color val = default(Color);
((Color)(ref val))..ctor(1f, 0.988f, 0.729f);
Color val2 = default(Color);
((Color)(ref val2))..ctor(1f, 0.25f, 0.25f);
Page val3 = Page.Root.CreatePage("Brain Injuries", val2, 0, true);
Page val4 = val3.CreatePage("GENERAL SETTINGS", val, 0, true);
val4.CreateBool("Knockouts / Unconscious", Color.cyan, true, (Action<bool>)delegate(bool v)
{
UnconsciousEnabled = v;
});
val4.CreateBool("Brain Injuries", Color.yellow, true, (Action<bool>)delegate(bool v)
{
BrainInjuriesEnabled = v;
});
val4.CreateBool("Seizures", Color.yellow, true, (Action<bool>)delegate(bool v)
{
SeizuresEnabled = v;
if (!v)
{
ModuleC_Seizures.ClearAll();
}
});
Page val5 = val3.CreatePage("SEIZURE CHANCE", val, 0, true);
val5.CreateFloat("Blunt Seizure Chance %", Color.white, SeizureChanceBlunt, 1f, 0f, 100f, (Action<float>)delegate(float v)
{
SeizureChanceBlunt = v;
});
val5.CreateFloat("Piercing Seizure Chance %", Color.white, SeizureChancePiercing, 1f, 0f, 100f, (Action<float>)delegate(float v)
{
SeizureChancePiercing = v;
});
Page val6 = val3.CreatePage("DAMAGE RESISTANCE", val, 0, true);
val6.CreateBool("Reduced Torso Damage", Color.white, true, (Action<bool>)delegate(bool v)
{
TorsoArmorEnabled = v;
});
val6.CreateBool("Reduced Blunt Head Damage", Color.white, true, (Action<bool>)delegate(bool v)
{
HeadBluntResistEnabled = v;
});
Page val7 = val3.CreatePage("REACTION WEIGHTS", Color.yellow, 0, true);
Page val8 = val7.CreatePage("IMMEDIATE REACTIONS", Color.white, 0, true);
Page val9 = val7.CreatePage("POSTURING TYPES", Color.white, 0, true);
foreach (ModuleA_Impact.ImmediateReaction reaction in UserSettings.Keys.ToList())
{
val8.CreateEnum(reaction.ToString(), Color.white, (Enum)UserSettings[reaction], (Action<Enum>)delegate(Enum obj)
{
UserSettings[reaction] = (FrequencyScale)(object)obj;
});
}
foreach (ModuleA_Impact.PostureTendency reaction2 in PosturingSettings.Keys.ToList())
{
val9.CreateEnum(reaction2.ToString(), Color.white, (Enum)PosturingSettings[reaction2], (Action<Enum>)delegate(Enum obj)
{
PosturingSettings[reaction2] = (FrequencyScale)(object)obj;
});
}
val7.CreateFunction("RESTORE TO DEFAULT", Color.blue, (Action)delegate
{
foreach (ModuleA_Impact.ImmediateReaction item in UserSettings.Keys.ToList())
{
UserSettings[item] = FrequencyScale.Default;
}
foreach (ModuleA_Impact.PostureTendency item2 in PosturingSettings.Keys.ToList())
{
PosturingSettings[item2] = FrequencyScale.Default;
}
SeizureChanceBlunt = 20f;
SeizureChancePiercing = 8f;
MelonLogger.Msg("Restored settings (buttons will still show old values)");
});
}
public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
{
DeathTracker.ClearAll();
((MelonBase)this).LoggerInstance.Msg("Scene cleared.");
}
}
public class ReactionContext
{
public readonly IntPtr Ptr;
public readonly int Generation;
public readonly Transform Root;
public readonly PuppetMaster Puppet;
public ReactionContext(PuppetMaster puppet)
{
Puppet = puppet;
Ptr = (((Object)(object)puppet != (Object)null) ? ((Il2CppObjectBase)puppet).Pointer : IntPtr.Zero);
Root = (((Object)(object)puppet != (Object)null) ? ((Component)puppet).transform : null);
if (Ptr != IntPtr.Zero && DeathTracker.PointerGeneration.TryGetValue(Ptr, out var value))
{
Generation = value;
}
else
{
Generation = -1;
}
}
public bool IsValid()
{
if ((Object)(object)Root == (Object)null || Ptr == IntPtr.Zero || Generation < 0)
{
return false;
}
int value;
return DeathTracker.PointerGeneration.TryGetValue(Ptr, out value) && value == Generation;
}
}
}