using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AIGraph; using API; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BoosterImplants; using ChainedPuzzles; using Enemies; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using ReplayRecorder; using ReplayRecorder.API; using ReplayRecorder.API.Attributes; using ReplayRecorder.Core; using ReplayRecorder.SNetUtils; using SNetwork; using StateMachines; using UnityEngine; using UnityEngine.AI; using UnityEngine.Analytics; using Vanilla.BepInEx; using Vanilla.Enemy; using Vanilla.Events; using Vanilla.Map; using Vanilla.Metadata; using Vanilla.Mines; using Vanilla.Noises; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Vanilla")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a458f17da3b86c563d11a01d26049c11863af1dd")] [assembly: AssemblyProduct("Vanilla")] [assembly: AssemblyTitle("Vanilla")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace API { [HarmonyPatch(typeof(GameDataInit))] internal class GameDataInit_Patches { [HarmonyPatch("Initialize")] [HarmonyWrapSafe] [HarmonyPostfix] public static void Initialize_Postfix() { Analytics.enabled = false; } } internal static class APILogger { private static readonly ManualLogSource logger; static APILogger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown logger = new ManualLogSource("Rand-API"); Logger.Sources.Add((ILogSource)(object)logger); } private static string Format(string module, object msg) { return $"[{module}]: {msg}"; } public static void Info(string module, object data) { logger.LogMessage((object)Format(module, data)); } public static void Verbose(string module, object data) { } public static void Log(object data) { logger.LogDebug((object)Format("ReplayRecorder.Vanilla", data)); } public static void Debug(object data) { if (ConfigManager.Debug) { Log(data); } } public static void Warn(object data) { logger.LogWarning((object)Format("ReplayRecorder.Vanilla", data)); } public static void Error(object data) { logger.LogError((object)Format("ReplayRecorder.Vanilla", data)); } } } namespace Vanilla { public struct Identifier : BufferWriteable, IEquatable { private enum Type { Unknown, Gear, Alias_Gear, Item, Enemy, Vanity } private static Dictionary GearCache = new Dictionary(); private static Dictionary GearTable = new Dictionary(); private static HashSet WrittenGears = new HashSet(); public static Identifier unknown = new Identifier { type = Type.Unknown }; private static ushort _id = 0; private string stringKey; private ushort id; private Type type; [ReplayInit] private static void Init() { _id = 0; GearTable.Clear(); GearCache.Clear(); WrittenGears.Clear(); } public override string ToString() { return $"{stringKey}({id})[{type}]"; } private static ushort AssignId() { return _id++; } public static void WriteToRNetPacket(Identifier identifier, ByteBuffer buffer) { Type type = identifier.type; if (type == Type.Alias_Gear) { type = Type.Gear; } BitHelper.WriteBytes((byte)type, buffer); BitHelper.WriteBytes(identifier.id, buffer); BitHelper.WriteBytes((identifier.stringKey == null) ? string.Empty : identifier.stringKey, buffer); } public static Identifier ReadFromRNetPacket(ArraySegment bytes, ref int index) { Type type = (Type)BitHelper.ReadByte(bytes, ref index); ushort num = BitHelper.ReadUShort(bytes, ref index); string key = BitHelper.ReadString(bytes, ref index); switch (type) { case Type.Unknown: return unknown; case Type.Gear: { if (GearTable.ContainsKey(key)) { num = GearTable[key]; } else { num = AssignId(); GearTable.Add(key, num); } Identifier result = default(Identifier); result.type = Type.Alias_Gear; result.stringKey = key; result.id = num; return result; } case Type.Alias_Gear: throw new Exception("Should not receive identifier type Alias_Gear from network."); case Type.Item: case Type.Enemy: case Type.Vanity: { Identifier result = default(Identifier); result.type = type; result.id = num; return result; } default: throw new NotImplementedException(); } } public void Write(ByteBuffer buffer) { switch (type) { case Type.Gear: throw new Exception("GearKey is an internal type that gets written when a new Gear Alias is created. Should not be written directly."); case Type.Alias_Gear: if (WrittenGears.Contains(id)) { BitHelper.WriteBytes((byte)2, buffer); BitHelper.WriteBytes(id, buffer); break; } WrittenGears.Add(id); BitHelper.WriteBytes((byte)1, buffer); BitHelper.WriteBytes(stringKey, buffer); BitHelper.WriteBytes(id, buffer); break; case Type.Item: case Type.Enemy: case Type.Vanity: BitHelper.WriteBytes((byte)type, buffer); BitHelper.WriteBytes(id, buffer); break; case Type.Unknown: BitHelper.WriteBytes((byte)0, buffer); break; default: throw new NotImplementedException(); } } public static bool operator ==(Identifier lhs, Identifier rhs) { return lhs.Equals(rhs); } public static bool operator !=(Identifier lhs, Identifier rhs) { return !(lhs == rhs); } public override bool Equals(object? obj) { if (obj != null && obj is Identifier) { return Equals(obj); } return false; } public bool Equals(Identifier other) { switch (type) { case Type.Unknown: return other.type == Type.Unknown; case Type.Gear: if (other.type == Type.Gear) { return stringKey == other.stringKey; } if (stringKey != null && GearTable.ContainsKey(stringKey)) { return other.id == GearTable[stringKey]; } return false; case Type.Alias_Gear: if (other.type == Type.Alias_Gear) { return id == other.id; } if (other.stringKey != null && GearTable.ContainsKey(other.stringKey)) { return id == GearTable[other.stringKey]; } return false; case Type.Item: case Type.Enemy: case Type.Vanity: if (type == other.type) { return id == other.id; } return false; default: throw new NotImplementedException(); } } public override int GetHashCode() { if (type == Type.Unknown) { return type.GetHashCode(); } return HashCode.Combine(type, stringKey, id); } private static void From(GearIDRange gear, ref Identifier identifier) { int hashCode = ((Object)gear).GetHashCode(); if (GearCache.ContainsKey(hashCode)) { identifier.stringKey = GearCache[hashCode]; } else { identifier.stringKey = gear.ToJSON(); GearCache.Add(hashCode, identifier.stringKey); } identifier.type = Type.Alias_Gear; if (GearTable.ContainsKey(identifier.stringKey)) { identifier.id = GearTable[identifier.stringKey]; return; } identifier.id = AssignId(); GearTable.Add(identifier.stringKey, identifier.id); } public static Identifier From(ItemEquippable? item) { Identifier identifier = default(Identifier); identifier.type = Type.Unknown; if ((Object)(object)item != (Object)null) { if (item.GearIDRange != null) { From(item.GearIDRange, ref identifier); } else if (((Item)item).ItemDataBlock != null) { identifier.type = Type.Item; identifier.id = (ushort)((GameDataBlockBase)(object)((Item)item).ItemDataBlock).persistentID; } } return identifier; } public static Identifier From(BackpackItem? item) { Identifier identifier = default(Identifier); identifier.type = Type.Unknown; if (item != null && item.GearIDRange != null) { From(item.GearIDRange, ref identifier); } return identifier; } public static Identifier From(Item? item) { Identifier result = default(Identifier); result.type = Type.Unknown; if ((Object)(object)item != (Object)null && item.ItemDataBlock != null) { result.type = Type.Item; result.id = (ushort)((GameDataBlockBase)(object)item.ItemDataBlock).persistentID; } return result; } public static Identifier From(pItemData item) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Identifier result = default(Identifier); result.type = Type.Item; result.id = (ushort)item.itemID_gearCRC; return result; } public static Identifier From(EnemyAgent enemy) { Identifier result = default(Identifier); result.type = Type.Enemy; result.id = (ushort)((GameDataBlockBase)(object)enemy.EnemyData).persistentID; return result; } public static Identifier Vanity(uint id) { Identifier result = default(Identifier); result.type = Type.Vanity; result.id = (ushort)id; return result; } public static Identifier Item(uint id) { Identifier result = default(Identifier); result.type = Type.Item; result.id = (ushort)id; return result; } } } namespace Vanilla.StatTracker { [HarmonyPatch] [ReplayData("Vanilla.Player.Gunshots.Info", "0.0.1")] public class rGunshotInfo : Id { [HarmonyPatch] public static class Patches { public struct BulletInfo { public int hits; public int crits; } private static Vector3? lastHit = null; private static Identifier currentWeapon = Identifier.unknown; public static PlayerAgent? currentPlayer = null; public static BulletInfo currentBullet = new BulletInfo { hits = 0, crits = 0 }; private static void TriggerBullet() { if (!((Object)(object)currentPlayer == (Object)null)) { if (currentBullet.hits > 255 || currentBullet.crits > 255) { APILogger.Warn($"Number of enemies hit / crit for this bullet exceeded maximum value of {255}."); } Sync.Trigger(new rGunshotInfo(currentPlayer, currentWeapon, (byte)currentBullet.hits, (byte)currentBullet.crits)); lastHit = null; currentBullet.crits = 0; currentBullet.hits = 0; } } private static void PrepareWeapon(BulletWeapon weapon) { if (!((Object)(object)((Item)weapon).Owner == (Object)null) && (SNet.IsMaster || !((Item)weapon).Owner.Owner.IsBot) && (((Item)weapon).Owner.Owner.IsBot || ((Agent)((Item)weapon).Owner).IsLocallyOwned) && !rGunshot.CancelSyncedShot(weapon)) { lastHit = null; currentPlayer = ((Item)weapon).Owner; ItemEquippable wieldedItem = currentPlayer.Inventory.WieldedItem; if (wieldedItem.IsWeapon && (Object)(object)((Il2CppObjectBase)wieldedItem).TryCast() != (Object)null) { currentWeapon = Identifier.From(wieldedItem); } } } private static void ResetWeapon() { TriggerBullet(); currentPlayer = null; currentWeapon = Identifier.unknown; } [HarmonyPatch(typeof(BulletWeapon), "Fire")] [HarmonyPrefix] private static void Prefix_BulletWeaponFire(BulletWeapon __instance) { PrepareWeapon(__instance); } [HarmonyPatch(typeof(BulletWeapon), "Fire")] [HarmonyPostfix] private static void Postfix_BulletWeaponFire(BulletWeapon __instance) { ResetWeapon(); } [HarmonyPatch(typeof(Shotgun), "Fire")] [HarmonyPrefix] private static void Prefix_ShotgunFire(Shotgun __instance) { PrepareWeapon((BulletWeapon)(object)__instance); } [HarmonyPatch(typeof(Shotgun), "Fire")] [HarmonyPostfix] private static void Postfix_ShotgunFire(Shotgun __instance) { ResetWeapon(); } [HarmonyPatch(typeof(BulletWeaponSynced), "Fire")] [HarmonyPrefix] private static void Prefix_BulletWeaponSyncFire(BulletWeaponSynced __instance) { if (!((Object)(object)((Item)__instance).Owner == (Object)null) && ((Item)__instance).Owner.Owner.IsBot) { PrepareWeapon((BulletWeapon)(object)__instance); } } [HarmonyPatch(typeof(BulletWeaponSynced), "Fire")] [HarmonyPostfix] private static void Postfix_BulletWeaponSyncFire() { ResetWeapon(); } [HarmonyPatch(typeof(ShotgunSynced), "Fire")] [HarmonyPrefix] private static void Prefix_ShotgunSyncFire(ShotgunSynced __instance) { if (!((Object)(object)((Item)__instance).Owner == (Object)null) && ((Item)__instance).Owner.Owner.IsBot) { PrepareWeapon((BulletWeapon)(object)__instance); } } [HarmonyPatch(typeof(ShotgunSynced), "Fire")] [HarmonyPostfix] private static void Postfix_ShotgunSyncFire() { ResetWeapon(); } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void Postfix_CastWeaponRay(bool __result, Transform alignTransform, WeaponHitData weaponRayData, Vector3 originPos) { //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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)currentPlayer == (Object)null)) { if (lastHit.HasValue && originPos != lastHit.Value) { TriggerBullet(); } RaycastHit rayHit = Weapon.s_weaponRayData.rayHit; lastHit = ((RaycastHit)(ref rayHit)).point + Weapon.s_weaponRayData.fireDir * 0.1f; } } [HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")] [HarmonyPrefix] public static void Prefix_EnemyLimbBulletDamage(Dam_EnemyDamageLimb __instance, Agent sourceAgent) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if (!((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; if ((int)__instance.m_type == 1) { currentBullet.crits++; } } } [HarmonyPatch(typeof(Dam_PlayerDamageLimb), "BulletDamage")] [HarmonyPrefix] public static void Prefix_PlayerLimbBulletDamage(Dam_PlayerDamageLimb __instance, Agent sourceAgent) { if (!((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; } } [HarmonyPatch(typeof(GenericDamageComponent), "BulletDamage")] [HarmonyPrefix] public static void Prefix_GenericBulletDamage(GenericDamageComponent __instance, Agent sourceAgent) { if (!((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; } } [HarmonyPatch(typeof(LG_WeakLockDamage), "BulletDamage")] [HarmonyPrefix] public static void Prefix_LockBulletDamage(LG_WeakLockDamage __instance, Agent sourceAgent) { if (!(__instance.Health <= 0f) && !((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; } } } public static class Sync { private const string eventName = "Vanilla.Player.Gunshots.Info"; private static ByteBuffer packet = new ByteBuffer(); [ReplayPluginLoad] private static void Load() { RNet.Register("Vanilla.Player.Gunshots.Info", (Action>)OnReceive); } public static void Trigger(rGunshotInfo info) { Replay.Trigger((ReplayEvent)(object)info); ByteBuffer val = packet; val.Clear(); BitHelper.WriteBytes((ushort)((Id)info).id, val); Identifier.WriteToRNetPacket(info.gear, val); BitHelper.WriteBytes(info.numHits, val); BitHelper.WriteBytes(info.numCrits, val); RNet.Trigger("Vanilla.Player.Gunshots.Info", val); } private static void OnReceive(ulong sender, ArraySegment packet) { int index = 0; ushort id = BitHelper.ReadUShort(packet, ref index); Identifier gear = Identifier.ReadFromRNetPacket(packet, ref index); byte numHits = BitHelper.ReadByte(packet, ref index); byte numCrits = BitHelper.ReadByte(packet, ref index); Replay.Trigger((ReplayEvent)(object)new rGunshotInfo(id, gear, numHits, numCrits)); } } public Identifier gear; public byte numHits; public byte numCrits; public rGunshotInfo(PlayerAgent owner, Identifier gear, byte numHits, byte numCrits) : base((int)((Agent)owner).GlobalID) { this.gear = gear; this.numHits = numHits; this.numCrits = numCrits; } public rGunshotInfo(ushort id, Identifier gear, byte numHits, byte numCrits) : base((int)id) { this.gear = gear; this.numHits = numHits; this.numCrits = numCrits; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes((BufferWriteable)(object)gear, buffer); BitHelper.WriteBytes(numHits, buffer); BitHelper.WriteBytes(numCrits, buffer); } } [HarmonyPatch] [ReplayData("Vanilla.StatTracker.Damage", "0.0.1")] public class rDamage : ReplayEvent { [HarmonyPatch] private static class Patches { private static bool sentry; [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")] [HarmonyPrefix] private static void Prefix_SentryGunFire(SentryGunInstance_Firing_Bullets __instance, bool doDamage, bool targetIsTagged) { sentry = true; } [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")] [HarmonyPostfix] private static void Postfix_SentryGunFire() { sentry = false; } [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")] [HarmonyPrefix] private static void Prefix_SentryShotgunFire(SentryGunInstance_Firing_Bullets __instance, bool isMaster, bool targetIsTagged) { sentry = true; } [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")] [HarmonyPostfix] private static void Postfix_SentryShotgunFire() { sentry = false; } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveFallDamage")] [HarmonyPrefix] public static void Prefix_PlayerReceiveFallDamage(Dam_PlayerDamageBase __instance, pMiniDamageData data) { if (SNet.IsMaster) { float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, (Agent)(object)__instance.Owner, Type.Fall, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num))); } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveTentacleAttackDamage")] [HarmonyPrefix] public static void Prefix_PlayerReceiveTentacleAttackDamage(Dam_PlayerDamageBase __instance, pMediumDamageData data) { if (SNet.IsMaster && ((Agent)__instance.Owner).Alive) { float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); Agent val = default(Agent); if (((pAgent)(ref data.source)).TryGet(ref val)) { num = AgentModifierManager.ApplyModifier(val, (AgentModifier)200, num); } num = AgentModifierManager.ApplyModifier((Agent)(object)__instance.Owner, (AgentModifier)6, num); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, val, Type.Tongue, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num))); } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveShooterProjectileDamage")] [HarmonyPrefix] public static void Prefix_PlayerReceiveShooterProjectileDamage(Dam_PlayerDamageBase __instance, pMediumDamageData data) { if (SNet.IsMaster && ((Agent)__instance.Owner).Alive) { float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); Agent val = default(Agent); if (((pAgent)(ref data.source)).TryGet(ref val)) { num = AgentModifierManager.ApplyModifier(val, (AgentModifier)70, num); } num = AgentModifierManager.ApplyModifier((Agent)(object)__instance.Owner, (AgentModifier)7, num); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, (Agent)(object)__instance.Owner, Type.Projectile, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num))); } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveExplosionDamage")] [HarmonyPrefix] public static void Prefix_PlayerReceiveExplosionDamage(Dam_PlayerDamageBase __instance, pExplosionDamageData data) { if (SNet.IsMaster && ((Agent)__instance.Owner).Alive && MineManager.currentDetonateEvent != null) { float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, ((Id)MineManager.currentDetonateEvent).id, Type.Explosive, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num))); } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveMeleeDamage")] [HarmonyPrefix] public static void Prefix_PlayerReceiveMeleeDamage(Dam_PlayerDamageBase __instance, pFullDamageData data) { Agent val = default(Agent); if (SNet.IsMaster && ((Agent)__instance.Owner).Alive && ((pAgent)(ref data.source)).TryGet(ref val)) { float num = AgentModifierManager.ApplyModifier(val, (AgentModifier)200, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).DamageMax)); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, val, Type.Melee, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num))); } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveBulletDamage")] [HarmonyPrefix] public static void Prefix_PlayerReceiveBulletDamage(Dam_PlayerDamageBase __instance, pBulletDamageData data) { Agent val = default(Agent); if (!SNet.IsMaster || !((Agent)__instance.Owner).Alive || !((pAgent)(ref data.source)).TryGet(ref val)) { return; } Identifier gear = Identifier.unknown; PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val2 != (Object)null) { if (!sentry) { ItemEquippable wieldedItem = val2.Inventory.WieldedItem; if (wieldedItem.IsWeapon && (Object)(object)((Il2CppObjectBase)wieldedItem).TryCast() != (Object)null) { gear = Identifier.From(wieldedItem); } } else { gear = Identifier.From(PlayerBackpackManager.GetItem(val2.Owner, (InventorySlot)3)); } } float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); APILogger.Debug($"{__instance.Owner.Owner.NickName} was hit by {((Il2CppObjectBase)val).Cast().Owner.NickName} -> {num}"); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, val, Type.Bullet, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num), gear, sentry)); } [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveBulletDamage")] [HarmonyPrefix] public static void Prefix_PlayerLocalReceiveBulletDamage(Dam_PlayerDamageBase __instance, pBulletDamageData data) { Agent val = default(Agent); if (!SNet.IsMaster || !((Agent)__instance.Owner).Alive || !((pAgent)(ref data.source)).TryGet(ref val)) { return; } Identifier gear = Identifier.unknown; PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val2 != (Object)null) { if (!sentry) { ItemEquippable wieldedItem = val2.Inventory.WieldedItem; if ((Object)(object)wieldedItem != (Object)null && wieldedItem.IsWeapon && (Object)(object)((Il2CppObjectBase)wieldedItem).TryCast() != (Object)null) { gear = Identifier.From(wieldedItem); } } else { gear = Identifier.From(PlayerBackpackManager.GetItem(val2.Owner, (InventorySlot)3)); } } float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); APILogger.Debug($"{__instance.Owner.Owner.NickName} was hit by {((Il2CppObjectBase)val).Cast().Owner.NickName} -> {num}"); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, val, Type.Bullet, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num), gear, sentry)); } [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveExplosionDamage")] [HarmonyPrefix] public static void Prefix_PlayerLocalReceiveExplosionDamage(Dam_PlayerDamageBase __instance, pExplosionDamageData data) { if (SNet.IsMaster && ((Agent)__instance.Owner).Alive) { APILogger.Debug("local explosive"); if (MineManager.currentDetonateEvent != null) { float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, ((Id)MineManager.currentDetonateEvent).id, Type.Explosive, Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num))); } } } [HarmonyPatch(typeof(Dam_EnemyDamageBase), "ReceiveExplosionDamage")] [HarmonyPrefix] public static void Prefix_EnemyReceiveExplosionDamage(Dam_EnemyDamageBase __instance, pExplosionDamageData data) { if (!SNet.IsMaster || !((Agent)__instance.Owner).Alive) { return; } if (MineManager.currentDetonateEvent != null) { float num = ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); float num2 = num; float num3 = __instance.Owner.EnemyBalancingData.Health.DamageUntilHitreact - __instance.m_damBuildToHitreact; if (num3 < 0f) { num3 = 0f; } num = Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num); num2 = HandlePouncerStagger(__instance, num, Mathf.Min(num3, num2)); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, ((Id)MineManager.currentDetonateEvent).id, Type.Explosive, num, sentry: false, num2)); } else { APILogger.Error("Unable to find detonation event. This should not happen."); } } [HarmonyPatch(typeof(Dam_EnemyDamageBase), "ReceiveMeleeDamage")] [HarmonyPrefix] public static void Prefix_EnemyReceiveMeleeDamage(Dam_EnemyDamageBase __instance, pFullDamageData data) { Agent val = default(Agent); if (!SNet.IsMaster || !((Agent)__instance.Owner).Alive || !((pAgent)(ref data.source)).TryGet(ref val)) { return; } Identifier gear = Identifier.unknown; PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val2 != (Object)null) { ItemEquippable wieldedItem = val2.Inventory.WieldedItem; if ((Object)(object)wieldedItem != (Object)null && wieldedItem.IsWeapon && (Object)(object)((Il2CppObjectBase)wieldedItem).TryCast() != (Object)null) { gear = Identifier.From(wieldedItem); } } float num = AgentModifierManager.ApplyModifier(val, (AgentModifier)200, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).DamageMax)); float num2 = num * ((UFloat16)(ref data.staggerMulti)).Get(10f); float num3 = __instance.Owner.EnemyBalancingData.Health.DamageUntilHitreact - __instance.m_damBuildToHitreact; if (num3 < 0f) { num3 = 0f; } num = Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num); num2 = HandlePouncerStagger(__instance, num, Mathf.Min(num3, num2)); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, val, Type.Melee, num, gear, sentry: false, num2)); } [HarmonyPatch(typeof(Dam_EnemyDamageBase), "ReceiveBulletDamage")] [HarmonyPrefix] public static void Prefix_EnemyReceiveBulletDamage(Dam_EnemyDamageBase __instance, pBulletDamageData data) { Agent val = default(Agent); if (!SNet.IsMaster || !((Agent)__instance.Owner).Alive || !((pAgent)(ref data.source)).TryGet(ref val)) { return; } Identifier gear = Identifier.unknown; PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val2 != (Object)null) { if (!sentry) { ItemEquippable wieldedItem = val2.Inventory.WieldedItem; if (wieldedItem.IsWeapon && (Object)(object)((Il2CppObjectBase)wieldedItem).TryCast() != (Object)null) { gear = Identifier.From(wieldedItem); } } else { gear = Identifier.From(PlayerBackpackManager.GetItem(val2.Owner, (InventorySlot)3)); } } float num = AgentModifierManager.ApplyModifier((Agent)(object)__instance.Owner, (AgentModifier)7, ((UFloat16)(ref data.damage)).Get(((Dam_SyncedDamageBase)__instance).HealthMax)); float num2 = num * ((UFloat16)(ref data.staggerMulti)).Get(10f); float num3 = __instance.Owner.EnemyBalancingData.Health.DamageUntilHitreact - __instance.m_damBuildToHitreact; if (num3 < 0f) { num3 = 0f; } num = Mathf.Min(((Dam_SyncedDamageBase)__instance).Health, num); num2 = HandlePouncerStagger(__instance, num, Mathf.Min(num3, num2)); Sync.Trigger(new rDamage((Agent)(object)__instance.Owner, val, Type.Bullet, num, gear, sentry, num2)); } private static float HandlePouncerStagger(Dam_EnemyDamageBase __instance, float damage, float stagger) { PouncerBehaviour component = ((Component)__instance.Owner).GetComponent(); if ((Object)(object)component == (Object)null) { return stagger; } if (((MachineState)(object)((StateMachine)(object)component).CurrentState).ENUM_ID == ((MachineState)(object)component.Dash).ENUM_ID) { return Mathf.Min(damage + component.Dash.m_damageReceivedDuringState, component.m_data.DashStaggerDamageThreshold) - component.Dash.m_damageReceivedDuringState; } if (((MachineState)(object)((StateMachine)(object)component).CurrentState).ENUM_ID == ((MachineState)(object)component.Charge).ENUM_ID) { return Mathf.Min(damage + component.Charge.m_damageReceivedDuringState, component.m_data.ChargeStaggerDamageThreshold) - component.Charge.m_damageReceivedDuringState; } return 0f; } } public enum Type { Bullet, Explosive, Melee, Projectile, Tongue, Fall } private static class Sync { private const string eventName = "Vanilla.StatTracker.Damage"; private static ByteBuffer packet = new ByteBuffer(); [ReplayPluginLoad] private static void Load() { RNet.Register("Vanilla.StatTracker.Damage", (Action>)OnReceive); } public static void Trigger(rDamage damage) { Replay.Trigger((ReplayEvent)(object)damage); ByteBuffer val = packet; val.Clear(); BitHelper.WriteBytes((byte)damage.type, val); BitHelper.WriteBytes(damage.source, val); BitHelper.WriteBytes(damage.target, val); BitHelper.WriteHalf(damage.damage, val); Identifier.WriteToRNetPacket(damage.gear, val); BitHelper.WriteBytes(damage.sentry, val); BitHelper.WriteHalf(damage.staggerDamage, val); RNet.Trigger("Vanilla.StatTracker.Damage", val); } private static void OnReceive(ulong sender, ArraySegment packet) { int index = 0; Type type = (Type)BitHelper.ReadByte(packet, ref index); int source = BitHelper.ReadInt(packet, ref index); ushort target = BitHelper.ReadUShort(packet, ref index); float damage = BitHelper.ReadHalf(packet, ref index); Identifier gear = Identifier.ReadFromRNetPacket(packet, ref index); bool sentry = BitHelper.ReadBool(packet, ref index); float staggerMulti = BitHelper.ReadHalf(packet, ref index); Replay.Trigger((ReplayEvent)(object)new rDamage(target, source, type, damage, gear, sentry, staggerMulti)); } } public Type type; public int source; public ushort target; public Identifier gear; public bool sentry; public float damage; public float staggerDamage; public rDamage(Agent target, Agent source, Type type, float damage, Identifier gear, bool sentry = false, float staggerMulti = 0f) { this.type = type; this.source = source.GlobalID; this.target = target.GlobalID; this.gear = gear; this.damage = damage; staggerDamage = staggerMulti; this.sentry = sentry; } public rDamage(Agent target, int source, Type type, float damage, Identifier gear, bool sentry = false, float staggerMulti = 0f) { this.type = type; this.source = source; this.target = target.GlobalID; this.gear = gear; this.damage = damage; staggerDamage = staggerMulti; this.sentry = sentry; } public rDamage(ushort target, int source, Type type, float damage, Identifier gear, bool sentry = false, float staggerMulti = 0f) { this.type = type; this.source = source; this.target = target; this.gear = gear; this.damage = damage; staggerDamage = staggerMulti; this.sentry = sentry; } public rDamage(Agent target, Agent source, Type type, float damage, bool sentry = false, float staggerMulti = 0f) { this.type = type; this.source = source.GlobalID; this.target = target.GlobalID; gear = Identifier.unknown; this.damage = damage; staggerDamage = staggerMulti; this.sentry = sentry; } public rDamage(Agent target, int source, Type type, float damage, bool sentry = false, float staggerMulti = 0f) { this.type = type; this.source = source; this.target = target.GlobalID; gear = Identifier.unknown; this.damage = damage; staggerDamage = staggerMulti; this.sentry = sentry; } public rDamage(ushort target, int source, Type type, float damage, bool sentry = false, float staggerMulti = 0f) { this.type = type; this.source = source; this.target = target; gear = Identifier.unknown; this.damage = damage; staggerDamage = staggerMulti; this.sentry = sentry; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes((byte)type, buffer); BitHelper.WriteBytes(source, buffer); BitHelper.WriteBytes(target, buffer); BitHelper.WriteHalf(damage, buffer); BitHelper.WriteBytes((BufferWriteable)(object)gear, buffer); BitHelper.WriteBytes(sentry, buffer); BitHelper.WriteHalf(staggerDamage, buffer); } } [HarmonyPatch] [ReplayData("Vanilla.StatTracker.Revive", "0.0.1")] public class rRevive : ReplayEvent { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(AgentReplicatedActions), "DoPlayerRevive")] [HarmonyPostfix] public static void DoPlayerRevive(pPlayerReviveAction data) { PlayerAgent val = default(PlayerAgent); PlayerAgent val2 = default(PlayerAgent); if (((pPlayerAgent)(ref data.TargetPlayer)).TryGet(ref val) && !((Agent)val).Alive && ((pPlayerAgent)(ref data.SourcePlayer)).TryGet(ref val2)) { APILogger.Debug($"Player {val.Owner.NickName} was revived by {val2.Owner.NickName}."); Replay.Trigger((ReplayEvent)(object)new rRevive(val, val2)); } } } private ushort source; private ushort target; public rRevive(PlayerAgent target, PlayerAgent source) { this.source = ((Agent)source).GlobalID; this.target = ((Agent)target).GlobalID; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes(source, buffer); BitHelper.WriteBytes(target, buffer); } } } namespace Vanilla.StatTracker.Dodges { [HarmonyPatch] [ReplayData("Vanilla.StatTracker.TongueDodge", "0.0.1")] public class rTongueDodge : ReplayEvent { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(MovingEnemyTentacleBase), "AttackIn")] [HarmonyPrefix] private static void AttackIn(MovingEnemyTentacleBase __instance) { int instanceID = ((Object)__instance).GetInstanceID(); if (Replay.Has(instanceID)) { rEnemyTongue rEnemyTongue = Replay.Get(instanceID); if (!rEnemyTongue.attackOut && (Object)(object)rEnemyTongue.target != (Object)null) { Replay.Trigger((ReplayEvent)(object)new rTongueDodge(__instance.m_owner, rEnemyTongue.target)); } rEnemyTongue.attackOut = false; } } [HarmonyPatch(typeof(MovingEnemyTentacleBase), "OnAttackIsOut")] [HarmonyPrefix] private static void OnAttackIsOut(MovingEnemyTentacleBase __instance) { //IL_005f: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } int instanceID = ((Object)__instance).GetInstanceID(); if (!Replay.Has(instanceID)) { return; } rEnemyTongue rEnemyTongue = Replay.Get(instanceID); rEnemyTongue.attackOut = true; PlayerAgent val = __instance.PlayerTarget; if ((Object)(object)val == (Object)null) { val = rEnemyTongue.target; } if ((Object)(object)val == (Object)null) { return; } bool flag = __instance.CheckTargetInAttackTunnel(); bool flag2 = false; if (__instance.m_hasStaticTargetPos) { RaycastHit val2 = default(RaycastHit); if (Physics.Linecast(((Agent)__instance.m_owner).EyePosition, __instance.m_staticTargetPos, ref val2, LayerManager.MASK_DEFAULT) && ((Component)((RaycastHit)(ref val2)).collider).GetComponent() != null) { flag2 = true; } } else if ((Object)(object)__instance.PlayerTarget != (Object)null && ((Dam_SyncedDamageBase)__instance.PlayerTarget.Damage).IsSetup) { bool flag3; if (__instance.m_owner.EnemyBalancingData.UseTentacleTunnelCheck) { flag3 = flag; } else { Vector3 tipPos = __instance.GetTipPos(); Vector3 val3 = ((Agent)__instance.PlayerTarget).TentacleTarget.position - tipPos; flag3 = ((Vector3)(ref val3)).magnitude < __instance.m_owner.EnemyBalancingData.TentacleAttackDamageRadiusIfNoTunnelCheck; } if (flag3) { flag2 = true; } } if (!flag2) { Replay.Trigger((ReplayEvent)(object)new rTongueDodge(__instance.m_owner, val)); } } } public ushort source; public ushort target; public rTongueDodge(EnemyAgent source, PlayerAgent target) { this.source = ((Agent)source).GlobalID; this.target = ((Agent)target).GlobalID; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes(source, buffer); BitHelper.WriteBytes(target, buffer); } } } namespace Vanilla.StatTracker.Consumable { [HarmonyPatch] [ReplayData("Vanilla.StatTracker.Pack", "0.0.1")] public class rPack : ReplayEvent { [HarmonyPatch] private class Patches { private static PlayerAgent? sourcePackUser; [HarmonyPatch(typeof(ResourcePackFirstPerson), "ApplyPackBot")] [HarmonyPrefix] public static void ApplyPackBot(PlayerAgent ownerAgent, PlayerAgent receiverAgent, ItemEquippable resourceItem) { if (SNet.IsMaster) { uint persistentID = ((GameDataBlockBase)(object)((Item)resourceItem).ItemDataBlock).persistentID; if (persistentID - 101 <= 1 || persistentID == 127 || persistentID == 132) { sourcePackUser = ownerAgent; } } } [HarmonyPatch(typeof(ResourcePackFirstPerson), "ApplyPack")] [HarmonyPrefix] public static void ApplyPackFirstPerson(ResourcePackFirstPerson __instance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 if (SNet.IsMaster) { eResourceContainerSpawnType packType = __instance.m_packType; if ((int)packType <= 2 || (int)packType == 9) { sourcePackUser = ((Item)__instance).Owner; } } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveAddHealth")] [HarmonyPrefix] public static void Postfix_ReceiveAddHealth(Dam_PlayerDamageBase __instance, pAddHealthData data) { if (!SNet.IsMaster) { return; } float num = ((SFloat16)(ref data.health)).Get(((Dam_SyncedDamageBase)__instance).HealthMax); if (Mathf.Min(((Dam_SyncedDamageBase)__instance).Health + num, ((Dam_SyncedDamageBase)__instance).HealthMax) - ((Dam_SyncedDamageBase)__instance).Health > 0f) { Agent val = default(Agent); if ((Object)(object)sourcePackUser == (Object)null) { ((pAgent)(ref data.source)).TryGet(ref val); } else { val = (Agent)(object)sourcePackUser; } if ((Object)(object)val != (Object)null) { PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val2 != (Object)null) { APILogger.Debug($"Player {val2.Owner.NickName} used healing item on {__instance.Owner.Owner.NickName}."); Sync.Trigger(new rPack(Type.HealingItem, val, (Agent)(object)__instance.Owner)); } } } sourcePackUser = null; } [HarmonyPatch(typeof(PlayerBackpackManager), "ReceiveAmmoGive")] [HarmonyPostfix] public static void ReceiveAmmoGive(PlayerBackpackManager __instance, pAmmoGive data) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } SNet_Player val = default(SNet_Player); if (((pPlayer)(ref data.targetPlayer)).TryGetPlayer(ref val)) { PlayerDataBlock block = GameDataBlockBase.GetBlock(1u); float num = data.ammoStandardRel * (float)block.AmmoStandardResourcePackMaxCap; float num2 = data.ammoSpecialRel * (float)block.AmmoSpecialResourcePackMaxCap; Type type = ((!(num > 0f) || !(num2 > 0f)) ? Type.Tool : Type.Ammo); PlayerAgent val2 = ((Il2CppObjectBase)val.PlayerAgent).Cast(); SNet_Player val3 = default(SNet_Player); if ((Object)(object)sourcePackUser != (Object)null) { APILogger.Debug($"Player {sourcePackUser.Owner.NickName} used {type} on {val2.Owner.NickName}."); Sync.Trigger(new rPack(type, (Agent)(object)sourcePackUser, (Agent)(object)val2)); } else if (SNetUtils.TryGetSender((SNet_Packet)(object)((SNet_SyncedAction)(object)__instance.m_giveAmmoPacket).m_packet, ref val3)) { APILogger.Debug($"Player {val3.NickName} used {type} on {val2.Owner.NickName}."); Sync.Trigger(new rPack(type, (Agent)(object)((Il2CppObjectBase)val3.PlayerAgent).Cast(), (Agent)(object)val2)); } else { APILogger.Debug($"Player {val2.Owner.NickName} used {type}."); Sync.Trigger(new rPack(type, (Agent)(object)val2, (Agent)(object)val2)); } } sourcePackUser = null; } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ModifyInfection")] [HarmonyPostfix] public static void ModifyInfection(Dam_PlayerDamageBase __instance, pInfection data, bool sync, bool updatePageMap) { //IL_0008: 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: Invalid comparison between Unknown and I4 if (!SNet.IsMaster) { return; } if ((int)data.effect == 1) { PlayerAgent owner = __instance.Owner; SNet_Player val = default(SNet_Player); if ((Object)(object)sourcePackUser != (Object)null) { APILogger.Debug($"Player {sourcePackUser.Owner.NickName} used disinfect pack on {owner.Owner.NickName}."); Sync.Trigger(new rPack(Type.Disinfect, (Agent)(object)sourcePackUser, (Agent)(object)owner)); } else if (SNetUtils.TryGetSender((SNet_Packet)(object)__instance.m_receiveModifyInfectionPacket, ref val)) { APILogger.Debug($"Player {val.NickName} used disinfect pack on {owner.Owner.NickName}."); Sync.Trigger(new rPack(Type.Disinfect, (Agent)(object)((Il2CppObjectBase)val.PlayerAgent).Cast(), (Agent)(object)owner)); } else { APILogger.Debug("Player " + owner.Owner.NickName + " used disinfect pack."); Sync.Trigger(new rPack(Type.Disinfect, (Agent)(object)owner, (Agent)(object)owner)); } } sourcePackUser = null; } } public enum Type { Ammo, Tool, HealingItem, Disinfect } private static class Sync { private const string eventName = "Vanilla.StatTracker.Pack"; private static ByteBuffer packet = new ByteBuffer(); [ReplayPluginLoad] private static void Load() { RNet.Register("Vanilla.StatTracker.Pack", (Action>)OnReceive); } public static void Trigger(rPack pack) { Replay.Trigger((ReplayEvent)(object)pack); ByteBuffer val = packet; val.Clear(); BitHelper.WriteBytes((byte)pack.type, val); BitHelper.WriteBytes(pack.source, val); BitHelper.WriteBytes(pack.target, val); RNet.Trigger("Vanilla.StatTracker.Pack", val); } private static void OnReceive(ulong sender, ArraySegment packet) { int num = 0; byte type = BitHelper.ReadByte(packet, ref num); ushort source = BitHelper.ReadUShort(packet, ref num); ushort target = BitHelper.ReadUShort(packet, ref num); Replay.Trigger((ReplayEvent)(object)new rPack((Type)type, source, target)); } } public Type type; public ushort source; public ushort target; public rPack(Type type, Agent source, Agent target) { this.type = type; this.source = source.GlobalID; this.target = target.GlobalID; } public rPack(Type type, ushort source, ushort target) { this.type = type; this.source = source; this.target = target; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes((byte)type, buffer); BitHelper.WriteBytes(source, buffer); BitHelper.WriteBytes(target, buffer); } } } namespace Vanilla.StaticItems { internal class rBulkheadController { public LG_BulkheadDoorController_Core core; public int id; public Vector3 position => ((Component)core).transform.position; public Quaternion rotation => ((Component)core).transform.rotation; public byte dimensionIndex => (byte)core.SpawnNode.m_dimension.DimensionIndex; public ushort serialNumber => (ushort)core.m_serialNumber; public rBulkheadController(LG_BulkheadDoorController_Core controller) { id = ((Object)controller).GetInstanceID(); core = controller; } } [HarmonyPatch] [ReplayData("Vanilla.Map.BulkheadControllers", "0.0.1")] internal class rBulkheadControllers : ReplayHeader { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_BulkheadDoorController_Core), "Setup")] [HarmonyPostfix] private static void Setup(LG_BulkheadDoorController_Core __instance) { rBulkheadController rBulkheadController2 = new rBulkheadController(__instance); bulkheadControllers.Add(rBulkheadController2.id, rBulkheadController2); } } internal static Dictionary bulkheadControllers = new Dictionary(); private static LG_LayerType[] layers = (LG_LayerType[])(object)new LG_LayerType[3] { default(LG_LayerType), (LG_LayerType)1, (LG_LayerType)2 }; [ReplayOnElevatorStop] private static void Trigger() { int[] array = bulkheadControllers.Keys.ToArray(); foreach (int key in array) { if (bulkheadControllers.ContainsKey(key) && (Object)(object)bulkheadControllers[key].core == (Object)null) { bulkheadControllers.Remove(key); } } Replay.Trigger((ReplayHeader)(object)new rBulkheadControllers()); bulkheadControllers.Clear(); } [ReplayInit] private static void Init() { bulkheadControllers.Clear(); } public override void Write(ByteBuffer buffer) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0095: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes((ushort)bulkheadControllers.Count, buffer); foreach (rBulkheadController value in bulkheadControllers.Values) { BitHelper.WriteBytes(value.id, buffer); BitHelper.WriteBytes(value.dimensionIndex, buffer); BitHelper.WriteBytes(value.position, buffer); BitHelper.WriteHalf(value.rotation, buffer); BitHelper.WriteBytes(value.serialNumber, buffer); Dictionary connectedBulkheadDoors = value.core.m_connectedBulkheadDoors; LG_LayerType[] array = layers; foreach (LG_LayerType val in array) { if (connectedBulkheadDoors.ContainsKey(val)) { BitHelper.WriteBytes(true, buffer); BitHelper.WriteBytes(((Object)connectedBulkheadDoors[val].Gate).GetInstanceID(), buffer); } else { BitHelper.WriteBytes(false, buffer); } } } } } internal class rDisinfectStation { public LG_DisinfectionStation core; public int id; public Vector3 position => ((Component)core).transform.position; public Quaternion rotation => ((Component)core).transform.rotation; public byte dimensionIndex => (byte)core.SpawnNode.m_dimension.DimensionIndex; public ushort serialNumber => (ushort)core.m_serialNumber; public rDisinfectStation(LG_DisinfectionStation disinfectStation) { id = ((Object)disinfectStation).GetInstanceID(); core = disinfectStation; } } [HarmonyPatch] [ReplayData("Vanilla.Map.DisinfectStations", "0.0.1")] internal class rDisinfectStations : ReplayHeader { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_DisinfectionStation), "Setup")] [HarmonyPostfix] private static void Setup(LG_DisinfectionStation __instance) { rDisinfectStation rDisinfectStation2 = new rDisinfectStation(__instance); disinfectStations.Add(rDisinfectStation2.id, rDisinfectStation2); } } internal static Dictionary disinfectStations = new Dictionary(); [ReplayOnElevatorStop] private static void Trigger() { int[] array = disinfectStations.Keys.ToArray(); foreach (int key in array) { if (disinfectStations.ContainsKey(key) && (Object)(object)disinfectStations[key].core == (Object)null) { disinfectStations.Remove(key); } } Replay.Trigger((ReplayHeader)(object)new rDisinfectStations()); disinfectStations.Clear(); } [ReplayInit] private static void Init() { disinfectStations.Clear(); } public override void Write(ByteBuffer buffer) { //IL_0043: 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) BitHelper.WriteBytes((ushort)disinfectStations.Count, buffer); foreach (rDisinfectStation value in disinfectStations.Values) { BitHelper.WriteBytes(value.id, buffer); BitHelper.WriteBytes(value.dimensionIndex, buffer); BitHelper.WriteBytes(value.position, buffer); BitHelper.WriteHalf(value.rotation, buffer); BitHelper.WriteBytes(value.serialNumber, buffer); } } } internal class rDoor { public enum Type { WeakDoor, SecurityDoor, BulkheadDoor, BulkheadDoorMain, ApexDoor } private int id; public LG_Gate gate; private MonoBehaviourExtended mono; private ushort serialNumber; private bool isCheckpoint; private Type type; private byte size; public rDoor(Type type, LG_Door_Sync sync, LG_Gate gate, MonoBehaviourExtended mono, int serialNumber, bool isCheckpoint = false) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Invalid comparison between Unknown and I4 id = sync.m_stateReplicator.Replicator.Key; this.gate = gate; this.mono = mono; this.serialNumber = (ushort)serialNumber; this.type = type; this.isCheckpoint = isCheckpoint; if (this.type == Type.SecurityDoor) { if (gate.ForceApexGate) { this.type = Type.ApexDoor; } else if (gate.ForceBulkheadGate) { this.type = Type.BulkheadDoor; } else if (gate.ForceBulkheadGateMainPath) { this.type = Type.BulkheadDoorMain; } } LG_GateType val = gate.Type; if ((int)val != 1) { if ((int)val == 2) { size = 2; } else { size = 0; } } else { size = 1; } } public void Write(ByteBuffer buffer) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes(id, buffer); BitHelper.WriteBytes((byte)Dimension.GetDimensionFromPos(((Component)mono).transform.position).DimensionIndex, buffer); BitHelper.WriteBytes(((Component)mono).transform.position, buffer); BitHelper.WriteHalf(((Component)mono).transform.rotation, buffer); BitHelper.WriteBytes(serialNumber, buffer); BitHelper.WriteBytes(isCheckpoint, buffer); BitHelper.WriteBytes((byte)type, buffer); BitHelper.WriteBytes(size, buffer); } } [ReplayData("Vanilla.Map.Doors", "0.0.1")] internal class rDoors : ReplayHeader { private List doors; public rDoors(List doors) { this.doors = doors; } public override void Write(ByteBuffer buffer) { if (doors.Count > 65535) { throw new TooManyDoors($"There were too many doors! {doors.Count} doors were found."); } BitHelper.WriteBytes((ushort)doors.Count, buffer); foreach (rDoor door in doors) { door.Write(buffer); } } } public class NoDoorDestructionComp : Exception { public NoDoorDestructionComp(string message) : base(message) { } } public class TooManyDoors : Exception { public TooManyDoors(string message) : base(message) { } } internal static class DoorReplayManager { internal static List doors = new List(); internal static List weakDoors = new List(); [ReplayInit] private static void Init() { doors.Clear(); weakDoors.Clear(); } [ReplayOnHeaderCompletion] private static void WriteWeakDoors() { rWeakDoor[] array = weakDoors.ToArray(); weakDoors.Clear(); rWeakDoor[] array2 = array; foreach (rWeakDoor rWeakDoor2 in array2) { if ((Object)(object)rWeakDoor2.door != (Object)null) { weakDoors.Add(rWeakDoor2); } } foreach (rWeakDoor weakDoor in weakDoors) { Replay.Spawn((ReplayDynamic)(object)weakDoor, true); } } public static byte doorStatus(eDoorStatus status) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected I4, but got Unknown return (status - 10) switch { 0 => 1, 2 => 2, 1 => 3, _ => 0, }; } } [HarmonyPatch] [ReplayData("Vanilla.Map.DoorStatusChange", "0.0.1")] internal class rDoorStatusChange : Id { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_WeakDoor), "OnSyncDoorStateChange")] [HarmonyPrefix] private static void Weak_DoorStateChange(LG_WeakDoor __instance, pDoorState state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) if (DoorReplayManager.doorStatus(__instance.LastStatus) != DoorReplayManager.doorStatus(state.status)) { Replay.Trigger((ReplayEvent)(object)new rDoorStatusChange(((Il2CppObjectBase)__instance.m_sync).Cast().m_stateReplicator.Replicator.Key, state.status)); } } [HarmonyPatch(typeof(LG_SecurityDoor), "OnSyncDoorStatusChange")] [HarmonyPrefix] private static void Security_DoorStateChange(LG_SecurityDoor __instance, pDoorState state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) if (DoorReplayManager.doorStatus(__instance.LastStatus) != DoorReplayManager.doorStatus(state.status)) { Replay.Trigger((ReplayEvent)(object)new rDoorStatusChange(((Il2CppObjectBase)__instance.m_sync).Cast().m_stateReplicator.Replicator.Key, state.status)); } } } private byte status; public rDoorStatusChange(int id, eDoorStatus status) : base(id) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) this.status = DoorReplayManager.doorStatus(status); } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(status, buffer); } } [HarmonyPatch] [ReplayData("Vanilla.Map.WeakDoor.Punch", "0.0.1")] internal class rDoorPunch : Id { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_WeakDoor_Destruction), "TriggerPunchEffect")] [HarmonyPostfix] private static void WeakDoor_Punch(LG_WeakDoor_Destruction __instance) { LG_WeakDoor val = ((Il2CppObjectBase)__instance.m_core).TryCast(); if (!((Object)(object)val == (Object)null)) { Replay.Trigger((ReplayEvent)(object)new rDoorPunch(((Il2CppObjectBase)val.m_sync).Cast().m_stateReplicator.Replicator.Key)); } } } public rDoorPunch(int id) : base(id) { } } [HarmonyPatch] [ReplayData("Vanilla.Map.WeakDoor", "0.0.1")] internal class rWeakDoor : ReplayDynamic { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_WeakDoor), "Setup")] [HarmonyPostfix] private static void WeakDoor_Setup(LG_WeakDoor __instance, LG_Gate gate) { DoorReplayManager.doors.Add(new rDoor(rDoor.Type.WeakDoor, ((Il2CppObjectBase)__instance.m_sync).Cast(), gate, (MonoBehaviourExtended)(object)__instance, __instance.m_serialNumber, __instance.IsCheckpointDoor)); DoorReplayManager.weakDoors.Add(new rWeakDoor(__instance)); } [HarmonyPatch(typeof(LG_SecurityDoor), "Setup")] [HarmonyPostfix] private static void SecurityDoor_Setup(LG_SecurityDoor __instance, LG_Gate gate) { DoorReplayManager.doors.Add(new rDoor(rDoor.Type.SecurityDoor, ((Il2CppObjectBase)__instance.m_sync).Cast(), gate, (MonoBehaviourExtended)(object)__instance, __instance.m_serialNumber, __instance.IsCheckpointDoor)); } [HarmonyPatch(typeof(GS_ReadyToStopElevatorRide), "Enter")] [HarmonyPostfix] private static void StopElevatorRide() { rDoor[] array = DoorReplayManager.doors.ToArray(); DoorReplayManager.doors.Clear(); rDoor[] array2 = array; foreach (rDoor rDoor2 in array2) { if ((Object)(object)rDoor2.gate != (Object)null) { DoorReplayManager.doors.Add(rDoor2); } } Replay.Trigger((ReplayHeader)(object)new rDoors(DoorReplayManager.doors)); } } private enum LockType { None, Melee, Hackable } private static class Sync { private const string eventName = "Vanilla.Map.WeakDoor"; private static ByteBuffer packet = new ByteBuffer(); [ReplayPluginLoad] private static void Load() { RNet.Register("Vanilla.Map.WeakDoor", (Action>)OnReceive); } public static void Trigger(int id, byte health) { ByteBuffer val = packet; val.Clear(); BitHelper.WriteBytes(id, val); BitHelper.WriteBytes(health, val); RNet.Trigger("Vanilla.Map.WeakDoor", val); } private static void OnReceive(ulong sender, ArraySegment packet) { int num = 0; int num2 = BitHelper.ReadInt(packet, ref num); byte health = BitHelper.ReadByte(packet, ref num); rWeakDoor rWeakDoor2 = default(rWeakDoor); if (Replay.TryGet(num2, ref rWeakDoor2)) { rWeakDoor2._health = health; } } } public LG_WeakDoor door; private LG_WeakDoor_Destruction destruction; private float damageTaken; private byte _health = byte.MaxValue; private byte prevHealth = byte.MaxValue; private byte _lock0; private byte _lock1; public override string? Debug => $"{base.id} - {destruction.m_health}/{door.m_healthMax}"; public override bool Active => (Object)(object)door != (Object)null; public override bool IsDirty { get { if (health == prevHealth && _lock0 == lock0) { return _lock1 != lock1; } return true; } } private byte health { get { if (SNet.IsMaster) { return (byte)(255f * destruction.m_health / door.m_healthMax); } return _health; } } private byte lock0 => (byte)GetLockType(0); private byte lock1 => (byte)GetLockType(1); private LockType GetLockType(int slot) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Invalid comparison between Unknown and I4 //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (door.m_weakLocks == null || slot < 0 || slot >= ((Il2CppArrayBase)(object)door.m_weakLocks).Length) { return LockType.None; } LG_WeakLock val = ((Il2CppArrayBase)(object)door.m_weakLocks)[slot]; LockType result = LockType.None; if ((Object)(object)val != (Object)null && (int)val.m_stateReplicator.State.status != 3 && (int)val.m_stateReplicator.State.status != 2) { eWeakLockType lockType = val.m_lockType; if ((int)lockType != 1) { if ((int)lockType == 2) { result = LockType.Hackable; } } else { result = LockType.Melee; } } return result; } public rWeakDoor(LG_WeakDoor door) : base((int)((Il2CppObjectBase)door.m_sync).Cast().m_stateReplicator.Replicator.Key) { this.door = door; damageTaken = door.m_healthMax; LG_WeakDoor_Destruction val = ((Il2CppObjectBase)door.m_destruction).TryCast(); if ((Object)(object)val == (Object)null) { throw new NoDoorDestructionComp("Failed to get 'LG_WeakDoor_Destruction'."); } destruction = val; } public override void Write(ByteBuffer buffer) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) prevHealth = health; _lock0 = lock0; _lock1 = lock1; BitHelper.WriteBytes(prevHealth, buffer); if (((Component)((Il2CppArrayBase)(object)door.m_buttonAligns)[0]).transform.localPosition.z < 0f) { BitHelper.WriteBytes(_lock0, buffer); BitHelper.WriteBytes(_lock1, buffer); } else { BitHelper.WriteBytes(_lock1, buffer); BitHelper.WriteBytes(_lock0, buffer); } if (SNet.IsMaster) { Sync.Trigger(base.id, health); } } public override void Spawn(ByteBuffer buffer) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) _lock0 = lock0; _lock1 = lock1; BitHelper.WriteHalf(door.m_healthMax, buffer); if (((Component)((Il2CppArrayBase)(object)door.m_buttonAligns)[0]).transform.localPosition.z < 0f) { BitHelper.WriteBytes(_lock0, buffer); BitHelper.WriteBytes(_lock1, buffer); } else { BitHelper.WriteBytes(_lock1, buffer); BitHelper.WriteBytes(_lock0, buffer); } } } [ReplayData("Vanilla.Map.Generators.State", "0.0.1")] internal class rGenerator : ReplayDynamic { public LG_PowerGenerator_Core core; private bool _powered; public Vector3 position => ((Component)core).transform.position; public Quaternion rotation => ((Component)core).transform.rotation; public byte dimensionIndex => (byte)core.SpawnNode.m_dimension.DimensionIndex; public ushort serialNumber => (ushort)core.m_serialNumber; public override bool Active => (Object)(object)core != (Object)null; public override bool IsDirty => _powered != powered; private bool powered => (int)core.m_stateReplicator.State.status == 0; public rGenerator(LG_PowerGenerator_Core generator) : base(((Object)generator).GetInstanceID()) { core = generator; } public override void Write(ByteBuffer buffer) { _powered = powered; BitHelper.WriteBytes(_powered, buffer); } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); } } [HarmonyPatch] [ReplayData("Vanilla.Map.Generators", "0.0.1")] internal class rGenerators : ReplayHeader { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_PowerGenerator_Core), "Setup")] [HarmonyPostfix] private static void Setup(LG_PowerGenerator_Core __instance) { rGenerator rGenerator2 = new rGenerator(__instance); generators.Add(((ReplayDynamic)rGenerator2).id, rGenerator2); } } internal static Dictionary generators = new Dictionary(); [ReplayOnElevatorStop] private static void Trigger() { int[] array = generators.Keys.ToArray(); foreach (int key in array) { if (generators.ContainsKey(key) && (Object)(object)generators[key].core == (Object)null) { generators.Remove(key); } } Replay.Trigger((ReplayHeader)(object)new rGenerators()); foreach (rGenerator value in generators.Values) { LG_GenericCarryItemInteractionTarget val = ((Il2CppObjectBase)value.core.m_powerCellInteraction).TryCast(); if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled) { Replay.Spawn((ReplayDynamic)(object)value, true); } } generators.Clear(); } [ReplayInit] private static void Init() { generators.Clear(); } public override void Write(ByteBuffer buffer) { //IL_0043: 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) BitHelper.WriteBytes((ushort)generators.Count, buffer); foreach (rGenerator value in generators.Values) { BitHelper.WriteBytes(((ReplayDynamic)value).id, buffer); BitHelper.WriteBytes(value.dimensionIndex, buffer); BitHelper.WriteBytes(value.position, buffer); BitHelper.WriteHalf(value.rotation, buffer); BitHelper.WriteBytes(value.serialNumber, buffer); } } } [HarmonyPatch] [ReplayData("Vanilla.Map.Items", "0.0.1")] internal class rItem : ReplayDynamic { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_PickupItem_Sync), "Setup")] [HarmonyPostfix] private static void Postfix_Setup(LG_PickupItem_Sync __instance) { Replay.Spawn((ReplayDynamic)(object)new rItem(__instance), true); } } public LG_PickupItem_Sync item; private byte _dimensionIndex; private Vector3 _position; private Quaternion _rotation; private bool _onGround; private bool _linkedToMachine; private byte _player = byte.MaxValue; private ushort _serialNumber = ushort.MaxValue; public override bool Active => (Object)(object)item != (Object)null; public override bool IsDirty { get { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (dimensionIndex == _dimensionIndex && !(position != _position) && !(rotation != _rotation) && onGround == _onGround && linkedToMachine == _linkedToMachine) { return serialNumber != _serialNumber; } return true; } } private byte dimensionIndex { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) pPickupItemState state = item.m_stateReplicator.State; AIG_CourseNode val = default(AIG_CourseNode); if (((pCourseNode)(ref state.placement.node)).TryGet(ref val)) { return (byte)val.m_dimension.DimensionIndex; } return (byte)Dimension.GetDimensionFromPos(position).DimensionIndex; } } private Vector3 position => item.m_stateReplicator.State.placement.position; private Quaternion rotation => item.m_stateReplicator.State.placement.rotation; private bool onGround { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((int)item.m_stateReplicator.State.status != 0) { return item.m_stateReplicator.State.placement.droppedOnFloor; } return true; } } private bool linkedToMachine => item.m_stateReplicator.State.placement.linkedToMachine; private byte player { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) pPickupItemState state = item.m_stateReplicator.State; SNet_Player val = default(SNet_Player); if (((pPlayer)(ref state.pPlayer)).TryGetPlayer(ref val)) { return (byte)val.PlayerSlotIndex(); } return byte.MaxValue; } } private ushort serialNumber { get { CarryItemPickup_Core val = ((Il2CppObjectBase)item.item).TryCast(); if ((Object)(object)val != (Object)null) { if (((Item)val).ItemDataBlock.addSerialNumberToName) { return (ushort)val.m_serialNumber; } return ushort.MaxValue; } ResourcePackPickup val2 = ((Il2CppObjectBase)item.item).TryCast(); if ((Object)(object)val2 != (Object)null) { if (((Item)val2).ItemDataBlock.addSerialNumberToName) { return (ushort)val2.m_serialNumber; } return ushort.MaxValue; } GenericSmallPickupItem_Core val3 = ((Il2CppObjectBase)item.item).TryCast(); if ((Object)(object)val3 != (Object)null) { if (((Item)val3).ItemDataBlock.addSerialNumberToName) { return (ushort)val3.m_serialNumber1; } return ushort.MaxValue; } KeyItemPickup_Core val4 = ((Il2CppObjectBase)item.item).TryCast(); if ((Object)(object)val4 != (Object)null && val4.m_keyItem != null) { if (((Item)val4).ItemDataBlock.addSerialNumberToName) { return (ushort)val4.m_keyItem.m_keyNum; } return ushort.MaxValue; } return ushort.MaxValue; } } public rItem(LG_PickupItem_Sync item) : base((int)item.m_stateReplicator.Replicator.Key) { this.item = item; } public override void Write(ByteBuffer buffer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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) _dimensionIndex = dimensionIndex; _position = position; _rotation = rotation; _onGround = onGround; _linkedToMachine = linkedToMachine; _player = player; _serialNumber = serialNumber; BitHelper.WriteBytes(_dimensionIndex, buffer); BitHelper.WriteBytes(_position, buffer); BitHelper.WriteHalf(_rotation, buffer); BitHelper.WriteBytes(_onGround, buffer); BitHelper.WriteBytes(_linkedToMachine, buffer); BitHelper.WriteBytes(_player, buffer); BitHelper.WriteBytes(_serialNumber, buffer); } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); BitHelper.WriteBytes((BufferWriteable)(object)Identifier.From(item.item), buffer); } } internal class rLadder { public readonly byte dimension; public LG_Ladder ladder; public Vector3 top => ladder.m_ladderTop; public float height => ladder.m_height; public Quaternion rotation => ((Component)ladder).gameObject.transform.rotation; public rLadder(byte dimension, LG_Ladder ladder) { this.dimension = dimension; this.ladder = ladder; } } [HarmonyPatch] [ReplayData("Vanilla.Map.Ladders", "0.0.1")] internal class rLadders : ReplayHeader { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_BuildLadderAIGNodeJob), "Build")] [HarmonyPostfix] private static void Ladder_OnBuild(LG_BuildLadderAIGNodeJob __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) LG_Ladder ladder = __instance.m_ladder; if (!ladder.m_enemyClimbingOnly) { ladders.Add(new rLadder((byte)__instance.m_dimensionIndex, ladder)); } } } internal static List ladders = new List(); [ReplayOnElevatorStop] private static void Trigger() { rLadder[] array = ladders.ToArray(); ladders.Clear(); rLadder[] array2 = array; foreach (rLadder rLadder2 in array2) { if ((Object)(object)rLadder2.ladder != (Object)null) { ladders.Add(rLadder2); } } Replay.Trigger((ReplayHeader)(object)new rLadders()); } [ReplayInit] private static void Init() { ladders.Clear(); } public override void Write(ByteBuffer buffer) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes((ushort)ladders.Count, buffer); foreach (rLadder ladder in ladders) { BitHelper.WriteBytes(ladder.dimension, buffer); BitHelper.WriteBytes(ladder.top, buffer); BitHelper.WriteHalf(ladder.rotation, buffer); BitHelper.WriteHalf(ladder.height, buffer); } ladders.Clear(); } } [ReplayData("Vanilla.Map.ResourceContainers.State", "0.0.1")] internal class rContainer : ReplayDynamic { private LG_ResourceContainer_Storage container; private LG_WeakResourceContainer core; private LG_ResourceContainer_Sync sync; public bool registered = true; public Identifier consumableType = Identifier.unknown; public eWeakLockType assignedLock; public bool isLocker; public byte dimension; public Vector3 position; public Quaternion rotation; private bool _closed = true; public ushort serialNumber => (ushort)core.m_serialNumber; public override bool Active => (Object)(object)core != (Object)null; public override bool IsDirty => _closed != closed; private bool closed => (int)sync.m_stateReplicator.State.status != 3; private bool weaklock { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if ((Object)(object)core.m_weakLock != (Object)null) { return (int)core.m_weakLock.Status == 0; } return false; } } private bool hacklock { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if ((Object)(object)core.m_weakLock != (Object)null) { return (int)core.m_weakLock.Status == 1; } return false; } } public rContainer(LG_ResourceContainer_Storage container, bool isLocker, byte dimension) : base(((Object)container).GetInstanceID()) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) this.container = container; this.isLocker = isLocker; this.dimension = dimension; core = ((Il2CppObjectBase)container.m_core).Cast(); sync = ((Il2CppObjectBase)core.m_sync).Cast(); position = ((Component)container).transform.position; rotation = ((Component)container).transform.rotation; } public override void Write(ByteBuffer buffer) { _closed = closed; BitHelper.WriteBytes(_closed, buffer); } public override void Spawn(ByteBuffer buffer) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) ((ReplayDynamic)this).Write(buffer); eWeakLockType val = (eWeakLockType)0; if ((Object)(object)core.m_weakLock != (Object)null) { eWeakLockStatus status = core.m_weakLock.Status; if ((int)status != 0) { if ((int)status == 1) { val = (eWeakLockType)2; } } else { val = (eWeakLockType)1; } } BitHelper.WriteBytes((byte)val, buffer); } } [HarmonyPatch] [ReplayData("Vanilla.Map.ResourceContainers", "0.0.3")] internal class rContainers : ReplayHeader { [HarmonyPatch] private static class Patches { private static bool patched; private static void SetupContainer(AIG_CourseNode node, rContainer container) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) container.dimension = (byte)node.m_dimension.DimensionIndex; } [HarmonyPatch(typeof(GameDataInit), "Initialize")] [HarmonyPostfix] private static void Patch_LG_ResourceContainerBuilder() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown if (!patched) { patched = true; rMetadata.NoArtifact_Compatibility = true; MethodInfo method = typeof(LG_ResourceContainerBuilder).GetMethod("SetupFunctionGO"); if (method == null) { APILogger.Error("[Patch_LG_ResourceContainerBuilder] Failed to patch - Method 'LG_ResourceContainerBuilder.SetupFunctionGO' was not found."); return; } if (GameDataBlockBase.Wrapper.Blocks.Count == 0) { APILogger.Warn("Debug resource containers will be disabled - missing 'GameData_ArtifactDatablock_bin.json'"); return; } rMetadata.NoArtifact_Compatibility = false; Plugin.harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches).GetMethod("Postfix_LG_ResourceContainerBuilder_OnBuild", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void Postfix_LG_ResourceContainerBuilder_OnBuild(LG_ResourceContainerBuilder __instance, LG_LayerType layer, GameObject GO) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) if ((int)((LG_FunctionMarkerBuilder)__instance).m_function != 10) { return; } LG_WeakResourceContainer componentInChildren = GO.GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { return; } LG_ResourceContainer_Storage val = ((Il2CppObjectBase)componentInChildren.m_storage).Cast(); int instanceID = ((Object)val).GetInstanceID(); if (!containers.ContainsKey(instanceID)) { containers.Add(instanceID, new rContainer(val, isLocker: false, 0)); } rContainer rContainer2 = containers[instanceID]; rContainer2.assignedLock = (eWeakLockType)((!(__instance.m_lockRandom < 0.5f)) ? 1 : 2); ConsumableDistributionDataBlock block = GameDataBlockBase.GetBlock(((LG_FunctionMarkerBuilder)__instance).m_node.m_zone.m_settings.m_zoneData.ConsumableDistributionInZone); if (block != null) { State state = Random.state; Random.InitState(__instance.m_randomSeed); float[] array = new float[block.SpawnData.Count]; for (int i = 0; i < block.SpawnData.Count; i++) { array[i] = block.SpawnData[i].Weight; } BuilderWeightedRandom val2 = new BuilderWeightedRandom(); val2.Setup(Il2CppStructArray.op_Implicit(array)); rContainer2.consumableType = Identifier.Item(block.SpawnData[val2.GetRandomIndex(Random.value)].ItemID); Random.state = state; } } [HarmonyPatch(typeof(AIG_CourseNode), "RegisterContainer")] [HarmonyPostfix] private static void ResourceContainer_Add(AIG_CourseNode __instance, LG_ResourceContainer_Storage container) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)container).GetInstanceID(); if (!containers.ContainsKey(instanceID)) { containers.Add(instanceID, new rContainer(container, isLocker: false, (byte)__instance.m_dimension.DimensionIndex)); } SetupContainer(__instance, containers[instanceID]); } [HarmonyPatch(typeof(AIG_CourseNode), "UnregisterContainer")] [HarmonyPostfix] private static void ResourceContainer_Remove(AIG_CourseNode __instance, LG_ResourceContainer_Storage container) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)container).GetInstanceID(); if (!containers.ContainsKey(instanceID)) { containers.Add(instanceID, new rContainer(container, isLocker: false, (byte)__instance.m_dimension.DimensionIndex)); } SetupContainer(__instance, containers[instanceID]); containers[instanceID].registered = false; } [HarmonyPatch(typeof(LG_ResourceContainer_Storage), "Setup")] [HarmonyPostfix] private static void Resource_Setup(LG_ResourceContainer_Storage __instance, iLG_ResourceContainer_Core core, bool isLocker) { int instanceID = ((Object)__instance).GetInstanceID(); if (!containers.ContainsKey(instanceID)) { containers.Add(instanceID, new rContainer(__instance, isLocker: false, 0)); } containers[instanceID].isLocker = isLocker; } } internal static Dictionary containers = new Dictionary(); [ReplayOnElevatorStop] private static void Trigger() { Replay.Trigger((ReplayHeader)(object)new rContainers()); foreach (rContainer value in containers.Values) { Replay.Spawn((ReplayDynamic)(object)value, true); } containers.Clear(); } [ReplayInit] private static void Init() { containers.Clear(); } public override void Write(ByteBuffer buffer) { //IL_0043: 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_008f: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes((ushort)containers.Count, buffer); foreach (rContainer value in containers.Values) { BitHelper.WriteBytes(((ReplayDynamic)value).id, buffer); BitHelper.WriteBytes(value.dimension, buffer); BitHelper.WriteBytes(value.position, buffer); BitHelper.WriteHalf(value.rotation, buffer); BitHelper.WriteBytes(value.serialNumber, buffer); BitHelper.WriteBytes(value.isLocker, buffer); BitHelper.WriteBytes((BufferWriteable)(object)value.consumableType, buffer); BitHelper.WriteBytes(value.registered, buffer); BitHelper.WriteBytes((byte)value.assignedLock, buffer); } } } internal class rTerminal { public readonly byte dimension; public readonly int id; public readonly ushort serialNumber; public LG_ComputerTerminal terminal; public Vector3 position => ((Component)terminal).transform.position; public Quaternion rotation => ((Component)terminal).transform.rotation; public rTerminal(byte dimension, LG_ComputerTerminal terminal) { id = ((Object)terminal).GetInstanceID(); this.dimension = dimension; this.terminal = terminal; serialNumber = (ushort)terminal.m_serialNumber; } } [HarmonyPatch] [ReplayData("Vanilla.Map.Terminals", "0.0.2")] internal class rTerminals : ReplayHeader { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_ComputerTerminal), "Setup")] [HarmonyPostfix] private static void Terminal_Setup(LG_ComputerTerminal __instance) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)__instance).GetInstanceID(); if (!terminals.ContainsKey(instanceID)) { if (__instance.SpawnNode == null) { terminals.Add(instanceID, new rTerminal((byte)Dimension.GetDimensionFromPos(((Component)__instance).transform.position).DimensionIndex, __instance)); } else { terminals.Add(instanceID, new rTerminal((byte)__instance.SpawnNode.m_dimension.DimensionIndex, __instance)); } } } } internal static Dictionary terminals = new Dictionary(); [ReplayOnElevatorStop] private static void Trigger() { int[] array = terminals.Keys.ToArray(); foreach (int key in array) { if (terminals.ContainsKey(key) && (Object)(object)terminals[key].terminal == (Object)null) { terminals.Remove(key); } } Replay.Trigger((ReplayHeader)(object)new rTerminals()); } [ReplayInit] private static void Init() { terminals.Clear(); } public override void Write(ByteBuffer buffer) { //IL_0043: 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) BitHelper.WriteBytes((ushort)terminals.Count, buffer); foreach (rTerminal value in terminals.Values) { BitHelper.WriteBytes(value.id, buffer); BitHelper.WriteBytes(value.dimension, buffer); BitHelper.WriteBytes(value.position, buffer); BitHelper.WriteHalf(value.rotation, buffer); BitHelper.WriteBytes(value.serialNumber, buffer); } terminals.Clear(); } } } namespace Vanilla.Sentries { internal struct SentryTransform : IReplayTransform { private SentryGunInstance sentry; public bool active => (Object)(object)sentry != (Object)null; public byte dimensionIndex => (byte)sentry.CourseNode.m_dimension.DimensionIndex; public Vector3 position => ((Component)sentry).transform.position; public Quaternion rotation { get { //IL_0033: 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) if (sentry.m_firing != null) { return Quaternion.LookRotation(sentry.m_firing.MuzzleAlign.forward); } return ((Component)sentry).transform.rotation; } } public SentryTransform(SentryGunInstance sentry) { this.sentry = sentry; } } [HarmonyPatch] [ReplayData("Vanilla.Sentry", "0.0.2")] public class rSentry : DynamicRotation { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(SentryGunInstance), "OnSpawn")] [HarmonyPostfix] private static void Postfix_OnSpawn(SentryGunInstance __instance, pGearSpawnData spawnData) { Replay.Spawn((ReplayDynamic)(object)new rSentry(__instance), true); } [HarmonyPatch(typeof(SentryGunInstance), "OnDespawn")] [HarmonyPostfix] private static void Postfix_OnDespawn(SentryGunInstance __instance) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(((Object)__instance).GetInstanceID()), true); } } private SentryGunInstance sentry; private Vector3 spawnPosition; private byte spawnDimension; public rSentry(SentryGunInstance sentry) : base(((Object)sentry).GetInstanceID(), (IReplayTransform)(object)new SentryTransform(sentry)) { //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) this.sentry = sentry; spawnPosition = base.transform.position; spawnDimension = base.transform.dimensionIndex; } public override void Spawn(ByteBuffer buffer) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes(spawnDimension, buffer); BitHelper.WriteBytes(spawnPosition, buffer); ((DynamicRotation)this).Spawn(buffer); if ((Object)(object)((Item)sentry).Owner != (Object)null) { BitHelper.WriteBytes(true, buffer); BitHelper.WriteBytes(((Agent)((Item)sentry).Owner).GlobalID, buffer); } else { BitHelper.WriteBytes(false, buffer); } } } } namespace Vanilla.Player { internal static class PlayerManager { [ReplayOnPlayerSpawn] private static void Spawn(PlayerAgent agent) { Replay.Spawn((ReplayDynamic)(object)new rPlayer(agent), true); PlayerBoosterImplantState val = default(PlayerBoosterImplantState); if (BoosterImplantManager.TryGetPlayerBoosterImplantState(agent.Owner, ref val) && val != null) { Replay.Spawn((ReplayDynamic)(object)new rPlayerBoosters(agent, val), true); } Replay.Spawn((ReplayDynamic)(object)new rPlayerAnimation(agent), true); Replay.Spawn((ReplayDynamic)(object)new rPlayerBackpack(agent), true); Replay.Spawn((ReplayDynamic)(object)new rPlayerStats(agent), true); } [ReplayOnPlayerDespawn] private static void Despawn(int id) { Replay.TryDespawn(id); Replay.TryDespawn(id); Replay.TryDespawn(id); Replay.TryDespawn(id); Replay.TryDespawn(id); } } [ReplayData("Vanilla.Player", "0.0.2")] public class rPlayer : DynamicTransform { public PlayerAgent agent; private Identifier lastEquipped = Identifier.unknown; private bool flashlightEnabled; private float flashlightRange = 1000f; private Identifier equipped => Identifier.From(agent.Inventory.WieldedItem); private bool _flashlightEnabled { get { if (!((Object)(object)agent.Inventory != (Object)null)) { return false; } return agent.Inventory.FlashlightEnabled; } } private float _flashlightRange { get { if (!((Object)(object)agent.Inventory != (Object)null) || !agent.Inventory.FlashlightEnabled) { return 1000f; } return agent.Inventory.m_flashlight.range; } } public override bool Active { get { if ((Object)(object)agent != (Object)null) { return (Object)(object)agent.Owner != (Object)null; } return false; } } public override bool IsDirty { get { if (!((DynamicTransform)this).IsDirty && !(equipped != lastEquipped) && flashlightEnabled == _flashlightEnabled) { return flashlightRange != _flashlightRange; } return true; } } public rPlayer(PlayerAgent player) : base((int)((Agent)player).GlobalID, (IReplayTransform)(object)new AgentTransform((Agent)(object)player)) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) agent = player; } public override void Write(ByteBuffer buffer) { flashlightEnabled = _flashlightEnabled; flashlightRange = _flashlightRange; ((DynamicTransform)this).Write(buffer); BitHelper.WriteBytes((BufferWriteable)(object)equipped, buffer); BitHelper.WriteBytes(flashlightEnabled, buffer); BitHelper.WriteHalf(flashlightRange, buffer); lastEquipped = equipped; } public override void Spawn(ByteBuffer buffer) { ((DynamicTransform)this).Spawn(buffer); BitHelper.WriteBytes(agent.Owner.Lookup, buffer); BitHelper.WriteBytes((byte)agent.PlayerSlotIndex, buffer); BitHelper.WriteBytes(agent.Owner.NickName, buffer); } } [ReplayData("Vanilla.Player.Animation.MeleeSwing", "0.0.1")] public class rMeleeSwing : Id { private bool charged; public rMeleeSwing(PlayerAgent player, bool charged = false) : base((int)((Agent)player).GlobalID) { this.charged = charged; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(charged, buffer); } } [ReplayData("Vanilla.Player.Animation.MeleeShove", "0.0.1")] public class rMeleeShove : Id { public rMeleeShove(PlayerAgent player) : base((int)((Agent)player).GlobalID) { } } [ReplayData("Vanilla.Player.Animation.ConsumableThrow", "0.0.1")] public class rConsumableThrow : Id { public rConsumableThrow(PlayerAgent player) : base((int)((Agent)player).GlobalID) { } } [ReplayData("Vanilla.Player.Animation.Revive", "0.0.1")] public class rRevive : Id { public rRevive(PlayerAgent player) : base((int)((Agent)player).GlobalID) { } } [ReplayData("Vanilla.Player.Animation.Downed", "0.0.1")] public class rDowned : Id { public rDowned(PlayerAgent player) : base((int)((Agent)player).GlobalID) { } } [HarmonyPatch] [ReplayData("Vanilla.Player.Animation", "0.0.1")] public class rPlayerAnimation : ReplayDynamic { [HarmonyPatch] private static class Patches { private static bool swingTrigger; private static void Trigger(Id e) { if (Replay.Has(e.id)) { Replay.Trigger((ReplayEvent)(object)e); } } [HarmonyPatch(typeof(PLOC_Downed), "OnPlayerRevived")] [HarmonyPrefix] private static void Prefix_OnPlayerRevived(PLOC_Downed __instance) { Trigger((Id)(object)new rRevive(((PLOC_Base)__instance).m_owner)); } [HarmonyPatch(typeof(PLOC_Downed), "CommonEnter")] [HarmonyPrefix] private static void Prefix_CommonEnter(PLOC_Downed __instance) { Trigger((Id)(object)new rDowned(((PLOC_Base)__instance).m_owner)); } [HarmonyPatch(typeof(PlayerSync), "SendThrowStatus")] [HarmonyPrefix] private static void Prefix_SendThrowStatus(PlayerSync __instance, StatusEnum status, bool applyLocally) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!applyLocally) { HandleThrowState(__instance.m_agent, status); } } [HarmonyPatch(typeof(PlayerInventorySynced), "SyncThrowState")] [HarmonyPrefix] private static void Prefix_SyncThrowState(PlayerInventorySynced __instance, StatusEnum status) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) HandleThrowState(((PlayerInventoryBase)__instance).Owner, status); } private static void HandleThrowState(PlayerAgent player, StatusEnum status) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 rPlayerAnimation rPlayerAnimation2 = default(rPlayerAnimation); if (!Replay.TryGet((int)((Agent)player).GlobalID, ref rPlayerAnimation2)) { return; } rPlayerAnimation rPlayerAnimation3 = rPlayerAnimation2; if ((int)status != 1) { if ((int)status == 2) { rPlayerAnimation3._chargingThrow = false; Trigger((Id)(object)new rConsumableThrow(player)); } } else { rPlayerAnimation3._chargingThrow = true; } } [HarmonyPatch(typeof(MWS_ChargeUp), "Enter")] [HarmonyPostfix] private static void Postfix_MWS_ChargeUp(MWS_ChargeUp __instance) { rPlayerAnimation rPlayerAnimation2 = default(rPlayerAnimation); if (Replay.TryGet((int)((Agent)((Item)((MWS_Base)__instance).m_weapon).Owner).GlobalID, ref rPlayerAnimation2)) { rPlayerAnimation2._chargingMelee = true; } } [HarmonyPatch(typeof(MWS_ChargeUp), "Exit")] [HarmonyPostfix] private static void Postfix_ReceiveClassItemSync(MWS_ChargeUp __instance) { rPlayerAnimation rPlayerAnimation2 = default(rPlayerAnimation); if (Replay.TryGet((int)((Agent)((Item)((MWS_Base)__instance).m_weapon).Owner).GlobalID, ref rPlayerAnimation2)) { rPlayerAnimation2._chargingMelee = false; } } [HarmonyPatch(typeof(MWS_AttackLight), "Enter")] [HarmonyPostfix] private static void Postfix_MWS_AttackLight_Enter(MWS_AttackLight __instance) { swingTrigger = false; } [HarmonyPatch(typeof(MWS_AttackLight), "UpdateStateInput")] [HarmonyPostfix] private static void Postfix_MWS_AttackLight(MWS_AttackLight __instance) { if ((!__instance.m_canCharge || !((ItemEquippable)((MWS_Base)__instance).m_weapon).FireButton) && !swingTrigger) { Trigger((Id)(object)new rMeleeSwing(((Item)((MWS_Base)__instance).m_weapon).Owner)); swingTrigger = true; } } [HarmonyPatch(typeof(MWS_AttackHeavy), "Enter")] [HarmonyPostfix] private static void Postfix_MWS_AttackHeavy(MWS_AttackHeavy __instance) { Trigger((Id)(object)new rMeleeSwing(((Item)((MWS_Base)__instance).m_weapon).Owner, charged: true)); } [HarmonyPatch(typeof(MeleeWeaponThirdPerson), "OnWield")] [HarmonyPrefix] private static void Prefix_ReceiveClassItemSync(MeleeWeaponThirdPerson __instance) { rPlayerAnimation rPlayerAnimation2 = default(rPlayerAnimation); if (Replay.TryGet((int)((Agent)((Item)__instance).Owner).GlobalID, ref rPlayerAnimation2)) { rPlayerAnimation obj = rPlayerAnimation2; obj.meleeWeaponThirdPerson = __instance; obj._chargingMelee = false; } } [HarmonyPatch(typeof(MeleeWeaponThirdPerson), "ReceiveClassItemSync")] [HarmonyPrefix] private static void Prefix_ReceiveClassItemSync(MeleeWeaponThirdPerson __instance, pSimpleItemSyncData data) { //IL_001e: 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) rPlayerAnimation rPlayerAnimation2 = default(rPlayerAnimation); if (!Replay.TryGet((int)((Agent)((Item)__instance).Owner).GlobalID, ref rPlayerAnimation2)) { return; } rPlayerAnimation rPlayerAnimation3 = rPlayerAnimation2; rPlayerAnimation3.meleeWeaponThirdPerson = __instance; if (data.inFireMode) { rPlayerAnimation3._chargingMelee = false; if (__instance.m_inChargeAnim) { Trigger((Id)(object)new rMeleeSwing(((Item)__instance).Owner, charged: true)); } else { Trigger((Id)(object)new rMeleeSwing(((Item)__instance).Owner)); } } else if (data.inAimMode) { rPlayerAnimation3._chargingMelee = true; } } [HarmonyPatch(typeof(MWS_Push), "Enter")] [HarmonyPostfix] private static void Postfix_MWS_Push(MWS_Push __instance) { Trigger((Id)(object)new rMeleeShove(((Item)((MWS_Base)__instance).m_weapon).Owner)); } [HarmonyPatch(typeof(PlayerInventorySynced), "SyncGenericInteract")] [HarmonyPrefix] private static void Prefix_SyncGenericInteract(PlayerInventorySynced __instance, TypeEnum type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)type == 7) { Trigger((Id)(object)new rMeleeShove(((PlayerInventoryBase)__instance).Owner)); } } } public PlayerAgent player; private Animator animator; private MeleeWeaponThirdPerson? meleeWeaponThirdPerson; private byte velFwd; private byte velRight; private byte crouch; private Vector3 targetLookDir; private const long landAnimDuration = 867L; private long landTriggered; private byte _state; private byte state; private bool _chargingMelee; private bool chargingMelee; private bool _chargingThrow; private bool chargingThrow; public bool isReloading; public bool wasReloading; private float reloadTime; private Identifier lastEquipped = Identifier.unknown; public override bool Active { get { if ((Object)(object)player != (Object)null) { return (Object)(object)player.Owner != (Object)null; } return false; } } public override bool IsDirty { get { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Invalid comparison between I4 and Unknown if (equipped != lastEquipped) { _chargingMelee = false; _chargingThrow = false; lastEquipped = equipped; } if ((Object)(object)meleeWeaponThirdPerson != (Object)null) { _chargingMelee = meleeWeaponThirdPerson.m_inChargeAnim; } bool num = velFwd != compress(_velFwd, 10f) || velRight != compress(_velRight, 10f); bool flag = crouch != (byte)(_crouch * 255f); bool flag2 = targetLookDir != ((Agent)player).TargetLookDir; if (!(num || flag || flag2) && state == (int)player.Locomotion.m_currentStateEnum && chargingMelee == _chargingMelee && chargingThrow == _chargingThrow) { return isReloading != _isReloading; } return true; } } private float _velFwd => animator.GetFloat("MoveBackwardForward"); private float _velRight => animator.GetFloat("MoveLeftRight"); private float _crouch => animator.GetFloat("Crouch"); private bool _isReloading { get { if ((Object)(object)player.Inventory == (Object)null) { return false; } if ((Object)(object)player.Inventory.m_wieldedItem == (Object)null) { return false; } if (!player.Inventory.m_wieldedItem.CanReload) { return false; } return player.Inventory.m_wieldedItem.IsReloading; } } private float _reloadTime { get { if ((Object)(object)player.Inventory == (Object)null) { return 0f; } if ((Object)(object)player.Inventory.m_wieldedItem == (Object)null) { return 0f; } if (!player.Inventory.m_wieldedItem.CanReload) { return 0f; } return player.Inventory.m_wieldedItem.ReloadTime; } } private Identifier equipped => Identifier.From(player.Inventory.WieldedItem); private static byte compress(float value, float max) { value /= max; value = Mathf.Clamp(value, -1f, 1f); value = Mathf.Clamp01((value + 1f) / 2f); return (byte)(value * 255f); } public rPlayerAnimation(PlayerAgent player) : base((int)((Agent)player).GlobalID) { this.player = player; animator = player.AnimatorBody; } public override void Write(ByteBuffer buffer) { //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_0075: 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_00d9: Expected I4, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 velRight = compress(_velRight, 10f); velFwd = compress(_velFwd, 10f); BitHelper.WriteBytes(velRight, buffer); BitHelper.WriteBytes(velFwd, buffer); crouch = (byte)(_crouch * 255f); BitHelper.WriteBytes(crouch, buffer); targetLookDir = ((Agent)player).TargetLookDir; BitHelper.WriteHalf(targetLookDir, buffer); if (Raudy.Now - landTriggered > 867 || state != 5 || (int)player.Locomotion.m_currentStateEnum == 3 || (int)player.Locomotion.m_currentStateEnum == 4) { state = (byte)(int)player.Locomotion.m_currentStateEnum; if ((_state == 3 || _state == 4) && state != 3 && state != 4) { landTriggered = Raudy.Now; state = 5; } } _state = state; BitHelper.WriteBytes(state, buffer); chargingMelee = _chargingMelee; BitHelper.WriteBytes(chargingMelee, buffer); chargingThrow = _chargingThrow; BitHelper.WriteBytes(chargingThrow, buffer); wasReloading = isReloading; isReloading = _isReloading; BitHelper.WriteBytes(isReloading, buffer); reloadTime = _reloadTime; BitHelper.WriteHalf(reloadTime, buffer); } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); } } [ReplayData("Vanilla.Player.Backpack", "0.0.2")] internal class rPlayerBackpack : ReplayDynamic { public PlayerAgent agent; private Identifier lastMelee = Identifier.unknown; private Identifier lastPrimary = Identifier.unknown; private Identifier lastSpecial = Identifier.unknown; private Identifier lastTool = Identifier.unknown; private Identifier lastPack = Identifier.unknown; private Identifier lastConsumable = Identifier.unknown; private Identifier lastHeavyItem = Identifier.unknown; private Identifier lastHackingTool = Identifier.unknown; private Identifier lastVanityHelmet = Identifier.unknown; private Identifier lastVanityTorso = Identifier.unknown; private Identifier lastVanityLegs = Identifier.unknown; private Identifier lastVanityBackpack = Identifier.unknown; private Identifier lastVanityPallete = Identifier.unknown; private Identifier melee => GetSlotId((InventorySlot)10); private Identifier primary => GetSlotId((InventorySlot)1); private Identifier special => GetSlotId((InventorySlot)2); private Identifier tool => GetSlotId((InventorySlot)3); private Identifier pack => GetSlotId((InventorySlot)4); private Identifier consumable => GetSlotId((InventorySlot)5); private Identifier heavyItem => GetSlotId((InventorySlot)8); private Identifier hackingTool => GetSlotId((InventorySlot)11); private Identifier vanityHelmet => GetVanityItem((ClothesType)0); private Identifier vanityTorso => GetVanityItem((ClothesType)1); private Identifier vanityLegs => GetVanityItem((ClothesType)2); private Identifier vanityBackpack => GetVanityItem((ClothesType)3); private Identifier vanityPallete => GetVanityItem((ClothesType)4); public override bool Active { get { if ((Object)(object)agent != (Object)null) { return (Object)(object)agent.Owner != (Object)null; } return false; } } public override bool IsDirty { get { if (!(melee != lastMelee) && !(primary != lastPrimary) && !(special != lastSpecial) && !(tool != lastTool) && !(pack != lastPack) && !(consumable != lastConsumable) && !(heavyItem != lastHeavyItem) && !(hackingTool != lastHackingTool) && !(vanityHelmet != lastVanityHelmet) && !(vanityTorso != lastVanityTorso) && !(vanityLegs != lastVanityLegs) && !(vanityBackpack != lastVanityBackpack)) { return vanityPallete != lastVanityPallete; } return true; } } private Identifier GetSlotId(InventorySlot slot) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) try { BackpackItem val = default(BackpackItem); if (PlayerBackpackManager.TryGetItem(agent.Owner, slot, ref val) && (Object)(object)val.Instance != (Object)null) { return Identifier.From(((Il2CppObjectBase)val.Instance).Cast()); } } catch { } return Identifier.unknown; } private Identifier GetVanityItem(ClothesType type) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown try { PlayerBackpack backpack = PlayerBackpackManager.GetBackpack(agent.Owner); if (backpack != null) { return Identifier.Vanity(((Il2CppArrayBase)(object)backpack.m_vanityItems)[(int)type]); } } catch { } return Identifier.unknown; } public rPlayerBackpack(PlayerAgent player) : base((int)((Agent)player).GlobalID) { agent = player; } public override void Write(ByteBuffer buffer) { lastMelee = melee; lastPrimary = primary; lastSpecial = special; lastTool = tool; lastPack = pack; lastConsumable = consumable; lastHeavyItem = heavyItem; lastHackingTool = hackingTool; lastVanityHelmet = vanityHelmet; lastVanityTorso = vanityTorso; lastVanityLegs = vanityLegs; lastVanityBackpack = vanityBackpack; lastVanityPallete = vanityPallete; BitHelper.WriteBytes((BufferWriteable)(object)lastMelee, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastPrimary, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastSpecial, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastTool, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastPack, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastConsumable, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastHeavyItem, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastHackingTool, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastVanityHelmet, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastVanityTorso, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastVanityLegs, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastVanityBackpack, buffer); BitHelper.WriteBytes((BufferWriteable)(object)lastVanityPallete, buffer); } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); } } [ReplayData("Vanilla.Player.Boosters", "0.0.1")] internal class rPlayerBoosters : ReplayDynamic { private PlayerBoosterImplantState state; private PlayerAgent player; public bool[]? conditionsMet; public override bool Active { get { if (state != null) { return (Object)(object)player != (Object)null; } return false; } } public override bool IsDirty { get { if (conditionsMet == null) { return false; } for (int i = 0; i < conditionsMet.Length; i++) { if ((i < ((Il2CppArrayBase)(object)state.m_boosterImplants).Count && ((Il2CppArrayBase)(object)state.m_boosterImplants)[i].ConditionsMet) != conditionsMet[i]) { return true; } } return false; } } public rPlayerBoosters(PlayerAgent player, PlayerBoosterImplantState state) : base((int)((Agent)player).GlobalID) { this.player = player; this.state = state; } public override void Write(ByteBuffer buffer) { for (int i = 0; i < conditionsMet.Length; i++) { bool flag = i < ((Il2CppArrayBase)(object)state.m_boosterImplants).Count && ((Il2CppArrayBase)(object)state.m_boosterImplants)[i].ConditionsMet; conditionsMet[i] = flag; BitHelper.WriteBytes(flag, buffer); } } public override void Spawn(ByteBuffer buffer) { //IL_0062: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes((byte)((Il2CppArrayBase)(object)state.m_boosterImplants).Count, buffer); foreach (BoosterImplantInstance item in (Il2CppArrayBase)(object)state.m_boosterImplants) { BitHelper.WriteBytes((ushort)item.BoosterImplantID, buffer); BitHelper.WriteBytes((byte)((Il2CppArrayBase)(object)item.BoosterEffects).Count, buffer); foreach (BoosterEffectInstance item2 in (Il2CppArrayBase)(object)item.BoosterEffects) { BitHelper.WriteBytes((byte)item2.Effect, buffer); BitHelper.WriteHalf(item2.Value, buffer); } BitHelper.WriteBytes((byte)((Il2CppArrayBase)(object)item.BoosterConditions).Count, buffer); foreach (BoosterCondition item3 in (Il2CppArrayBase)(object)item.BoosterConditions) { BitHelper.WriteBytes((byte)item3, buffer); } } conditionsMet = new bool[((Il2CppArrayBase)(object)state.m_boosterImplants).Count]; for (int i = 0; i < conditionsMet.Length; i++) { conditionsMet[i] = false; } } } [ReplayData("Vanilla.Player.Stats", "0.0.3")] public class rPlayerStats : ReplayDynamic { private static class Sync { private const string eventName = "Vanilla.Player.Stats.Stamina"; private static ByteBuffer packet = new ByteBuffer(); [ReplayPluginLoad] private static void Load() { RNet.Register("Vanilla.Player.Stats.Stamina", (Action>)OnReceive); } public static void Trigger(int id, byte stamina) { ByteBuffer val = packet; val.Clear(); BitHelper.WriteBytes(id, val); BitHelper.WriteBytes(stamina, val); RNet.Trigger("Vanilla.Player.Stats.Stamina", val); } private static void OnReceive(ulong sender, ArraySegment packet) { int num = 0; int num2 = BitHelper.ReadInt(packet, ref num); byte stamina = BitHelper.ReadByte(packet, ref num); rPlayerStats rPlayerStats2 = default(rPlayerStats); if (Replay.TryGet(num2, ref rPlayerStats2)) { rPlayerStats2._stamina = stamina; } } } public PlayerAgent player; private PlayerBackpack backpack; private byte _stamina = byte.MaxValue; private byte oldHealth = byte.MaxValue; private byte oldInfection = byte.MaxValue; private byte oldPrimaryAmmo = byte.MaxValue; private byte oldSecondaryAmmo = byte.MaxValue; private byte oldToolAmmo = byte.MaxValue; private byte oldConsumableAmmo = byte.MaxValue; private byte oldResourceAmmo = byte.MaxValue; private byte oldStamina = byte.MaxValue; public override bool Active { get { if ((Object)(object)player != (Object)null) { return (Object)(object)player.Owner != (Object)null; } return false; } } public override bool IsDirty { get { if (health == oldHealth && infection == oldInfection && primaryAmmo == oldPrimaryAmmo && secondaryAmmo == oldSecondaryAmmo && toolAmmo == oldToolAmmo && consumableAmmo == oldConsumableAmmo && resourceAmmo == oldResourceAmmo) { return stamina != oldStamina; } return true; } } private byte health => (byte)(255f * ((Dam_SyncedDamageBase)player.Damage).Health / ((Dam_SyncedDamageBase)player.Damage).HealthMax); private byte infection => (byte)(255f * player.Damage.Infection); private byte primaryAmmo { get { InventorySlotAmmo inventorySlotAmmo = backpack.AmmoStorage.GetInventorySlotAmmo((AmmoType)0); BackpackItem val = default(BackpackItem); if (backpack.TryGetBackpackItem((InventorySlot)1, ref val)) { ItemEquippable val2 = ((Il2CppObjectBase)val.Instance).TryCast(); if ((Object)(object)val2 != (Object)null) { return (byte)(255f * (float)(inventorySlotAmmo.BulletsInPack + val2.GetCurrentClip()) * inventorySlotAmmo.BulletsToRelConv); } } return (byte)(255f * inventorySlotAmmo.RelInPack); } } private byte secondaryAmmo { get { InventorySlotAmmo inventorySlotAmmo = backpack.AmmoStorage.GetInventorySlotAmmo((AmmoType)1); BackpackItem val = default(BackpackItem); if (backpack.TryGetBackpackItem((InventorySlot)2, ref val)) { ItemEquippable val2 = ((Il2CppObjectBase)val.Instance).TryCast(); if ((Object)(object)val2 != (Object)null) { return (byte)(255f * (float)(inventorySlotAmmo.BulletsInPack + val2.GetCurrentClip()) * inventorySlotAmmo.BulletsToRelConv); } } return (byte)(255f * inventorySlotAmmo.RelInPack); } } private byte toolAmmo { get { InventorySlotAmmo inventorySlotAmmo = backpack.AmmoStorage.GetInventorySlotAmmo((AmmoType)2); BackpackItem val = default(BackpackItem); if (backpack.IsDeployed((InventorySlot)3) && PlayerBackpackManager.TryGetItem(player.Owner, (InventorySlot)3, ref val)) { SentryGunInstance val2 = ((Il2CppObjectBase)val.Instance).TryCast(); if ((Object)(object)val2 != (Object)null) { int num = (int)(val2.m_ammo / inventorySlotAmmo.CostOfBullet); return (byte)(255f * (float)num * inventorySlotAmmo.BulletsToRelConv); } } return (byte)(255f * inventorySlotAmmo.RelInPack); } } private byte consumableAmmo { get { InventorySlotAmmo inventorySlotAmmo = backpack.AmmoStorage.GetInventorySlotAmmo((AmmoType)5); return (byte)(255f * inventorySlotAmmo.RelInPack); } } private byte resourceAmmo { get { float num = backpack.AmmoStorage.GetInventorySlotAmmo((AmmoType)3).RelInPack * 5f / 6f; return (byte)(255f * num); } } private byte stamina { get { if (((Agent)player).IsLocallyOwned) { return (byte)(255f * Mathf.Clamp01(player.Stamina.m_currentStamina)); } return _stamina; } } public rPlayerStats(PlayerAgent player) : base((int)((Agent)player).GlobalID) { this.player = player; backpack = PlayerBackpackManager.GetBackpack(player.Owner); } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes(health, buffer); BitHelper.WriteBytes(infection, buffer); BitHelper.WriteBytes(primaryAmmo, buffer); BitHelper.WriteBytes(secondaryAmmo, buffer); BitHelper.WriteBytes(toolAmmo, buffer); BitHelper.WriteBytes(consumableAmmo, buffer); BitHelper.WriteBytes(resourceAmmo, buffer); BitHelper.WriteBytes(stamina, buffer); if (stamina != oldStamina && !player.Owner.IsBot) { Sync.Trigger(base.id, stamina); } oldHealth = health; oldInfection = infection; oldPrimaryAmmo = primaryAmmo; oldSecondaryAmmo = secondaryAmmo; oldToolAmmo = toolAmmo; oldConsumableAmmo = consumableAmmo; oldResourceAmmo = resourceAmmo; oldStamina = stamina; } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); } } } namespace Vanilla.Objectives { [ReplayData("Vanilla.Objectives.Reactor", "0.0.1")] public class rReactor : ReplayDynamic { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")] [HarmonyPostfix] private static void Postfix_OnBuildDone(LG_WardenObjective_Reactor __instance) { if (__instance.m_isWardenObjective) { Replay.Spawn((ReplayDynamic)(object)new rReactor(__instance), true); } } } private LG_WardenObjective_Reactor core; private ushort[] terminalSerials; private byte status; private byte wave; private float waveDuration; private byte waveProgress; public override bool Active => (Object)(object)core != (Object)null; public override bool IsDirty { get { if (core.m_currentWaveData != null) { if (status == _status && wave == _wave && waveDuration == _waveDuration) { return waveProgress != _waveProgress; } return true; } return false; } } private byte _status => (byte)core.m_currentState.status; private byte _wave => (byte)(core.m_currentWaveCount - 1); private float _waveDuration => core.m_currentDuration; private byte _waveProgress => (byte)(255f * Mathf.Clamp01(core.m_currentWaveProgress)); public rReactor(LG_WardenObjective_Reactor core) : base((int)core.m_stateReplicator.Replicator.Key) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) this.core = core; List reactorWaves = WardenObjectiveManager.Current.m_activeWardenObjectives[core.OriginLayer].ReactorWaves; terminalSerials = new ushort[reactorWaves.Count]; for (int i = 0; i < terminalSerials.Length; i++) { ReactorWaveData val = reactorWaves[i]; if (val.HasVerificationTerminal && ushort.TryParse(val.VerificationTerminalSerial.Trim().ToUpper().Replace("TERMINAL_", ""), out var result)) { terminalSerials[i] = result; } else { terminalSerials[i] = ushort.MaxValue; } } } public override void Write(ByteBuffer buffer) { status = _status; wave = _wave; waveDuration = _waveDuration; waveProgress = _waveProgress; BitHelper.WriteBytes(status, buffer); BitHelper.WriteBytes(wave, buffer); BitHelper.WriteHalf(waveDuration, buffer); BitHelper.WriteBytes(waveProgress, buffer); } public override void Spawn(ByteBuffer buffer) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown BitHelper.WriteBytes((ushort)core.m_serialNumber, buffer); BitHelper.WriteBytes((byte)(int)core.OriginLayer, buffer); BitHelper.WriteBytes(((Object)core.m_terminal).GetInstanceID(), buffer); BitHelper.WriteBytes((byte)core.m_waveCountMax, buffer); for (int i = 0; i < core.m_waveCountMax; i++) { BitHelper.WriteBytes(terminalSerials[i], buffer); BitHelper.WriteBytes(((Il2CppArrayBase)(object)core.m_overrideCodes)[i], buffer); } } } } namespace Vanilla.Noises { [HarmonyPatch] internal class Noises { private static bool fromMWS_AttackHit; [HarmonyPatch(typeof(NoiseManager), "ReceiveNoise")] [HarmonyPostfix] private static void RemoteNoise(pNM_NoiseData data) { if (SNet.IsMaster) { PlayerAgent source = null; SNet_Player val = default(SNet_Player); if (SNetUtils.TryGetSender((SNet_Packet)(object)NoiseManager.s_noisePacket, ref val)) { source = ((Il2CppObjectBase)val.PlayerAgent).TryCast(); } NoiseTracker.TrackNextNoise(new NoiseInfo(source)); } } [HarmonyPatch(typeof(MWS_AttackHit), "Update")] [HarmonyPrefix] private static void Prefix_MWS_AttackHit() { fromMWS_AttackHit = true; } [HarmonyPatch(typeof(MWS_AttackHit), "Update")] [HarmonyPostfix] private static void Postfix_MWS_AttackHit() { fromMWS_AttackHit = false; } [HarmonyPatch(typeof(NoiseManager), "MakeNoise")] [HarmonyPrefix] private static void MakeNoise() { if (fromMWS_AttackHit) { NoiseTracker.TrackNextNoise(new NoiseInfo(PlayerManager.GetLocalPlayerAgent())); } } [HarmonyPatch(typeof(SentryGunInstance), "OnGearSpawnComplete")] [HarmonyPostfix] private static void SentryShootNoise(SentryGunInstance __instance) { SentryGunInstance __instance2 = __instance; if (!SNet.IsMaster) { return; } SentryGunInstance_Firing_Bullets val = ((Il2CppObjectBase)__instance2.m_firing).Cast(); Action previous = val.OnBulletFired; val.OnBulletFired = Action.op_Implicit((Action)delegate { if (__instance2.m_noiseTimer < Clock.Time) { NoiseTracker.TrackNextNoise(new NoiseInfo(((Item)__instance2).Owner)); } Action obj = previous; if (obj != null) { obj.Invoke(); } }); } [HarmonyPatch(typeof(InfectionSpitter), "Update")] [HarmonyPrefix] private static void SpitterExplodeNoise(InfectionSpitter __instance) { if (SNet.IsMaster && __instance.m_hasNode && __instance.m_isExploding && __instance.m_explodeProgression > 1.6f) { NoiseTracker.TrackNextNoise(new NoiseInfo()); } } [HarmonyPatch(typeof(LG_WeakDoor_Destruction), "TriggerExplosionEffect")] [HarmonyPrefix] private static void DoorBreakNoise(LG_WeakDoor_Destruction __instance) { if (SNet.IsMaster && !((Object)(object)__instance.m_destructionController == (Object)null)) { NoiseTracker.TrackNextNoise(new NoiseInfo()); } } internal static void OldBulkheadSound_Compatability(string OldBulkheadSoundGUID) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown rMetadata.OldBulkheadSound_Compatibility = true; if (((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue(OldBulkheadSoundGUID, out var _)) { APILogger.Warn("Replay mod is incompatible with DarkEmperor-OldBulkheadSound due to a patch to 'LG_SecurityDoor.OnDoorIsOpened'. This compatability layer disables that patch, possible causing incorrect alert blame."); return; } MethodInfo method = typeof(LG_SecurityDoor).GetMethod("OnDoorIsOpened"); if (method == null) { APILogger.Error("[OldBulkheadSound_Compatability] Failed to patch - Method 'LG_SecurityDoor.OnDoorIsOpened' was not found."); return; } rMetadata.OldBulkheadSound_Compatibility = false; Plugin.harmony.Patch((MethodBase)method, new HarmonyMethod(typeof(Noises).GetMethod("Prefix_SecurityDoor_OnDoorIsOpened", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void Prefix_SecurityDoor_OnDoorIsOpened(LG_SecurityDoor __instance) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster || __instance.LinkedToZoneData == null || __instance.LinkedToZoneData.EventsOnEnter == null) { return; } for (int i = 0; i < __instance.LinkedToZoneData.EventsOnEnter.Count; i++) { LevelEventData val = __instance.LinkedToZoneData.EventsOnEnter[i]; if (val.Noise.Enabled) { AIG_CourseNode courseNode = ((LG_ZoneExpander)__instance.Gate).GetOppositeArea(__instance.Gate.ProgressionSourceArea).m_courseNode; NoiseTracker.TrackNextDelayedNoise(((Component)__instance).transform.position, val.Noise.RadiusMin, val.Noise.RadiusMax, 1f, courseNode, (NM_NoiseType)0, includeToNeightbourAreas: true, raycastFirstNode: false, new NoiseInfo()); } } } } public class NoiseInfo { public PlayerAgent? source; public NoiseInfo() { } public NoiseInfo(PlayerAgent? source) { this.source = source; } } [HarmonyPatch] public static class NoiseTracker { private class NoiseEvent { public Vector3 position; public float radiusMin; public float radiusMax; public float yScale; public int courseNodeInstance; public NM_NoiseType type; public bool includeToNeightbourAreas; public bool raycastFirstNode; public NoiseInfo? info; public NoiseEvent(NM_NoiseData data, NoiseInfo? noise) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) position = data.position; radiusMin = data.radiusMin; radiusMax = data.radiusMax; yScale = data.yScale; courseNodeInstance = ((Object)data.node.gameObject).GetInstanceID(); type = data.type; includeToNeightbourAreas = data.includeToNeightbourAreas; raycastFirstNode = data.raycastFirstNode; info = noise; } public NoiseEvent(Vector3 position, float radiusMin, float radiusMax, float yScale, AIG_CourseNode courseNode, NM_NoiseType type, bool includeToNeightbourAreas, bool raycastFirstNode, NoiseInfo noise) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) this.position = position; this.radiusMin = radiusMin; this.radiusMax = radiusMax; this.yScale = yScale; courseNodeInstance = ((Object)courseNode.gameObject).GetInstanceID(); this.type = type; this.includeToNeightbourAreas = includeToNeightbourAreas; this.raycastFirstNode = raycastFirstNode; info = noise; } } [HarmonyPatch] private static class Patches { internal static List delayedNoiseEvents = new List(); private static List _delayedNoiseEvents = new List(); internal static Queue noises = new Queue(); internal static NoiseInfo? currentNoiseInfo = null; [ReplayInit] private static void Init() { NoiseManager.noiseDataToProcess.Clear(); delayedNoiseEvents.Clear(); _delayedNoiseEvents.Clear(); noises.Clear(); } [HarmonyPatch(typeof(NoiseManager), "ProcessNoise")] [HarmonyPrefix] private static void Prefix_ProcessNoise() { if (SNet.IsMaster) { if (NoiseManager.noiseDataToProcess.Count + 1 != noises.Count) { APILogger.Error("Noises are desynced for an unknown reason..."); noises.Clear(); } if (noises.Count > 0) { currentNoise = noises.Dequeue(); } else { currentNoise = null; } } } [HarmonyPatch(typeof(NoiseManager), "ProcessNoise")] [HarmonyPostfix] private static void Postfix_ProcessNoise() { if (SNet.IsMaster) { currentNoise = null; } } [HarmonyPatch(typeof(NoiseManager), "MakeNoise")] [HarmonyPostfix] private static void MakeNoise(NM_NoiseData noiseData) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster) { return; } NoiseEvent noiseEvent = null; _delayedNoiseEvents.Clear(); foreach (NoiseEvent delayedNoiseEvent in delayedNoiseEvents) { if (noiseEvent == null && delayedNoiseEvent.position == noiseData.position && delayedNoiseEvent.radiusMin == noiseData.radiusMin && delayedNoiseEvent.radiusMax == noiseData.radiusMax && delayedNoiseEvent.yScale == noiseData.yScale && delayedNoiseEvent.courseNodeInstance == ((Object)noiseData.node.gameObject).GetInstanceID() && delayedNoiseEvent.type == noiseData.type && delayedNoiseEvent.includeToNeightbourAreas == noiseData.includeToNeightbourAreas && delayedNoiseEvent.raycastFirstNode == noiseData.raycastFirstNode) { noiseEvent = delayedNoiseEvent; } else { _delayedNoiseEvents.Add(delayedNoiseEvent); } } List list = _delayedNoiseEvents; _delayedNoiseEvents = delayedNoiseEvents; delayedNoiseEvents = list; if (noiseEvent != null) { APILogger.Debug($"Matched sound to a delayed sec door event. {_delayedNoiseEvents.Count} -> {delayedNoiseEvents.Count}"); noises.Enqueue(noiseEvent.info); } else if (currentNoiseInfo == null) { noises.Enqueue(null); } } } private static NoiseInfo? currentNoise; public static NoiseInfo? CurrentNoise => currentNoise; public static void TrackNextNoise(NoiseInfo? info) { Patches.noises.Enqueue(info); Patches.currentNoiseInfo = info; } public static void TrackNextDelayedNoise(NM_NoiseData noiseData, NoiseInfo? info) { Patches.delayedNoiseEvents.Add(new NoiseEvent(noiseData, info)); } public static void TrackNextDelayedNoise(Vector3 position, float radiusMin, float radiusMax, float yScale, AIG_CourseNode courseNode, NM_NoiseType type, bool includeToNeightbourAreas, bool raycastFirstNode, NoiseInfo info) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Patches.delayedNoiseEvents.Add(new NoiseEvent(position, radiusMin, radiusMax, yScale, courseNode, type, includeToNeightbourAreas, raycastFirstNode, info)); } } } namespace Vanilla.BepInEx { public static class Module { public const string GUID = "randomuserhi.ReplayRecorder.Vanilla"; public const string Name = "ReplayRecorder.Vanilla"; public const string Version = "0.0.1"; } public static class ConfigManager { public static ConfigFile configFile; private static ConfigEntry debug; private static ConfigEntry recordEnemyRagdolls; private static ConfigEntry subdivideNavMesh; public static bool Debug { get { return debug.Value; } set { debug.Value = value; } } public static bool RecordEnemyRagdolls { get { return recordEnemyRagdolls.Value; } set { recordEnemyRagdolls.Value = value; } } public static bool SubdivideNavMesh { get { return subdivideNavMesh.Value; } set { subdivideNavMesh.Value = value; } } static ConfigManager() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "ReplayRecorder.Vanilla.cfg"), true); debug = configFile.Bind("Debug", "enable", false, "Enables debug messages when true."); recordEnemyRagdolls = configFile.Bind("Settings", "recordEnemyRagdolls", false, "Enables enemy ragdolls when true. Storing ragdoll information is very expensive and will increase replay file sizes. Preferably do not enable this, its mostly a for fun option."); subdivideNavMesh = configFile.Bind("Map", "subdivideNavMesh", true, "The navmesh is often inaccurate, by subdividing and sampling we can get a more accurate map but this may take levels to take longer to load."); } } [BepInPlugin("randomuserhi.ReplayRecorder.Vanilla", "ReplayRecorder.Vanilla", "0.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { private const string OldBulkheadSoundGUID = "OldBulkheadSound.GUID"; private const string ExtraWeaponCustomizationGUID = "Dinorush.ExtraWeaponCustomization"; internal static Harmony? harmony; public override void Load() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown APILogger.Log("Plugin is loaded!"); harmony = new Harmony("randomuserhi.ReplayRecorder.Vanilla"); harmony.PatchAll(); Replay.RegisterAll(); APILogger.Log("Debug is " + (ConfigManager.Debug ? "Enabled" : "Disabled")); Vanilla.Noises.Noises.OldBulkheadSound_Compatability("OldBulkheadSound.GUID"); } } } namespace Vanilla.Mines { public class MineManager { public static rMineDetonate? currentDetonateEvent; } internal struct MineTransform : IReplayTransform { private MineDeployerInstance mine; private MineDeployerInstance_Detect_Laser? laser; public bool active => (Object)(object)mine != (Object)null; public byte dimensionIndex => (byte)mine.CourseNode.m_dimension.DimensionIndex; public Vector3 position => ((Component)mine).transform.position; public Quaternion rotation { get { //IL_002f: 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_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)laser == (Object)null)) { return Quaternion.LookRotation(laser.m_lineRendererAlign.forward); } return ((Component)mine).transform.rotation; } } public MineTransform(MineDeployerInstance mine) { this.mine = mine; laser = ((Il2CppObjectBase)mine.m_detection).TryCast(); } } [HarmonyPatch] [ReplayData("Vanilla.Mine", "0.0.2")] public class rMine : DynamicTransform { [HarmonyPatch] private static class Patches { public static PlayerAgent? player; private static int? currentMineId; [HarmonyPatch(typeof(MineDeployerInstance), "OnSpawn")] [HarmonyPostfix] private static void Spawn(MineDeployerInstance __instance, pItemSpawnData spawnData) { //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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) SNet_Player val = default(SNet_Player); if (((pPlayer)(ref spawnData.owner)).TryGetPlayer(ref val)) { PlayerAgent obj = ((Il2CppObjectBase)val.PlayerAgent).Cast(); APILogger.Debug($"Mine Spawn ID - {spawnData.itemData.itemID_gearCRC}"); Identifier item = Identifier.From(spawnData.itemData); Replay.Spawn((ReplayDynamic)(object)new rMine(obj, __instance, item), true); } } [HarmonyPatch(typeof(MineDeployerInstance), "SyncedPickup")] [HarmonyPrefix] private static void SyncedPickup(MineDeployerInstance __instance) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(GetMineId(__instance)), true); } [HarmonyPatch(typeof(GenericDamageComponent), "BulletDamage")] [HarmonyPrefix] private static void Prefix_BulletDamage(float dam, Agent sourceAgent) { player = ((Il2CppObjectBase)sourceAgent).TryCast(); } [HarmonyPatch(typeof(GenericDamageComponent), "BulletDamage")] [HarmonyPostfix] private static void Postfix_BulletDamage() { player = null; } [HarmonyPatch(typeof(MineDeployerInstance), "SyncedTrigger")] [HarmonyPrefix] private static void Prefix_SyncedTrigger(MineDeployerInstance __instance) { if (SNet.IsMaster) { rMine rMine2 = Replay.Get(GetMineId(__instance)); SNet_Player val = default(SNet_Player); if ((Object)(object)player != (Object)null) { rMine2.shot = true; rMine2.trigger = player; } else if (SNetUtils.TryGetSender((SNet_Packet)(object)__instance.m_itemActionPacket, ref val)) { rMine2.shot = true; rMine2.trigger = ((Il2CppObjectBase)val.PlayerAgent).Cast(); } } } private static void DetonateMine(int mineId) { rMine rMine2 = Replay.Get(mineId); APILogger.Debug($"shot: {rMine2.shot}"); APILogger.Debug("trigger: " + rMine2.trigger.Owner.NickName); NoiseTracker.TrackNextNoise(new NoiseInfo(rMine2.trigger)); MineManager.currentDetonateEvent = new rMineDetonate(mineId, ((Agent)rMine2.trigger).GlobalID, rMine2.shot); Replay.Trigger((ReplayEvent)(object)MineManager.currentDetonateEvent); } [HarmonyPatch(typeof(MineDeployerInstance_Detonate_Explosive), "DoExplode")] [HarmonyPrefix] private static void Prefix_Detonate_Explosive(MineDeployerInstance_Detonate_Explosive __instance) { currentMineId = GetMineId(__instance); DetonateMine(currentMineId.Value); } [HarmonyPatch(typeof(MineDeployerInstance_Detonate_Explosive), "DoExplode")] [HarmonyPostfix] private static void Postfix_Detonate_Explosive(MineDeployerInstance_Detonate_Explosive __instance) { MineManager.currentDetonateEvent = null; if (currentMineId.HasValue) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(currentMineId.Value), true); } currentMineId = null; } [HarmonyPatch(typeof(MineDeployerInstance_Detonate_Glue), "DoExplode")] [HarmonyPrefix] private static void Prefix_Detonate_Glue(MineDeployerInstance_Detonate_Explosive __instance) { currentMineId = GetMineId(__instance); } [HarmonyPatch(typeof(MineDeployerInstance_Detonate_Glue), "DoExplode")] [HarmonyPostfix] private static void Postfix_Detonate_Glue(MineDeployerInstance_Detonate_Explosive __instance) { MineManager.currentDetonateEvent = null; if (currentMineId.HasValue) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(currentMineId.Value), true); } currentMineId = null; } } public bool shot; public PlayerAgent trigger; public PlayerAgent owner; private MineDeployerInstance_Detect_Laser? laser; public MineDeployerInstance instance; private float oldLength; private Identifier item = Identifier.unknown; public override bool IsDirty { get { if (!((DynamicTransform)this).IsDirty) { return length != oldLength; } return true; } } private float length { get { if (!((Object)(object)laser == (Object)null)) { return laser.DetectionRange; } return 0f; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetMineId(MineDeployerInstance instance) { return instance.Replicator.Key; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetMineId(MineDeployerInstance_Detonate_Explosive instance) { return GetMineId(((Component)instance).GetComponent()); } public rMine(PlayerAgent player, MineDeployerInstance mine, Identifier item) : base(GetMineId(mine), (IReplayTransform)(object)new MineTransform(mine)) { instance = mine; laser = ((Il2CppObjectBase)mine.m_detection).TryCast(); this.item = item; owner = player; trigger = player; } public override void Write(ByteBuffer buffer) { ((DynamicTransform)this).Write(buffer); BitHelper.WriteHalf(length, buffer); oldLength = length; } public override void Spawn(ByteBuffer buffer) { ((DynamicTransform)this).Spawn(buffer); BitHelper.WriteBytes((BufferWriteable)(object)item, buffer); BitHelper.WriteBytes(((Agent)owner).GlobalID, buffer); } } [ReplayData("Vanilla.Mine.Detonate", "0.0.1")] public class rMineDetonate : Id { private ushort trigger; private bool shot; public rMineDetonate(int mineId, ushort trigger, bool shot = false) : base(mineId) { this.trigger = trigger; this.shot = shot; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(trigger, buffer); BitHelper.WriteBytes(shot, buffer); } } } namespace Vanilla.Map { internal class Surface { public Mesh? mesh; public Surface(Mesh mesh) { this.mesh = mesh; } } public static class MapUtils { public static Dictionary lowestPoint { get; internal set; } = new Dictionary(); } [HarmonyPatch] internal static class MapGeometryReplayManager { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(LG_SetupFloor), "Build")] [HarmonyPostfix] private static void OnSetupFloor(LG_SetupFloor __instance) { dimensions = __instance.m_floor.m_dimensions; dimensionsLoaded = 0; } [HarmonyPatch(typeof(LG_BuildUnityGraphJob), "Build")] [HarmonyPostfix] private static void OnNavmeshDone(LG_BuildUnityGraphJob __instance) { if (__instance.m_dimension.NavmeshOperation.isDone) { dimensionsLoaded++; } } } private static int dimensionsLoaded = 0; private static List? dimensions; private static HashSet processed = new HashSet(); [ReplayInit] private static void Init() { processed.Clear(); dimensions = null; dimensionsLoaded = 0; MapUtils.lowestPoint.Clear(); } private static int GetNewVertex(Dictionary newVectices, List vertices, int i1, int i2, float min, float max) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (i1 > 65535) { throw new Exception("Only supports 16 bit indices."); } if (i2 > 65535) { throw new Exception("Only supports 16 bit indices."); } uint key = (uint)((i1 << 16) | i2); uint key2 = (uint)((i2 << 16) | i1); if (newVectices.ContainsKey(key2)) { return newVectices[key2]; } if (newVectices.ContainsKey(key)) { return newVectices[key]; } int count = vertices.Count; newVectices.Add(key, count); Vector3 val = (vertices[i1] + vertices[i2]) * 0.5f; NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(val, ref val2, 3f, 1)) { val = ((NavMeshHit)(ref val2)).position; } vertices.Add(val); return count; } private static (Vector3[], int[]) Subdivide(Mesh mesh) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) Dictionary newVectices = new Dictionary(); List list = new List((IEnumerable)mesh.vertices); List list2 = new List(); for (int i = 0; i < ((Il2CppArrayBase)(object)mesh.triangles).Length; i += 3) { int num = ((Il2CppArrayBase)(object)mesh.triangles)[i]; int num2 = ((Il2CppArrayBase)(object)mesh.triangles)[i + 1]; int num3 = ((Il2CppArrayBase)(object)mesh.triangles)[i + 2]; float min = Mathf.Min(new float[3] { list[num].y, list[num2].y, list[num3].y }); float max = Mathf.Max(new float[3] { list[num].y, list[num2].y, list[num3].y }); int newVertex = GetNewVertex(newVectices, list, num, num2, min, max); int newVertex2 = GetNewVertex(newVectices, list, num2, num3, min, max); int newVertex3 = GetNewVertex(newVectices, list, num3, num, min, max); list2.Add(num); list2.Add(newVertex); list2.Add(newVertex3); list2.Add(num2); list2.Add(newVertex2); list2.Add(newVertex); list2.Add(num3); list2.Add(newVertex3); list2.Add(newVertex2); list2.Add(newVertex); list2.Add(newVertex2); list2.Add(newVertex3); } return (list.ToArray(), list2.ToArray()); } private static void GenerateMeshSurfaces(Dimension dimension) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_06dc: Unknown result type (might be due to invalid IL or missing references) //IL_06e1: Unknown result type (might be due to invalid IL or missing references) //IL_06e5: Unknown result type (might be due to invalid IL or missing references) //IL_06f6: Unknown result type (might be due to invalid IL or missing references) //IL_06fb: Unknown result type (might be due to invalid IL or missing references) //IL_06ff: Unknown result type (might be due to invalid IL or missing references) //IL_0719: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_0731: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) Dimension dimension2 = dimension; NavMeshTriangulation obj = NavMesh.CalculateTriangulation(); APILogger.Debug("Merging nearby vertices..."); Vector3[] vertices = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)obj.vertices); int[] indices = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)obj.indices); (vertices, indices) = MeshUtils.Weld(vertices, indices, 0.25f, 2f); APILogger.Debug("Splitting navmesh..."); MeshUtils.Surface[] array = MeshUtils.SplitNavmesh(vertices, indices); APILogger.Debug($"Generated {array.Length} surfaces. Converting to meshes..."); if (processed.Contains(dimension2.DimensionIndex)) { APILogger.Error("Dimension already has been constructed, this should not happen"); return; } processed.Add(dimension2.DimensionIndex); Mesh[] array2 = (Mesh[])(object)new Mesh[array.Length]; for (int i = 0; i < array.Length; i++) { array2[i] = array[i].ToMesh(); array2[i].RecalculateBounds(); } long now = Raudy.Now; array2 = array2.Where((Mesh s) => MeshUtils.GetSurfaceArea(s) > 5f && MeshUtils.InvalidPercentage(s, dimension2.DimensionIndex, 0.2f)).ToArray(); long now2 = Raudy.Now; APILogger.Warn($"Culled surfaces in {(float)(now2 - now) / 1000f} seconds."); Surface[] array3; if (array2.Length > 1) { APILogger.Debug("Getting relevant surfaces."); long now3 = Raudy.Now; Dictionary dictionary = new Dictionary(); for (int j = 0; j < dimension2.Layers.Count; j++) { LG_Layer val = dimension2.Layers[j]; for (int k = 0; k < val.m_zones.Count; k++) { LG_Zone val2 = val.m_zones[k]; for (int l = 0; l < val2.m_areas.Count; l++) { LG_Area area = val2.m_areas[l]; for (int n = 0; n < area.m_gates.Count; n++) { LG_Gate val3 = area.m_gates[n]; Vector3 gateLocation = ((Component)val3).transform.position; int num = 0; foreach (Mesh item in array2.Where(delegate(Mesh m) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0068: Unknown result type (might be due to invalid IL or missing references) double num8 = gateLocation.y; Bounds bounds6 = m.bounds; float y2 = ((Bounds)(ref bounds6)).center.y; bounds6 = m.bounds; if (num8 >= (double)(y2 - ((Bounds)(ref bounds6)).extents.y) - 0.1) { double num9 = gateLocation.y; bounds6 = m.bounds; float y3 = ((Bounds)(ref bounds6)).center.y; bounds6 = m.bounds; return num9 <= (double)(y3 + ((Bounds)(ref bounds6)).extents.y) + 0.1; } return false; }).OrderBy(delegate(Mesh m) { //IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val11 = gateLocation; Bounds bounds5 = m.bounds; Vector3 val12 = val11 - ((Bounds)(ref bounds5)).ClosestPoint(gateLocation); return ((Vector3)(ref val12)).sqrMagnitude; })) { if (++num > 3) { break; } if (!dictionary.ContainsKey(item)) { dictionary.Add(item, new Surface(item)); } } } for (int num2 = 0; num2 < ((Il2CppArrayBase)(object)area.m_courseNode.m_laddersInNode).Count; num2++) { LG_Ladder val4 = ((Il2CppArrayBase)(object)area.m_courseNode.m_laddersInNode)[num2]; if (val4.m_enemyClimbingOnly) { continue; } Vector3 val5 = ((Component)val4).transform.forward * 0.1f; Vector3 bottom = ((Component)val4).transform.position + val5; Vector3 top = bottom + ((Component)val4).transform.up * ((Component)val4.m_topFloor).transform.localPosition.y; int num3 = 0; foreach (Mesh item2 in array2.OrderBy(delegate(Mesh m) { //IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val9 = top; Bounds bounds4 = m.bounds; Vector3 val10 = val9 - ((Bounds)(ref bounds4)).ClosestPoint(top); return ((Vector3)(ref val10)).sqrMagnitude; })) { if (++num3 > 2) { break; } if (!dictionary.ContainsKey(item2)) { dictionary.Add(item2, new Surface(item2)); } } num3 = 0; foreach (Mesh item3 in array2.OrderBy(delegate(Mesh m) { //IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val7 = bottom; Bounds bounds3 = m.bounds; Vector3 val8 = val7 - ((Bounds)(ref bounds3)).ClosestPoint(bottom); return ((Vector3)(ref val8)).sqrMagnitude; })) { if (++num3 > 2) { break; } if (!dictionary.ContainsKey(item3)) { dictionary.Add(item3, new Surface(item3)); } } } int num4 = 0; foreach (Mesh item4 in array2.OrderBy(delegate(Mesh m) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) Vector3 position = area.Position; Bounds bounds2 = m.bounds; Vector3 val6 = position - ((Bounds)(ref bounds2)).ClosestPoint(area.Position); return ((Vector3)(ref val6)).sqrMagnitude; })) { if (++num4 > 2) { break; } if (!dictionary.ContainsKey(item4)) { dictionary.Add(item4, new Surface(item4)); } } } } } long now4 = Raudy.Now; array3 = dictionary.Values.ToArray(); APILogger.Warn($"Found {array3.Length} relevant surfaces in {(float)(now4 - now3) / 1000f} seconds."); } else { array3 = new Surface[array2.Length]; for (int num5 = 0; num5 < array2.Length; num5++) { array3[num5] = new Surface(array2[num5]); } } if (array3.Length == 0) { APILogger.Warn("No relevent surfaces found"); return; } if (!MapUtils.lowestPoint.ContainsKey((byte)dimension2.DimensionIndex)) { MapUtils.lowestPoint.Add((byte)dimension2.DimensionIndex, float.PositiveInfinity); } if (ConfigManager.SubdivideNavMesh) { APILogger.Warn("Subdividing meshes (Shouldn't take longer than a minute - If it takes too long, you can disable subdivision in config):"); now = Raudy.Now; } for (int num6 = 0; num6 < array3.Length; num6++) { Surface surface = array3[num6]; if (ConfigManager.SubdivideNavMesh) { (vertices, indices) = Subdivide(surface.mesh); surface.mesh.Clear(); surface.mesh.vertices = Il2CppStructArray.op_Implicit(vertices); surface.mesh.triangles = Il2CppStructArray.op_Implicit(indices); surface.mesh.RecalculateBounds(); } Bounds bounds = surface.mesh.bounds; float y = ((Bounds)(ref bounds)).center.y; bounds = surface.mesh.bounds; float num7 = y - ((Bounds)(ref bounds)).extents.y; if (num7 < MapUtils.lowestPoint[(byte)dimension2.DimensionIndex]) { MapUtils.lowestPoint[(byte)dimension2.DimensionIndex] = num7; } Replay.Trigger((ReplayHeader)(object)new rMapGeometry((byte)dimension2.DimensionIndex, surface)); array3[num6].mesh = null; GC.Collect(); } if (ConfigManager.SubdivideNavMesh) { now2 = Raudy.Now; APILogger.Warn($"Subdivided surfaces in {(float)(now2 - now) / 1000f} seconds."); } } [ReplayOnElevatorStop] private static void GenerateMapInfo() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (dimensions == null) { APILogger.Error("No dimensions found, this should not happen."); return; } if (dimensionsLoaded != dimensions.Count) { APILogger.Error("Elevator has stopped, but not all dimensions have been loaded?"); } APILogger.Debug("Generating map navmesh..."); for (int i = 0; i < dimensions.Count; i++) { NavMesh.RemoveAllNavMeshData(); NavMesh.AddNavMeshData(dimensions[i].NavmeshData); GenerateMeshSurfaces(dimensions[i]); } APILogger.Debug("Re-constructing navmesh..."); NavMesh.RemoveAllNavMeshData(); for (int j = 0; j < dimensions.Count; j++) { dimensions[j].NavmeshInstance = NavMesh.AddNavMeshData(dimensions[j].NavmeshData); } } } [ReplayData("Vanilla.Map.Geometry", "0.0.1")] internal class rMapGeometry : ReplayHeader { private byte dimension; private Surface surface; public rMapGeometry(byte dimension, Surface surface) { this.dimension = dimension; this.surface = surface; } public override void Write(ByteBuffer buffer) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)surface.mesh == (Object)null) { throw new NullReferenceException("Mesh was null."); } BitHelper.WriteBytes(dimension, buffer); Vector3[] array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)surface.mesh.vertices); int[] array2 = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)surface.mesh.triangles); if (array.Length > 65535) { APILogger.Error($"There were more than {65535} vertices"); return; } BitHelper.WriteBytes((ushort)array.Length, buffer); BitHelper.WriteBytes((uint)array2.Length, buffer); for (int i = 0; i < array.Length; i++) { BitHelper.WriteBytes(array[i], buffer); } for (int j = 0; j < array2.Length; j++) { BitHelper.WriteBytes((ushort)array2[j], buffer); } } } [ReplayData("Vanilla.Map.Geometry.EOH", "0.0.1")] internal class rMapGeometryEOH : ReplayHeader { [ReplayOnElevatorStop] private static void Trigger() { Replay.Trigger((ReplayHeader)(object)new rMapGeometryEOH()); } public override void Write(ByteBuffer buffer) { } } internal static class MeshUtils { public class Surface { public List vertices = new List(); public List indices = new List(); public Mesh ToMesh() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown return new Mesh { vertices = Il2CppStructArray.op_Implicit(vertices.ToArray()), triangles = Il2CppStructArray.op_Implicit(indices.ToArray()) }; } } private class DisJointSet { private int[] parents; private int[] ranks; public DisJointSet(int size) { ranks = new int[size]; parents = new int[size]; for (int i = 0; i < size; i++) { parents[i] = i; } } public int Root(int i) { while (i != parents[i]) { i = parents[i]; } return i; } public void Union(int a, int b) { int num = Root(a); int num2 = Root(b); if (num == num2) { return; } if (ranks[num] > ranks[num2]) { parents[num2] = num; return; } parents[num] = num2; if (ranks[num] == ranks[num2]) { ranks[num2]++; } } } public static float GetSurfaceArea(Mesh mesh) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_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) Il2CppStructArray triangles = mesh.triangles; Il2CppStructArray vertices = mesh.vertices; double num = 0.0; for (int i = 0; i < ((Il2CppArrayBase)(object)triangles).Length; i += 3) { Vector3 val = ((Il2CppArrayBase)(object)vertices)[((Il2CppArrayBase)(object)triangles)[i]]; Vector3 val2 = ((Il2CppArrayBase)(object)vertices)[((Il2CppArrayBase)(object)triangles)[i + 1]] - val; Vector3 val3 = ((Il2CppArrayBase)(object)vertices)[((Il2CppArrayBase)(object)triangles)[i + 2]] - val; double num2 = num; Vector3 val4 = Vector3.Cross(val2, val3); num = num2 + (double)((Vector3)(ref val4)).magnitude; } return (float)(num / 2.0); } public static Surface[] SplitNavmesh(Vector3[] vertices, int[] indices) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) DisJointSet disJointSet = new DisJointSet(vertices.Length); int num = 0; while (num < indices.Length) { int a = indices[num++]; int b = indices[num++]; int b2 = indices[num++]; disJointSet.Union(a, b); disJointSet.Union(a, b2); } Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); for (int i = 0; i < vertices.Length; i++) { int key = disJointSet.Root(i); if (!dictionary2.ContainsKey(key)) { dictionary2.Add(key, new Surface()); } Surface surface = dictionary2[key]; dictionary.Add(i, surface.vertices.Count); surface.vertices.Add(vertices[i]); } for (int j = 0; j < indices.Length; j++) { int key2 = disJointSet.Root(indices[j]); dictionary2[key2].indices.Add(dictionary[indices[j]]); } return dictionary2.Values.ToArray(); } private static Vector3 ClosestPoint(Vector3 point, Vector3 line1, Vector3 line2) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Vector3 val = line2 - line1; float num = Vector3.Dot(point - line1, val) / Vector3.Dot(val, val); if (num < 0f) { return line1; } if (num > 1f) { return line2; } return line1 + val * num; } private static Vector3 EstimateClosestPoint(Vector3 point, Vector3 tri1, Vector3 tri2, Vector3 tri3) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.Cross(tri2 - tri1, tri3 - tri1); point -= Vector3.Dot(val, point - tri1) * val; Vector3 val2 = ClosestPoint(point, tri1, tri2); Vector3 val3 = ClosestPoint(point, tri2, tri3); Vector3 val4 = ClosestPoint(point, tri3, tri1); Vector3 val5 = point - val2; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; val5 = point - val3; float sqrMagnitude2 = ((Vector3)(ref val5)).sqrMagnitude; val5 = point - val4; float sqrMagnitude3 = ((Vector3)(ref val5)).sqrMagnitude; float num = Mathf.Min(sqrMagnitude, sqrMagnitude2); num = Mathf.Min(num, sqrMagnitude3); if (num == sqrMagnitude) { return val2; } if (num == sqrMagnitude2) { return val3; } return val4; } public static Mesh[] GetNearbyMeshes(Vector3 point, float radius, Mesh[] meshes) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_00ed: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (Mesh val in meshes) { Bounds bounds = val.bounds; Vector3 min = ((Bounds)(ref bounds)).min; bounds = val.bounds; Vector3 max = ((Bounds)(ref bounds)).max; float num = radius * radius; if (point.x < min.x) { num -= (point.x - min.x) * (point.x - min.x); } else if (point.x > max.x) { num -= (point.x - max.x) * (point.x - max.x); } if (point.y < min.y) { num -= (point.y - min.y) * (point.y - min.y); } else if (point.y > max.y) { num -= (point.y - max.y) * (point.y - max.y); } if (point.z < min.z) { num -= (point.z - min.z) * (point.z - min.z); } else if (point.z > max.z) { num -= (point.z - max.z) * (point.z - max.z); } if (num > 0f) { list.Add(val); } } return list.ToArray(); } public static Vector3 EstimateClosestPoint(Vector3 point, Mesh mesh) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0045: 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_0062: 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_006b: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Vector3 result = Vector3.zero; float num = float.MaxValue; int num2 = 0; while (num2 < ((Il2CppArrayBase)(object)mesh.triangles).Length) { Vector3 tri = ((Il2CppArrayBase)(object)mesh.vertices)[((Il2CppArrayBase)(object)mesh.triangles)[num2++]]; Vector3 tri2 = ((Il2CppArrayBase)(object)mesh.vertices)[((Il2CppArrayBase)(object)mesh.triangles)[num2++]]; Vector3 tri3 = ((Il2CppArrayBase)(object)mesh.vertices)[((Il2CppArrayBase)(object)mesh.triangles)[num2++]]; Vector3 val = EstimateClosestPoint(point, tri, tri2, tri3); Vector3 val2 = val - point; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } return result; } public static int[] ClearInaccessibleTriangles(eDimensionIndex dimensionIndex, Vector3[] triangles, int[] indices) { //IL_001d: 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_0029: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i < indices.Length; i += 3) { int num = indices[i]; int num2 = indices[i + 1]; int num3 = indices[i + 2]; Vector3 p = triangles[num]; Vector3 p2 = triangles[num2]; Vector3 p3 = triangles[num3]; CalcTriangleProps(p, p2, p3, out var center, out var heightDifference); float voxelSearchTolerance = Mathf.Max(2f, heightDifference * 2f); if (IsPositionValid(dimensionIndex, center, voxelSearchTolerance)) { list.Add(num); list.Add(num2); list.Add(num3); } } return list.ToArray(); } public static bool InvalidPercentage(Mesh mesh, eDimensionIndex dimensionIndex, float threshold) { //IL_004c: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) Il2CppStructArray triangles = mesh.triangles; Il2CppStructArray vertices = mesh.vertices; float num = 0f; float num2 = 3f / (float)((Il2CppArrayBase)(object)triangles).Length; for (int i = 0; i < ((Il2CppArrayBase)(object)triangles).Length; i += 3) { int num3 = ((Il2CppArrayBase)(object)triangles)[i]; int num4 = ((Il2CppArrayBase)(object)triangles)[i + 1]; int num5 = ((Il2CppArrayBase)(object)triangles)[i + 2]; Vector3 p = ((Il2CppArrayBase)(object)vertices)[num3]; Vector3 p2 = ((Il2CppArrayBase)(object)vertices)[num4]; Vector3 p3 = ((Il2CppArrayBase)(object)vertices)[num5]; CalcTriangleProps(p, p2, p3, out var center, out var heightDifference); float voxelSearchTolerance = Mathf.Max(2f, heightDifference * 2f); if (IsPositionValid(dimensionIndex, center, voxelSearchTolerance)) { num += num2; } if (num >= threshold) { return true; } } return num >= threshold; } public static void CalcTriangleProps(Vector3 p1, Vector3 p2, Vector3 p3, out Vector3 center, out float heightDifference) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) center = (p1 + p2 + p3) * 0.333333f; float num = Mathf.Min(new float[3] { p1.y, p2.y, p3.y }); float num2 = Mathf.Max(new float[3] { p1.y, p2.y, p3.y }); heightDifference = num2 - num; } private static bool IsPositionValid(eDimensionIndex dimensionIndex, Vector3 position, float voxelSearchTolerance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) AIG_GeomorphNodeVolume val = default(AIG_GeomorphNodeVolume); if (!AIG_GeomorphNodeVolume.TryGetGeomorphVolume(0, dimensionIndex, position, ref val)) { return false; } AIG_VoxelNodePillar val2 = default(AIG_VoxelNodePillar); if (!((AIG_NodeVolume)val).m_voxelNodeVolume.TryGetPillar(position, ref val2)) { return false; } float y = position.y; AIG_INode val3 = default(AIG_INode); if (!val2.TryGetVoxelNode(y - voxelSearchTolerance, y + voxelSearchTolerance, ref val3)) { return false; } AIG_NodeCluster val4 = default(AIG_NodeCluster); if (!AIG_NodeCluster.TryGetNodeCluster(val3.ClusterID, ref val4)) { return false; } return true; } public static (Vector3[], int[]) Weld(Vector3[] vertices, int[] indices, float threshold, float bucketStep = 1.3f) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) threshold *= threshold; List list = new List(); int[] array = new int[vertices.Length]; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(float.MinValue, float.MinValue, float.MinValue); for (int i = 0; i < vertices.Length; i++) { if (vertices[i].x < val.x) { val.x = vertices[i].x; } if (vertices[i].y < val.y) { val.y = vertices[i].y; } if (vertices[i].z < val.z) { val.z = vertices[i].z; } if (vertices[i].x > val2.x) { val2.x = vertices[i].x; } if (vertices[i].y > val2.y) { val2.y = vertices[i].y; } if (vertices[i].z > val2.z) { val2.z = vertices[i].z; } } int num = Mathf.FloorToInt((val2.x - val.x) / bucketStep) + 1; int num2 = Mathf.FloorToInt((val2.y - val.y) / bucketStep) + 1; int num3 = Mathf.FloorToInt((val2.z - val.z) / bucketStep) + 1; List[,,] array2 = new List[num, num2, num3]; for (int j = 0; j < vertices.Length; j++) { int num4 = Mathf.FloorToInt((vertices[j].x - val.x) / bucketStep); int num5 = Mathf.FloorToInt((vertices[j].y - val.y) / bucketStep); int num6 = Mathf.FloorToInt((vertices[j].z - val.z) / bucketStep); if (array2[num4, num5, num6] == null) { array2[num4, num5, num6] = new List(); } int num7 = 0; while (true) { if (num7 < array2[num4, num5, num6].Count) { Vector3 val3 = list[array2[num4, num5, num6][num7]] - vertices[j]; if (((Vector3)(ref val3)).sqrMagnitude < threshold) { array[j] = array2[num4, num5, num6][num7]; break; } num7++; continue; } array[j] = list.Count; array2[num4, num5, num6].Add(list.Count); list.Add(vertices[j]); break; } } List list2 = new List(); for (int k = 0; k < indices.Length; k += 3) { int num8 = array[indices[k]]; int num9 = array[indices[k + 1]]; int num10 = array[indices[k + 2]]; if (num8 != num9 && num8 != num10 && num9 != num10) { list2.Add(num8); list2.Add(num9); list2.Add(num10); } } return (list.ToArray(), list2.ToArray()); } } } namespace Vanilla.Metadata { [ReplayData("Vanilla.Metadata", "0.0.4")] internal class rMetadata : ReplayHeader { private const string Version = "0.1.8"; public static bool OldBulkheadSound_Compatibility; public static bool NoArtifact_Compatibility; [ReplayInit] private static void Init() { Replay.Trigger((ReplayHeader)(object)new rMetadata()); } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes("0.1.8", buffer); BitHelper.WriteBytes(OldBulkheadSound_Compatibility, buffer); BitHelper.WriteBytes(NoArtifact_Compatibility, buffer); BitHelper.WriteBytes(ConfigManager.RecordEnemyRagdolls, buffer); } } } namespace Vanilla.Events { [ReplayData("Vanilla.Checkpoint", "0.0.1")] [HarmonyPatch] public class rCheckpoint : ReplayEvent { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(CheckpointManager), "OnStateChange")] [HarmonyPrefix] private static void Prefix_CheckpointStateChange(pCheckpointState oldState, pCheckpointState newState, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (oldState.isReloadingCheckpoint && isRecall && !SNet.MasterManagement.IsMigrating) { Replay.Trigger((ReplayEvent)(object)new rCheckpoint()); } } } } [HarmonyPatch] [ReplayData("Vanilla.Player.Gunshots", "0.0.2")] public class rGunshot : Id { [HarmonyPatch] private static class Patches { private static bool glueShot = false; private static PlayerAgent? owner = null; private static float damage = 0f; private static bool silent = false; private static bool sentry = false; private static bool autoTrack = true; [HarmonyPatch(typeof(GlueGun), "FireSingle")] [HarmonyPrefix] private static void Prefix_GlueGunFireSingle() { glueShot = true; } [HarmonyPatch(typeof(GlueGun), "FireSingle")] [HarmonyPostfix] private static void Postfix_GlueGunFireSingle() { glueShot = false; } [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")] [HarmonyPrefix] private static void Prefix_SentryGunFire(SentryGunInstance_Firing_Bullets __instance, bool doDamage, bool targetIsTagged) { damage = __instance.m_archetypeData.GetSentryDamage(__instance.m_core.Owner, 0.01f, targetIsTagged); owner = __instance.m_core.Owner; sentry = true; } [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "FireBullet")] [HarmonyPostfix] private static void Postfix_SentryGunFire() { damage = 0f; owner = null; sentry = false; } [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")] [HarmonyPrefix] private static void Prefix_SentryShotgunFire(SentryGunInstance_Firing_Bullets __instance, bool isMaster, bool targetIsTagged) { damage = __instance.m_archetypeData.GetSentryDamage(__instance.m_core.Owner, 0.01f, targetIsTagged); owner = __instance.m_core.Owner; sentry = true; } [HarmonyPatch(typeof(SentryGunInstance_Firing_Bullets), "UpdateFireShotgunSemi")] [HarmonyPostfix] private static void Postfix_SentryShotgunFire() { damage = 0f; owner = null; sentry = false; } [HarmonyPatch(typeof(PlayerInventorySynced), "GetSync")] [HarmonyPrefix] private static void Prefix_ShotSync(PlayerInventorySynced __instance) { if (!SNet.IsMaster || ((Agent)((PlayerInventoryBase)__instance).Owner).IsLocallyOwned || ((PlayerInventoryBase)__instance).Owner.Owner.IsBot || !((Object)(object)((Il2CppObjectBase)((PlayerInventoryBase)__instance).m_wieldedItem).TryCast() == (Object)null) || !((Object)(object)__instance.m_queuedEquipItem != (Object)null)) { return; } silent = true; ItemEquippable queuedEquipItem = __instance.m_queuedEquipItem; ShotgunSynced val = ((Il2CppObjectBase)queuedEquipItem).TryCast(); if ((Object)(object)val != (Object)null) { _Prefix_ShotgunSyncFire(val); _Postfix_ShotgunSyncFire(); } else { BulletWeaponSynced val2 = ((Il2CppObjectBase)queuedEquipItem).TryCast(); if ((Object)(object)val2 != (Object)null) { _Prefix_BulletWeaponSyncFire(val2); _Postfix_BulletWeaponSyncFire(); } } silent = false; } [HarmonyPatch(typeof(BulletWeapon), "Fire")] [HarmonyPrefix] private static void Prefix_BulletWeaponFire(BulletWeapon __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) damage = ((ItemEquippable)__instance).ArchetypeData.GetDamageWithBoosterEffect(((Item)__instance).Owner, ((Item)__instance).ItemDataBlock.inventorySlot); owner = ((Item)__instance).Owner; } [HarmonyPatch(typeof(BulletWeapon), "Fire")] [HarmonyPostfix] private static void Postfix_BulletWeaponFire(BulletWeapon __instance) { damage = 0f; owner = null; } [HarmonyPatch(typeof(Shotgun), "Fire")] [HarmonyPrefix] private static void Prefix_ShotgunFire(Shotgun __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) damage = ((ItemEquippable)__instance).ArchetypeData.GetDamageWithBoosterEffect(((Item)__instance).Owner, ((Item)__instance).ItemDataBlock.inventorySlot); owner = ((Item)__instance).Owner; } [HarmonyPatch(typeof(Shotgun), "Fire")] [HarmonyPostfix] private static void Postfix_ShotgunFire() { damage = 0f; owner = null; } [HarmonyPatch(typeof(BulletWeaponSynced), "Fire")] [HarmonyPrefix] private static void Prefix_BulletWeaponSyncFire(BulletWeaponSynced __instance) { _Prefix_BulletWeaponSyncFire(__instance); } private static void _Prefix_BulletWeaponSyncFire(BulletWeaponSynced __instance) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) autoTrack = false; if (CancelSyncedShot((BulletWeapon)(object)__instance)) { return; } damage = ((ItemEquippable)__instance).ArchetypeData.GetDamageWithBoosterEffect(((Item)__instance).Owner, ((Item)__instance).ItemDataBlock.inventorySlot); owner = ((Item)__instance).Owner; _ = ((ItemEquippable)__instance).MuzzleAlign; Vector3 targetLookDir = ((Agent)((Item)__instance).Owner).TargetLookDir; Vector3 val = ((Item)__instance).Owner.AnimatorBody.GetBoneTransform((HumanBodyBones)10).position; float num = ((Weapon)__instance).MaxRayDist; RaycastHit val4 = default(RaycastHit); if (((ItemEquippable)__instance).ArchetypeData.PiercingBullets) { int num2 = 5; int num3 = 0; bool flag = false; float num4 = 0f; int num5 = 0; RaycastHit val2 = default(RaycastHit); while (!flag && num3 < num2 && num > 0f && num5 < ((ItemEquippable)__instance).ArchetypeData.PiercingDamageCountLimit) { if (Physics.Raycast(val, targetLookDir, ref val2, num, LayerManager.MASK_BULLETWEAPON_RAY)) { GameObject gameObject = ((Component)((RaycastHit)(ref val2)).collider).gameObject; IDamageable val3 = null; ColliderMaterial component = gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { val3 = component.Damageable; } if (val3 == null) { val3 = gameObject.GetComponent(); } if (val3 != null) { num5++; } Replay.Trigger((ReplayEvent)(object)new rGunshot(owner, damage, val, ((RaycastHit)(ref val2)).point, sentry, silent)); flag = !CustomExtensions.IsInLayerMask(((Component)((RaycastHit)(ref val2)).collider).gameObject, LayerMask.op_Implicit(LayerManager.MASK_BULLETWEAPON_PIERCING_PASS)); val = ((RaycastHit)(ref val2)).point + targetLookDir * 0.1f; num4 += ((RaycastHit)(ref val2)).distance; num -= ((RaycastHit)(ref val2)).distance; } else { flag = true; } num3++; } } else if (Physics.Raycast(val, targetLookDir, ref val4, num, LayerManager.MASK_BULLETWEAPON_RAY)) { Replay.Trigger((ReplayEvent)(object)new rGunshot(owner, damage, val, ((RaycastHit)(ref val4)).point, sentry, silent)); } } [HarmonyPatch(typeof(BulletWeaponSynced), "Fire")] [HarmonyPostfix] private static void Postfix_BulletWeaponSyncFire() { _Postfix_BulletWeaponSyncFire(); } private static void _Postfix_BulletWeaponSyncFire() { damage = 0f; autoTrack = true; owner = null; } [HarmonyPatch(typeof(ShotgunSynced), "Fire")] [HarmonyPrefix] private static void Prefix_ShotgunSyncFire(ShotgunSynced __instance) { _Prefix_ShotgunSyncFire(__instance); } private static void _Prefix_ShotgunSyncFire(ShotgunSynced __instance) { //IL_0021: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) autoTrack = false; if (CancelSyncedShot((BulletWeapon)(object)__instance)) { return; } damage = ((ItemEquippable)__instance).ArchetypeData.GetDamageWithBoosterEffect(((Item)__instance).Owner, ((Item)__instance).ItemDataBlock.inventorySlot); owner = ((Item)__instance).Owner; Transform muzzleAlign = ((ItemEquippable)__instance).MuzzleAlign; RaycastHit val4 = default(RaycastHit); RaycastHit val6 = default(RaycastHit); for (int i = 0; i < ((ItemEquippable)__instance).ArchetypeData.ShotgunBulletCount; i++) { Vector3 val = ((Item)__instance).Owner.AnimatorBody.GetBoneTransform((HumanBodyBones)10).position; float num = __instance.m_segmentSize * (float)i; float num2 = 0f; float num3 = 0f; if (i > 0) { num2 += (float)((ItemEquippable)__instance).ArchetypeData.ShotgunConeSize * Mathf.Cos(num); num3 += (float)((ItemEquippable)__instance).ArchetypeData.ShotgunConeSize * Mathf.Sin(num); } float num4 = ((ItemEquippable)__instance).ArchetypeData.ShotgunBulletSpread; Vector3 val2 = ((Agent)((Item)__instance).Owner).TargetLookDir; float num5 = ((Weapon)__instance).MaxRayDist; Vector3 up = muzzleAlign.up; Vector3 right = muzzleAlign.right; if (Mathf.Abs(num2) > 0f) { val2 = Quaternion.AngleAxis(num2, up) * val2; } if (Mathf.Abs(num3) > 0f) { val2 = Quaternion.AngleAxis(num3, right) * val2; } if (num4 > 0f) { Vector2 val3 = Random.insideUnitCircle * num4; val2 = Quaternion.AngleAxis(val3.x, up) * val2; val2 = Quaternion.AngleAxis(val3.y, right) * val2; } if (((ItemEquippable)__instance).ArchetypeData.PiercingBullets) { int num6 = 5; int num7 = 0; bool flag = false; float num8 = 0f; int num9 = 0; while (!flag && num7 < num6 && num5 > 0f && num9 < ((ItemEquippable)__instance).ArchetypeData.PiercingDamageCountLimit) { if (Physics.Raycast(val, val2, ref val4, num5, LayerManager.MASK_BULLETWEAPON_RAY)) { GameObject gameObject = ((Component)((RaycastHit)(ref val4)).collider).gameObject; IDamageable val5 = null; ColliderMaterial component = gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { val5 = component.Damageable; } if (val5 == null) { val5 = gameObject.GetComponent(); } if (val5 != null) { num9++; } Replay.Trigger((ReplayEvent)(object)new rGunshot(owner, damage, val, ((RaycastHit)(ref val4)).point, sentry, silent)); flag = !CustomExtensions.IsInLayerMask(((Component)((RaycastHit)(ref val4)).collider).gameObject, LayerMask.op_Implicit(LayerManager.MASK_BULLETWEAPON_PIERCING_PASS)); val = ((RaycastHit)(ref val4)).point + val2 * 0.1f; num8 += ((RaycastHit)(ref val4)).distance; num5 -= ((RaycastHit)(ref val4)).distance; } else { flag = true; } num7++; } } else if (Physics.Raycast(val, val2, ref val6, num5, LayerManager.MASK_BULLETWEAPON_RAY)) { Replay.Trigger((ReplayEvent)(object)new rGunshot(owner, damage, val, ((RaycastHit)(ref val6)).point, sentry, silent)); } } } [HarmonyPatch(typeof(ShotgunSynced), "Fire")] [HarmonyPostfix] private static void Postfix_ShotgunSyncFire() { _Postfix_ShotgunSyncFire(); } private static void _Postfix_ShotgunSyncFire() { damage = 0f; autoTrack = true; owner = null; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void Postfix_CastWeaponRay(bool __result, Transform alignTransform, WeaponHitData weaponRayData, Vector3 originPos) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (autoTrack && __result && !glueShot) { PlayerAgent? source = owner; float num = damage; RaycastHit rayHit = weaponRayData.rayHit; Replay.Trigger((ReplayEvent)(object)new rGunshot(source, num, originPos, ((RaycastHit)(ref rayHit)).point, sentry, silent)); } } } private static List> cancelSyncedShotConditions = new List>(); private byte dimension; private float damage; private Vector3 start; private Vector3 end; private bool sentry; private bool silent; public static void RegisterCancelSyncedShot(Func condition) { cancelSyncedShotConditions.Add(condition); } internal static bool CancelSyncedShot(BulletWeapon weapon) { foreach (Func cancelSyncedShotCondition in cancelSyncedShotConditions) { if (cancelSyncedShotCondition(weapon)) { return true; } } return false; } public rGunshot(PlayerAgent? source, float damage, Vector3 start, Vector3 end, bool sentry, bool silent, bool fixStartPos = true) : base(((Object)(object)source == (Object)null) ? (-1) : ((Agent)source).GlobalID) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Invalid comparison between Unknown and I4 //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) dimension = (((Object)(object)source == (Object)null) ? ((byte)Dimension.GetDimensionFromPos(start).DimensionIndex) : ((byte)((Agent)source).DimensionIndex)); this.damage = damage; this.start = start; this.silent = silent; if (fixStartPos && !sentry && (Object)(object)source != (Object)null) { Vector3 position = ((Component)source).transform.position; position.y = 0f; Vector3 val = this.start; val.y = 0f; Vector3 val2 = position - val; if (((Vector3)(ref val2)).sqrMagnitude < 1f) { ItemEquippable wieldedItem = source.Inventory.WieldedItem; Animator animatorBody = source.AnimatorBody; if ((Object)(object)wieldedItem != (Object)null) { Vector3 position2 = animatorBody.GetBoneTransform((HumanBodyBones)5).position; Vector3 position3 = animatorBody.GetBoneTransform((HumanBodyBones)6).position; Vector3 val3 = (position2 + position3) / 2f; val3.y = 0f; Vector3 position4 = ((Component)source).transform.position; position4.y = 0f; Vector3 val4 = Vector3.zero; if ((int)source.Locomotion.m_currentStateEnum != 1) { val4 = Vector3.down * ((((Agent)source).IsLocallyOwned && !source.Owner.IsBot) ? 0.45f : 0.25f); } this.start = ((Component)wieldedItem.GearPartHolder).transform.position + val4 + (position4 - val3); } else { this.start += Vector3.down * 0.4f; } } } this.end = end; this.sentry = sentry; } public override void Write(ByteBuffer buffer) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) ((Id)this).Write(buffer); BitHelper.WriteBytes(dimension, buffer); BitHelper.WriteHalf(damage, buffer); BitHelper.WriteBytes(sentry, buffer); BitHelper.WriteBytes(start, buffer); BitHelper.WriteBytes(end, buffer); BitHelper.WriteBytes(silent, buffer); } } [ReplayData("Vanilla.Pings", "0.0.1")] [HarmonyPatch] public class rPing : ReplayDynamic { public class rNavMarker { public int instance; public SyncedNavMarkerWrapper sync; public NavMarker marker; public eNavMarkerStyle style = (eNavMarkerStyle)15; public rNavMarker(SyncedNavMarkerWrapper sync) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) this.sync = sync; marker = sync.m_marker; instance = ((Object)marker).GetInstanceID(); } } [HarmonyPatch] private static class Patches { public static Dictionary navMarkers = new Dictionary(); [HarmonyPatch(typeof(SyncedNavMarkerWrapper), "Setup")] [HarmonyPostfix] private static void Postfix_Setup(SyncedNavMarkerWrapper __instance) { navMarkers.Add(((Object)__instance.m_marker).GetInstanceID(), new rNavMarker(__instance)); } [HarmonyPatch(typeof(NavMarker), "SetStyle")] [HarmonyPostfix] private static void Postfix_Setup(NavMarker __instance, eNavMarkerStyle style) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)__instance).GetInstanceID(); if (navMarkers.ContainsKey(instanceID)) { navMarkers[instanceID].style = style; } } [ReplayOnHeaderCompletion] private static void Init() { foreach (rNavMarker value in navMarkers.Values) { Replay.Spawn((ReplayDynamic)(object)new rPing(value), true); } } } private bool _visible; private eNavMarkerStyle _style; private Vector3 _position; private byte _dimension; private rNavMarker navMarker; public override bool Active => navMarker != null; public override bool IsDirty { get { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) if (_dimension == dimension && !(_position != position) && _visible == visible) { return _style != style; } return true; } } private bool visible => navMarker.marker.IsVisible; private eNavMarkerStyle style => navMarker.style; private Vector3 position => ((Component)navMarker.sync).transform.position; private byte dimension => (byte)Dimension.GetDimensionFromPos(position).DimensionIndex; public rPing(rNavMarker navMarker) : base(((Object)navMarker.marker).GetInstanceID()) { this.navMarker = navMarker; } public override void Write(ByteBuffer buffer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) _visible = visible; _style = style; _position = position; _dimension = dimension; BitHelper.WriteBytes(_dimension, buffer); BitHelper.WriteBytes(_position, buffer); BitHelper.WriteBytes(_visible, buffer); BitHelper.WriteBytes((byte)_style, buffer); } public override void Spawn(ByteBuffer buffer) { BitHelper.WriteBytes((byte)((navMarker.sync.m_playerIndex < 0) ? 255u : ((uint)navMarker.sync.m_playerIndex)), buffer); ((ReplayDynamic)this).Write(buffer); } } [ReplayData("Vanilla.WardenEvents.Survival", "0.0.1")] internal class rWardenEventSurvival : ReplayDynamic { private enum State { Inactive, TimeToActivate, Survival, Completed } private static int _id; private WardenObjectiveDataBlock data; private State state; private float timeLeft; private LG_LayerType layer; private int chainIndex; public override bool IsDirty { get { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected I4, but got Unknown pWardenObjectiveState currentState = WardenObjectiveManager.CurrentState; currentState.GetLayerStatus(layer); float extraTime = WardenObjectiveManager.GetExtraTime(); float num = WardenObjectiveManager.CurrentState.GetStartTimeFromLayer(layer) + data.Survival_TimeToActivate; if (data.Survival_TimeToActivate > 0f) { num += extraTime; } float num2 = num + data.Survival_TimeToSurvive; if (data.Survival_TimeToSurvive > 0f) { num2 += extraTime; } int num3 = 0; LG_LayerType val = layer; switch ((int)val) { case 0: num3 = currentState.main_chainIndex; break; case 1: num3 = currentState.second_chainIndex; break; case 2: num3 = currentState.third_chainIndex; break; } float num4; State state; if (chainIndex != num3) { num4 = 0f; state = ((chainIndex >= num3) ? State.Completed : State.Inactive); } else if (Clock.ExpeditionProgressionTime > num2) { num4 = 0f; state = State.Completed; } else if (Clock.ExpeditionProgressionTime > num) { num4 = num2 - Clock.ExpeditionProgressionTime; state = State.Survival; } else { num4 = num - Clock.ExpeditionProgressionTime; state = State.TimeToActivate; } bool result = timeLeft != num4 || this.state != state; timeLeft = num4; this.state = state; return result; } } public override bool Active => true; [ReplayOnGameplayStart] private static void Init() { _id = 0; SpawnSurvivalEventsForLayer((LG_LayerType)0); SpawnSurvivalEventsForLayer((LG_LayerType)1); SpawnSurvivalEventsForLayer((LG_LayerType)2); } private static void SpawnSurvivalEventsForLayer(LG_LayerType layer) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); for (int i = 0; i < WardenObjectiveManager.GetWardenObjectiveCountForLayer(layer); i++) { if (WardenObjectiveManager.TryGetWardenObjectiveDataForLayer(layer, i, ref val) && (int)val.Type == 11) { Replay.Spawn((ReplayDynamic)(object)new rWardenEventSurvival(_id++, val, layer, i), true); } } } public rWardenEventSurvival(int id, WardenObjectiveDataBlock data, LG_LayerType layer, int chainIndex) : base(id) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) this.data = data; this.chainIndex = chainIndex; this.layer = layer; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes((byte)state, buffer); BitHelper.WriteHalf(timeLeft, buffer); } public override void Spawn(ByteBuffer buffer) { BitHelper.WriteBytes(LocalizedText.op_Implicit(data.Survival_TimerTitle), buffer); BitHelper.WriteBytes(LocalizedText.op_Implicit(data.Survival_TimerToActivateTitle), buffer); } } } namespace Vanilla.Enemy { [HarmonyPatch] internal static class EnemyReplayManager { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(EnemySync), "OnSpawn")] [HarmonyPostfix] private static void OnSpawn(EnemySync __instance, pEnemySpawnData spawnData) { Spawn(__instance.m_agent); } [HarmonyPatch(typeof(EnemySync), "OnDespawn")] [HarmonyPostfix] private static void OnDespawn(EnemySync __instance) { Despawn(__instance.m_agent); } [HarmonyPatch(typeof(EnemyBehaviour), "ChangeState", new Type[] { typeof(EB_States) })] [HarmonyPrefix] private static void Behaviour_ChangeState(EnemyBehaviour __instance, EB_States state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if (__instance.m_currentStateName != state && (int)state == 19) { Despawn(__instance.m_ai.m_enemyAgent); } } } public static void Spawn(EnemyAgent enemy) { if (Replay.Active) { Replay.Spawn((ReplayDynamic)(object)new rEnemy(enemy), true); Replay.Spawn((ReplayDynamic)(object)new rEnemyAnimation(enemy), true); } } public static void Despawn(EnemyAgent enemy) { if (Replay.Active) { Replay.TryDespawn((int)((Agent)enemy).GlobalID); Replay.TryDespawn((int)((Agent)enemy).GlobalID); } } } public struct EnemyTransform : IReplayTransform { private Agent agent; public bool active => (Object)(object)agent != (Object)null; public byte dimensionIndex => (byte)agent.m_dimensionIndex; public Vector3 position => ((Component)agent).transform.position; public Quaternion rotation => ((Component)agent).transform.rotation; public EnemyTransform(Agent agent) { this.agent = agent; } } [ReplayData("Vanilla.Enemy", "0.0.4")] public class rEnemy : DynamicTransform { [HarmonyPatch] private static class Patches { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static void Prefix_SetTarget(EnemyAI __instance, AgentTarget value) { if (value != null && (((AgentAI)__instance).m_target == null || value.m_agent.GlobalID != ((AgentAI)__instance).m_target.m_agent.GlobalID)) { PlayerAgent val = ((Il2CppObjectBase)value.m_agent).TryCast(); if ((Object)(object)val != (Object)null && Replay.Has((int)((Agent)__instance.m_enemyAgent).GlobalID)) { Replay.Get((int)((Agent)__instance.m_enemyAgent).GlobalID).targetPlayer = val; } } } } public PlayerAgent? targetPlayer; public EnemyAgent agent; private bool tagged; private byte target = byte.MaxValue; private PouncerBehaviour? pouncer; private byte consumedPlayer; private byte stagger; private bool canStagger = true; private bool _tagged => agent.IsTagged; private byte _target { get { if ((Object)(object)agent.AI == (Object)null || ((AgentAI)agent.AI).m_target == null || (Object)(object)((AgentAI)agent.AI).m_target.m_agent == (Object)null) { return byte.MaxValue; } PlayerAgent val = ((Il2CppObjectBase)((AgentAI)agent.AI).m_target.m_agent).TryCast(); if ((Object)(object)val == (Object)null) { return byte.MaxValue; } return (byte)val.PlayerSlotIndex; } } private byte _consumedPlayer { get { if ((Object)(object)pouncer == (Object)null) { return byte.MaxValue; } if ((Object)(object)pouncer.CapturedPlayer == (Object)null) { return byte.MaxValue; } return (byte)pouncer.CapturedPlayer.PlayerSlotIndex; } } private byte _stagger { get { float num = ((!((Object)(object)pouncer != (Object)null)) ? (agent.Damage.m_damBuildToHitreact / agent.EnemyBalancingData.Health.DamageUntilHitreact) : ((((MachineState)(object)((StateMachine)(object)pouncer).CurrentState).ENUM_ID == ((MachineState)(object)pouncer.Dash).ENUM_ID) ? (pouncer.Dash.m_damageReceivedDuringState / pouncer.m_data.DashStaggerDamageThreshold) : ((((MachineState)(object)((StateMachine)(object)pouncer).CurrentState).ENUM_ID == ((MachineState)(object)pouncer.Charge).ENUM_ID) ? (pouncer.Charge.m_damageReceivedDuringState / pouncer.m_data.ChargeStaggerDamageThreshold) : ((((MachineState)(object)((StateMachine)(object)pouncer).CurrentState).ENUM_ID != ((MachineState)(object)pouncer.Stagger).ENUM_ID) ? 0f : 1f)))); return (byte)(Mathf.Clamp01(num) * 255f); } } private bool _canStagger { get { if ((Object)(object)pouncer != (Object)null) { if (((MachineState)(object)((StateMachine)(object)pouncer).CurrentState).ENUM_ID != ((MachineState)(object)pouncer.Dash).ENUM_ID) { return ((MachineState)(object)((StateMachine)(object)pouncer).CurrentState).ENUM_ID == ((MachineState)(object)pouncer.Charge).ENUM_ID; } return true; } return true; } } public override bool IsDirty { get { if (!((DynamicTransform)this).IsDirty && consumedPlayer == _consumedPlayer && tagged == _tagged && target == _target && stagger == _stagger) { return canStagger != _canStagger; } return true; } } public rEnemy(EnemyAgent enemy) : base((int)((Agent)enemy).GlobalID, (IReplayTransform)(object)new EnemyTransform((Agent)(object)enemy)) { agent = enemy; pouncer = ((Component)enemy).GetComponent(); } public override void Write(ByteBuffer buffer) { ((DynamicTransform)this).Write(buffer); tagged = _tagged; BitHelper.WriteBytes(tagged, buffer); consumedPlayer = _consumedPlayer; BitHelper.WriteBytes(consumedPlayer, buffer); target = _target; BitHelper.WriteBytes(target, buffer); stagger = _stagger; BitHelper.WriteBytes(stagger, buffer); canStagger = _canStagger; BitHelper.WriteBytes(canStagger, buffer); } public override void Spawn(ByteBuffer buffer) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) ((DynamicTransform)this).Spawn(buffer); BitHelper.WriteBytes((ushort)agent.Locomotion.AnimHandleName, buffer); BitHelper.WriteHalf(agent.SizeMultiplier, buffer); BitHelper.WriteBytes((BufferWriteable)(object)Identifier.From(agent), buffer); BitHelper.WriteHalf(((Dam_SyncedDamageBase)agent.Damage).HealthMax, buffer); } } [ReplayData("Vanilla.Enemy.Animation.AttackWindup", "0.0.1")] internal class rAttackWindup : Id { private byte animIndex; public rAttackWindup(EnemyAgent enemy, byte animIndex) : base((int)((Agent)enemy).GlobalID) { this.animIndex = animIndex; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(animIndex, buffer); } } [ReplayData("Vanilla.Enemy.Animation.Hitreact", "0.0.1")] internal class rHitreact : Id { public enum Direction { Forward, Backward, Left, Right } public enum Type { Light, Heavy } private byte animIndex; private Direction direction; private Type type; public rHitreact(EnemyAgent enemy, byte animIndex, Type type, Direction direction) : base((int)((Agent)enemy).GlobalID) { this.animIndex = animIndex; this.direction = direction; this.type = type; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(animIndex, buffer); BitHelper.WriteBytes((byte)direction, buffer); BitHelper.WriteBytes((byte)type, buffer); } } [ReplayData("Vanilla.Enemy.Animation.Melee", "0.0.1")] internal class rMelee : Id { public enum Type { foward, backward } private byte animIndex; private Type type; public rMelee(EnemyAgent enemy, byte animIndex, Type type) : base((int)((Agent)enemy).GlobalID) { this.animIndex = animIndex; this.type = type; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(animIndex, buffer); BitHelper.WriteBytes((byte)type, buffer); } } [ReplayData("Vanilla.Enemy.Animation.Jump", "0.0.1")] internal class rJump : Id { private byte animIndex; public rJump(EnemyAgent enemy, byte animIndex) : base((int)((Agent)enemy).GlobalID) { this.animIndex = animIndex; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(animIndex, buffer); } } [ReplayData("Vanilla.Enemy.Animation.Heartbeat", "0.0.1")] internal class rHeartbeat : Id { private byte animIndex; public rHeartbeat(EnemyAgent enemy, byte animIndex) : base((int)((Agent)enemy).GlobalID) { this.animIndex = animIndex; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(animIndex, buffer); } } [ReplayData("Vanilla.Enemy.Animation.Wakeup", "0.0.1")] internal class rWakeup : Id { private byte animIndex; private bool turn; public rWakeup(EnemyAgent enemy, byte animIndex, bool turn) : base((int)((Agent)enemy).GlobalID) { this.animIndex = animIndex; this.turn = turn; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(animIndex, buffer); BitHelper.WriteBytes(turn, buffer); } } [ReplayData("Vanilla.Enemy.Animation.PouncerGrab", "0.0.1")] internal class rPouncerGrab : Id { public rPouncerGrab(EnemyAgent enemy) : base((int)((Agent)enemy).GlobalID) { } } [ReplayData("Vanilla.Enemy.Animation.PouncerSpit", "0.0.1")] internal class rPouncerSpit : Id { public rPouncerSpit(EnemyAgent enemy) : base((int)((Agent)enemy).GlobalID) { } } [ReplayData("Vanilla.Enemy.Animation.ScoutScream", "0.0.1")] internal class rScoutScream : Id { private bool start; public rScoutScream(EnemyAgent enemy, bool start) : base((int)((Agent)enemy).GlobalID) { this.start = start; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(start, buffer); } } [ReplayData("Vanilla.Enemy.Animation.BigFlyerCharge", "0.0.1")] internal class rBigFlyerCharge : Id { private float charge; public rBigFlyerCharge(EnemyAgent enemy, float chargeDuration) : base((int)((Agent)enemy).GlobalID) { charge = chargeDuration; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteHalf(charge, buffer); } } [HarmonyPatch] [ReplayData("Vanilla.Enemy.Animation", "0.0.1")] internal class rEnemyAnimation : ReplayDynamic { [HarmonyPatch] private static class Patches { private static void Trigger(Id e) { if (Replay.Has(e.id)) { Replay.Trigger((ReplayEvent)(object)e); } } [HarmonyPatch(typeof(EB_InCombat_ChargedAttack_Flyer), "SetAI")] [HarmonyPostfix] private static void Postfix_BigFlyerAttack_Client(EB_InCombat_ChargedAttack_Flyer __instance) { EB_InCombat_ChargedAttack_Flyer __instance2 = __instance; if (!SNet.IsMaster && ((Agent)((EB_StateBase)__instance2).m_ai.m_enemyAgent).Alive) { Action previous = __instance2.m_attackVisualsPacket.ReceiveAction; __instance2.m_attackVisualsPacket.ReceiveAction = Action.op_Implicit((Action)delegate(pEB_FlyerAttackVisualInfoSignal packet) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Trigger((Id)(object)new rBigFlyerCharge(((EB_StateBase)__instance2).m_ai.m_enemyAgent, packet.ChargeDuration)); previous?.Invoke(packet); }); } } [HarmonyPatch(typeof(EB_InCombat_ChargedAttack_Flyer), "CommonEnter")] [HarmonyPostfix] private static void Postfix_BigFlyerAttack_Host(EB_InCombat_ChargedAttack_Flyer __instance) { if (SNet.IsMaster && ((Agent)((EB_StateBase)__instance).m_ai.m_enemyAgent).Alive) { Trigger((Id)(object)new rBigFlyerCharge(((EB_StateBase)__instance).m_ai.m_enemyAgent, ((InCombat_ChargedAttack)__instance).m_CharageDuration)); } } [HarmonyPatch(typeof(ES_ScoutDetection), "CommonEnter")] [HarmonyPostfix] private static void Postfix_ScoutDetection_Enter(ES_ScoutScream __instance) { if (((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { Trigger((Id)(object)new rScoutScream(((ES_Base)__instance).m_ai.m_enemyAgent, start: true)); } } [HarmonyPatch(typeof(ES_ScoutDetection), "CommonExit")] [HarmonyPostfix] private static void Postfix_ScoutDetection_Exit(ES_ScoutScream __instance) { if (((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { Trigger((Id)(object)new rScoutScream(((ES_Base)__instance).m_ai.m_enemyAgent, start: false)); } } [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] [HarmonyPrefix] private static void Prefix_ScoutScream(ES_ScoutScream __instance) { //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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if (!((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { return; } ScoutScreamState state = __instance.m_state; if ((int)state != 0) { if ((int)state == 1 && __instance.m_stateDoneTimer < Clock.Time) { Trigger((Id)(object)new rScoutScream(((ES_Base)__instance).m_ai.m_enemyAgent, start: false)); } } else { Trigger((Id)(object)new rScoutScream(((ES_Base)__instance).m_ai.m_enemyAgent, start: true)); } } [HarmonyPatch(typeof(PouncerBehaviour), "ForceChangeAnimationState")] [HarmonyPostfix] private static void Postfix_Pouncer_Host(PouncerBehaviour __instance, int animationState) { if (SNet.IsMaster && ((Agent)((EnemyBehaviour)__instance).m_ai.m_enemyAgent).Alive) { if (animationState == PouncerBehaviour.PO_ConsumeStart) { Trigger((Id)(object)new rPouncerGrab(((EnemyBehaviour)__instance).m_ai.m_enemyAgent)); } else if (animationState == PouncerBehaviour.PO_SpitOut) { Trigger((Id)(object)new rPouncerSpit(((EnemyBehaviour)__instance).m_ai.m_enemyAgent)); } } } [HarmonyPatch(typeof(PouncerBehaviour), "OnAnimationStateChangePacketReceived")] [HarmonyPostfix] private static void Postfix_Pouncer_Client(PouncerBehaviour __instance, pEB_AnimationStateChanagePacket data) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster && ((Agent)((EnemyBehaviour)__instance).m_ai.m_enemyAgent).Alive) { if (data.AnimationState == PouncerBehaviour.PO_ConsumeStart) { Trigger((Id)(object)new rPouncerGrab(((EnemyBehaviour)__instance).m_ai.m_enemyAgent)); } else if (data.AnimationState == PouncerBehaviour.PO_SpitOut) { Trigger((Id)(object)new rPouncerSpit(((EnemyBehaviour)__instance).m_ai.m_enemyAgent)); } } } [HarmonyPatch(typeof(ES_HibernateWakeUp), "DoWakeup")] [HarmonyPostfix] private static void Postfix_Wakeup(ES_HibernateWakeUp __instance) { if (((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { Trigger((Id)(object)new rWakeup(((ES_Base)__instance).m_enemyAgent, (byte)__instance.m_animationIndex, __instance.m_isTurn)); } } [HarmonyPatch(typeof(ES_Hibernate), "StartBeat")] [HarmonyPrefix] private static void Prefix_StartBeat(ES_Hibernate __instance, float strength, bool doAnim) { if (!((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { return; } if (doAnim && __instance.m_lastHeartbeatAnim < Clock.Time) { Trigger((Id)(object)new rHeartbeat(((ES_Base)__instance).m_enemyAgent, (byte)__instance.m_currentHeartBeatIndex)); } if (!((ES_Base)__instance).m_enemyAgent.MovingCuller.IsShown) { __instance.m_lastHeartbeatAnim = Clock.Time + 1f; int currentHeartBeatIndex = __instance.m_currentHeartBeatIndex; __instance.m_currentHeartBeatIndex = currentHeartBeatIndex + 1; if (__instance.m_currentHeartBeatIndex == __instance.m_heartBeatIndexMax) { __instance.m_currentHeartBeatIndex = 0; } } } [HarmonyPatch(typeof(ES_Jump), "DoStartJump")] [HarmonyPrefix] private static void Prefix_DoStartJump(ES_Jump __instance) { if (((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { Trigger((Id)(object)new rJump(((ES_Base)__instance).m_enemyAgent, 0)); } } [HarmonyPatch(typeof(ES_Jump), "UpdateJump")] [HarmonyPrefix] private static void Prefix_UpdateJump(ES_Jump __instance) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (((Agent)((ES_Base)__instance).m_enemyAgent).Alive && (int)__instance.m_state == 1 && !(__instance.m_jumpMoveTimeRel + Clock.Delta * __instance.m_jumpMoveSpeed < 1f)) { Trigger((Id)(object)new rJump(((ES_Base)__instance).m_enemyAgent, 1)); } } [HarmonyPatch(typeof(ES_Hitreact), "DoHitReact")] [HarmonyPrefix] private static void Prefix_DoHitReact(ES_Hitreact __instance, int index, ES_HitreactType hitreactType, ImpactDirection impactDirection, float deathDelay, bool propagated, Vector3 damagePos, Vector3 source) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected I4, but got Unknown if (!((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { return; } rHitreact.Type type; if ((int)hitreactType != 3) { if ((int)hitreactType != 4) { return; } type = rHitreact.Type.Heavy; } else { type = rHitreact.Type.Light; } rHitreact.Direction direction; switch (impactDirection - 1) { default: return; case 0: direction = rHitreact.Direction.Forward; break; case 1: direction = rHitreact.Direction.Backward; break; case 3: direction = rHitreact.Direction.Left; break; case 2: direction = rHitreact.Direction.Right; break; } Trigger((Id)(object)new rHitreact(((ES_Base)__instance).m_enemyAgent, (byte)index, type, direction)); } [HarmonyPatch(typeof(ES_StrikerMelee), "DoStartMeleeAttack")] [HarmonyPrefix] private static void Prefix_DoStartMeleeAttack(ES_StrikerMelee __instance, int animIndex, bool fwdAttack) { if (((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { Trigger((Id)(object)new rMelee(((ES_Base)__instance).m_enemyAgent, (byte)animIndex, (!fwdAttack) ? rMelee.Type.backward : rMelee.Type.foward)); } } [HarmonyPatch(typeof(ES_EnemyAttackBase), "DoStartAttack")] [HarmonyPrefix] private static void Prefix_DoStartAttack(ES_EnemyAttackBase __instance, Vector3 pos, Vector3 attackTargetPosition, Agent targetAgent, int animIndex, AgentAbility abilityType, int abilityIndex) { if (((Agent)((ES_Base)__instance).m_enemyAgent).Alive) { Trigger((Id)(object)new rAttackWindup(((ES_Base)__instance).m_enemyAgent, (byte)animIndex)); } } } public EnemyAgent enemy; private Vector3 lastPosition; private Vector3 velocity; private byte velFwd; private byte velRight; private byte velUp; private byte state; private bool up; private byte detect; public override bool Active => (Object)(object)enemy != (Object)null; public override bool IsDirty { get { UpdateVelocity(); if (velFwd == compress(_velFwd, 10f) && velRight == compress(_velRight, 10f) && velUp == compress(_velUp, 10f) && up == _up && state == _state) { return detect != _detect; } return true; } } private float _velFwd => velocity.z; private float _velRight => velocity.x; private float _velUp => velocity.y; private byte _state { get { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown if (!((Object)(object)enemy.Damage != (Object)null) || !enemy.Damage.IsStuckInGlue) { return (byte)(int)((StateMachine)(object)enemy.Locomotion).m_currentState.m_stateEnum; } return 17; } } private bool _up => enemy.Locomotion.ClimbLadder.m_goingUp; private byte _detect => (byte)(Mathf.Clamp01(enemy.Locomotion.Hibernate.m_detectionCurrent) * 255f); private static byte compress(float value, float max) { value /= max; value = Mathf.Clamp(value, -1f, 1f); value = Mathf.Clamp01((value + 1f) / 2f); return (byte)(value * 255f); } private void UpdateVelocity() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)enemy).transform.position - lastPosition; val /= Replay.tickRate; lastPosition = ((Component)enemy).transform.position; velocity.x = Vector3.Dot(((Component)enemy).transform.right, val); velocity.y = Vector3.Dot(((Component)enemy).transform.up, val); velocity.z = Vector3.Dot(((Component)enemy).transform.forward, val); } public rEnemyAnimation(EnemyAgent enemy) : base((int)((Agent)enemy).GlobalID) { this.enemy = enemy; } public override void Write(ByteBuffer buffer) { velRight = compress(_velRight, 10f); velUp = compress(_velUp, 10f); velFwd = compress(_velFwd, 10f); BitHelper.WriteBytes(velRight, buffer); BitHelper.WriteBytes(velUp, buffer); BitHelper.WriteBytes(velFwd, buffer); state = _state; BitHelper.WriteBytes(state, buffer); up = _up; BitHelper.WriteBytes(up, buffer); detect = _detect; BitHelper.WriteBytes(detect, buffer); } public override void Spawn(ByteBuffer buffer) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) lastPosition = ((Component)enemy).transform.position; UpdateVelocity(); ((ReplayDynamic)this).Write(buffer); } } [HarmonyPatch] [ReplayData("Vanilla.Enemy.LimbCustom", "0.0.2")] public class rLimbCustom : ReplayDynamic { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(EnemySync), "OnSpawn")] [HarmonyPostfix] private static void OnSpawn(EnemySync __instance, pEnemySpawnData spawnData) { foreach (Dam_EnemyDamageLimb item in (Il2CppArrayBase)(object)__instance.m_damage.DamageLimbs) { Dam_EnemyDamageLimb_Custom val = ((Il2CppObjectBase)item).TryCast(); if ((Object)(object)val != (Object)null) { Bone bone = Bone.Hip; GetBone(val, ref bone); Replay.Spawn((ReplayDynamic)(object)new rLimbCustom(val, bone), true); } } } [HarmonyPatch(typeof(EnemySync), "OnDespawn")] [HarmonyPostfix] private static void OnDespawn(EnemySync __instance) { foreach (Dam_EnemyDamageLimb item in (Il2CppArrayBase)(object)__instance.m_damage.DamageLimbs) { Dam_EnemyDamageLimb_Custom val = ((Il2CppObjectBase)item).TryCast(); if ((Object)(object)val != (Object)null) { Replay.TryDespawn(((Object)val).GetInstanceID()); } } } [HarmonyPatch(typeof(Dam_EnemyDamageLimb_Custom), "DestroyLimb")] [HarmonyPostfix] private static void OnDestroy(Dam_EnemyDamageLimb_Custom __instance) { Replay.TryDespawn(((Object)__instance).GetInstanceID()); } } public enum Bone { Hip, LeftUpperLeg, LeftLowerLeg, LeftFoot, RightUpperLeg, RightLowerLeg, RightFoot, Spine0, Spine1, Spine2, LeftShoulder, LeftUpperArm, LeftLowerArm, LeftHand, RightShoulder, RightUpperArm, RightLowerArm, RightHand, Neck, Head } private Dam_EnemyDamageLimb_Custom limb; private Collider col; private Bone bone; private bool oldEnabled = true; private Vector3 offset { get { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) Vector3 result = ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.InverseTransformDirection(((Component)limb).transform.position - ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.position); result.x /= ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.lossyScale.x; result.y /= ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.lossyScale.y; result.z /= ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.lossyScale.z; return result; } } private float scale => Mathf.Max(new float[3] { ((Component)limb).transform.lossyScale.x / ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.lossyScale.x, ((Component)limb).transform.lossyScale.y / ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.lossyScale.y, ((Component)limb).transform.lossyScale.z / ((Component)((Dam_EnemyDamageLimb)limb).m_base.Owner).transform.lossyScale.z }); public override bool Active => (Object)(object)limb != (Object)null; public override bool IsDirty => col.enabled != oldEnabled; public static Transform? GetBone(Dam_EnemyDamageLimb_Custom limb, ref Bone bone) { Transform val = ((Component)limb).transform; while ((Object)(object)val.parent != (Object)null) { switch (((Object)val.parent).name.Trim().ToLower()) { case "head": bone = Bone.Head; return val.parent; case "neck": bone = Bone.Neck; return val.parent; case "leftshoulder": bone = Bone.LeftShoulder; return val.parent; case "leftupperarm": bone = Bone.LeftUpperArm; return val.parent; case "leftlowerarm": bone = Bone.LeftLowerArm; return val.parent; case "lefthand": bone = Bone.LeftHand; return val.parent; case "rightshoulder": bone = Bone.RightShoulder; return val.parent; case "rightupperarm": bone = Bone.RightUpperArm; return val.parent; case "rightlowerarm": bone = Bone.RightLowerArm; return val.parent; case "righthand": bone = Bone.RightHand; return val.parent; case "spine1": bone = Bone.Spine0; return val.parent; case "spine2": bone = Bone.Spine1; return val.parent; case "spine3": bone = Bone.Spine2; return val.parent; case "chest": bone = Bone.Spine2; return val.parent; case "spine": bone = Bone.Spine0; return val.parent; case "hip": bone = Bone.Hip; return val.parent; case "leftupperleg": bone = Bone.LeftUpperLeg; return val.parent; case "leftLowerleg": bone = Bone.LeftLowerLeg; return val.parent; case "leftFoot": bone = Bone.LeftFoot; return val.parent; case "rightupperleg": bone = Bone.RightUpperLeg; return val.parent; case "rightLowerleg": bone = Bone.RightLowerLeg; return val.parent; case "rightFoot": bone = Bone.RightFoot; return val.parent; } val = val.parent; } return val.parent; } public rLimbCustom(Dam_EnemyDamageLimb_Custom limb, Bone bone) : base(((Object)limb).GetInstanceID()) { this.limb = limb; col = ((Component)limb).GetComponent(); this.bone = bone; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes(col.enabled, buffer); oldEnabled = col.enabled; } public override void Spawn(ByteBuffer buffer) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes(((Agent)((Dam_EnemyDamageLimb)limb).m_base.Owner).GlobalID, buffer); BitHelper.WriteBytes((byte)bone, buffer); BitHelper.WriteHalf(offset, buffer); BitHelper.WriteHalf(scale, buffer); } } [HarmonyPatch] [ReplayData("Vanilla.Enemy.LimbDestruction", "0.0.1")] public class rLimbDestruction : Id { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(EnemySync), "OnSpawn")] [HarmonyPostfix] private static void OnSpawn(EnemySync __instance) { EnemySync __instance2 = __instance; if ((Object)(object)__instance2.m_agent.m_headLimb == (Object)null) { return; } __instance2.m_agent.m_headLimb.OnLimbDestroyed += Action.op_Implicit((Action)delegate { if (((Agent)__instance2.m_agent).Alive) { Replay.Trigger((ReplayEvent)(object)new rLimbDestruction(__instance2.m_agent, Type.head)); } }); } } public enum Type { head } private Type type; public rLimbDestruction(EnemyAgent agent, Type type) : base((int)((Agent)agent).GlobalID) { this.type = type; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes((byte)type, buffer); } } internal struct ProjectileTransform : IReplayTransform { private GameObject projectile; private byte dimension; public byte dimensionIndex => dimension; public bool active => (Object)(object)projectile != (Object)null; public Vector3 position => projectile.transform.position; public Quaternion rotation => projectile.transform.rotation; public ProjectileTransform(GameObject projectile) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) this.projectile = projectile; dimension = (byte)((Agent)PlayerManager.GetLocalPlayerAgent()).m_dimensionIndex; } } [HarmonyPatch] [ReplayData("Vanilla.Enemy.Projectile", "0.0.1")] public class rEnemyProjectile : DynamicTransform { [HarmonyPatch] internal static class EnemyProjectilePatches { [HarmonyPatch(typeof(ProjectileManager), "DoFireTargeting")] [HarmonyPostfix] private static void DoFireTargeting(ProjectileManager __instance, pFireTargeting data) { GameObject s_tempGO = ProjectileManager.s_tempGO; if (!((Object)(object)s_tempGO == (Object)null)) { Replay.Spawn((ReplayDynamic)(object)new rEnemyProjectile(s_tempGO), true); } } [HarmonyPatch(typeof(ProjectileBase), "OnDestroy")] [HarmonyPrefix] private static void OnDestroy(ProjectileBase __instance) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(((Object)((Component)__instance).gameObject).GetInstanceID()), true); } [HarmonyPatch(typeof(ProjectileBase), "Collision")] [HarmonyPrefix] private static void OnCollision(ProjectileBase __instance) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(((Object)((Component)__instance).gameObject).GetInstanceID()), true); } } public rEnemyProjectile(GameObject projectile) : base(((Object)projectile).GetInstanceID(), (IReplayTransform)(object)new ProjectileTransform(projectile)) { } } [HarmonyPatch] internal static class EnemyRagdollManager { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(EnemyBehaviour), "ChangeState", new Type[] { typeof(EB_States) })] [HarmonyPrefix] private static void Behaviour_ChangeState(EnemyBehaviour __instance, EB_States state) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (ConfigManager.RecordEnemyRagdolls && __instance.m_currentStateName != state && (int)state == 19) { Spawn(__instance.m_ai.m_enemyAgent); } } } public static void Spawn(EnemyAgent enemy) { if (Replay.Active && RagdollPartManager.isValid(enemy)) { RagdollPartManager ragdoll = new RagdollPartManager(enemy); Replay.Spawn((ReplayDynamic)(object)new rEnemyRagdoll(enemy, ragdoll), true); } } public static void Despawn(EnemyAgent enemy) { if (Replay.Active) { Replay.TryDespawn((int)((Agent)enemy).GlobalID); } } [ReplayOnElevatorStop] private static void Init() { Replay.Configure(2, int.MaxValue); } } public class RagdollPartManager { public Transform hip; public Transform spine1; public Transform leftUpperLeg; public Transform leftLowerLeg; public Transform leftFoot; public Transform rightUpperLeg; public Transform rightLowerLeg; public Transform rightFoot; public Transform leftShoulder; public Transform leftUpperArm; public Transform leftLowerArm; public Transform leftHand; public Transform rightShoulder; public Transform rightUpperArm; public Transform rightLowerArm; public Transform rightHand; public Transform neck; public Transform head; public static bool isValid(EnemyAgent enemy) { Animator anim = enemy.Anim; try { return (Object)(object)anim.GetBoneTransform((HumanBodyBones)10) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)9) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)11) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)13) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)15) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)17) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)12) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)14) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)16) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)18) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)1) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)3) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)5) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)2) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)4) != (Object)null && (Object)(object)anim.GetBoneTransform((HumanBodyBones)6) != (Object)null && Object.op_Implicit((Object)(object)anim.GetBoneTransform((HumanBodyBones)0)) && Object.op_Implicit((Object)(object)anim.GetBoneTransform((HumanBodyBones)7)); } catch { return false; } } public RagdollPartManager(EnemyAgent enemy) { Animator anim = enemy.Anim; hip = anim.GetBoneTransform((HumanBodyBones)0); leftUpperLeg = anim.GetBoneTransform((HumanBodyBones)1); leftLowerLeg = anim.GetBoneTransform((HumanBodyBones)3); leftFoot = anim.GetBoneTransform((HumanBodyBones)5); rightUpperLeg = anim.GetBoneTransform((HumanBodyBones)2); rightLowerLeg = anim.GetBoneTransform((HumanBodyBones)4); rightFoot = anim.GetBoneTransform((HumanBodyBones)6); spine1 = anim.GetBoneTransform((HumanBodyBones)7); leftShoulder = anim.GetBoneTransform((HumanBodyBones)11); leftUpperArm = anim.GetBoneTransform((HumanBodyBones)13); leftLowerArm = anim.GetBoneTransform((HumanBodyBones)15); leftHand = anim.GetBoneTransform((HumanBodyBones)17); rightShoulder = anim.GetBoneTransform((HumanBodyBones)12); rightUpperArm = anim.GetBoneTransform((HumanBodyBones)14); rightLowerArm = anim.GetBoneTransform((HumanBodyBones)16); rightHand = anim.GetBoneTransform((HumanBodyBones)18); neck = anim.GetBoneTransform((HumanBodyBones)9); head = anim.GetBoneTransform((HumanBodyBones)10); } } public struct RagdollTransform : IReplayTransform { private EnemyAgent agent; private RagdollPartManager ragdoll; public bool active => (Object)(object)agent != (Object)null; public byte dimensionIndex => (byte)((Agent)agent).m_dimensionIndex; public Vector3 position => ((Component)ragdoll.hip).transform.position; public Quaternion rotation => Quaternion.identity; public RagdollTransform(EnemyAgent agent, RagdollPartManager ragdoll) { this.agent = agent; this.ragdoll = ragdoll; } } [ReplayData("Vanilla.Enemy.Ragdoll", "0.0.2")] public class rEnemyRagdoll : DynamicTransform { public EnemyAgent agent; public RagdollPartManager ragdoll; private Vector3 hip; private Vector3 leftUpperLeg; private Vector3 leftLowerLeg; private Vector3 leftFoot; private Vector3 rightUpperLeg; private Vector3 rightLowerLeg; private Vector3 rightFoot; private Vector3 spine1; private Vector3 leftShoulder; private Vector3 leftUpperArm; private Vector3 leftLowerArm; private Vector3 leftHand; private Vector3 rightShoulder; private Vector3 rightUpperArm; private Vector3 rightLowerArm; private Vector3 rightHand; private Vector3 neck; private Vector3 head; public override bool Active => (Object)(object)agent != (Object)null; public override bool IsDirty { get { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_005a: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0138: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) if (!(((Component)ragdoll.hip).transform.position != hip) && !(((Component)ragdoll.spine1).transform.position != spine1) && !(((Component)ragdoll.leftUpperLeg).transform.position != leftUpperLeg) && !(((Component)ragdoll.leftLowerLeg).transform.position != leftLowerLeg) && !(((Component)ragdoll.leftFoot).transform.position != leftFoot) && !(((Component)ragdoll.rightUpperLeg).transform.position != rightUpperLeg) && !(((Component)ragdoll.rightLowerLeg).transform.position != rightLowerLeg) && !(((Component)ragdoll.rightFoot).transform.position != rightFoot) && !(((Component)ragdoll.leftShoulder).transform.position != leftShoulder) && !(((Component)ragdoll.leftUpperArm).transform.position != leftUpperArm) && !(((Component)ragdoll.leftLowerArm).transform.position != leftLowerArm) && !(((Component)ragdoll.leftHand).transform.position != leftHand) && !(((Component)ragdoll.rightShoulder).transform.position != rightShoulder) && !(((Component)ragdoll.rightUpperArm).transform.position != rightUpperArm) && !(((Component)ragdoll.rightLowerArm).transform.position != rightLowerArm) && !(((Component)ragdoll.rightHand).transform.position != rightHand) && !(((Component)ragdoll.neck).transform.position != neck)) { return ((Component)ragdoll.head).transform.position != head; } return true; } } public rEnemyRagdoll(EnemyAgent agent, RagdollPartManager ragdoll) : base((int)((Agent)agent).GlobalID, (IReplayTransform)(object)new RagdollTransform(agent, ragdoll)) { this.agent = agent; this.ragdoll = ragdoll; } private void WriteAvatar(ByteBuffer buffer) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0214: 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_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) leftUpperLeg = ((Component)ragdoll.leftUpperLeg).transform.position; leftLowerLeg = ((Component)ragdoll.leftLowerLeg).transform.position; leftFoot = ((Component)ragdoll.leftFoot).transform.position; rightUpperLeg = ((Component)ragdoll.rightUpperLeg).transform.position; rightLowerLeg = ((Component)ragdoll.rightLowerLeg).transform.position; rightFoot = ((Component)ragdoll.rightFoot).transform.position; spine1 = ((Component)ragdoll.spine1).transform.position; leftShoulder = ((Component)ragdoll.leftShoulder).transform.position; leftUpperArm = ((Component)ragdoll.leftUpperArm).transform.position; leftLowerArm = ((Component)ragdoll.leftLowerArm).transform.position; leftHand = ((Component)ragdoll.leftHand).transform.position; rightShoulder = ((Component)ragdoll.rightShoulder).transform.position; rightUpperArm = ((Component)ragdoll.rightUpperArm).transform.position; rightLowerArm = ((Component)ragdoll.rightLowerArm).transform.position; rightHand = ((Component)ragdoll.rightHand).transform.position; neck = ((Component)ragdoll.neck).transform.position; head = ((Component)ragdoll.neck).transform.position; BitHelper.WriteHalf(hip, buffer); BitHelper.WriteHalf(leftUpperLeg, buffer); BitHelper.WriteHalf(leftLowerLeg, buffer); BitHelper.WriteHalf(leftFoot, buffer); BitHelper.WriteHalf(rightUpperLeg, buffer); BitHelper.WriteHalf(rightLowerLeg, buffer); BitHelper.WriteHalf(rightFoot, buffer); BitHelper.WriteHalf(spine1, buffer); BitHelper.WriteHalf(leftShoulder, buffer); BitHelper.WriteHalf(leftUpperArm, buffer); BitHelper.WriteHalf(leftLowerArm, buffer); BitHelper.WriteHalf(leftHand, buffer); BitHelper.WriteHalf(rightShoulder, buffer); BitHelper.WriteHalf(rightUpperArm, buffer); BitHelper.WriteHalf(rightLowerArm, buffer); BitHelper.WriteHalf(rightHand, buffer); BitHelper.WriteHalf(neck, buffer); BitHelper.WriteHalf(head, buffer); } public override void Write(ByteBuffer buffer) { ((DynamicTransform)this).Write(buffer); WriteAvatar(buffer); } public override void Spawn(ByteBuffer buffer) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) ((DynamicTransform)this).Spawn(buffer); BitHelper.WriteBytes((ushort)agent.Locomotion.AnimHandleName, buffer); BitHelper.WriteHalf(agent.SizeMultiplier, buffer); BitHelper.WriteBytes((BufferWriteable)(object)Identifier.From(agent), buffer); BitHelper.WriteHalf(((Dam_SyncedDamageBase)agent.Damage).HealthMax, buffer); BitHelper.WriteBytes(agent.m_headLimb.m_health > 0f, buffer); WriteAvatar(buffer); } } [ReplayData("Vanilla.Enemy.Alert", "0.0.1")] public class rEnemyAlert : Id { public byte targetSlot; public rEnemyAlert(EnemyAgent agent, PlayerAgent? target = null) : base((int)((Agent)agent).GlobalID) { if ((Object)(object)target == (Object)null) { targetSlot = byte.MaxValue; } else { targetSlot = (byte)target.PlayerSlotIndex; } } public rEnemyAlert(int id, byte targetSlot) : base(id) { this.targetSlot = targetSlot; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(targetSlot, buffer); } } [ReplayData("Vanilla.Enemy.Animation.Scream", "0.0.1")] public class rEnemyScream : Id { public enum Type { Regular, Scout } private Type type; private byte animIndex; public rEnemyScream(EnemyAgent agent, byte animIndex, Type type = Type.Regular) : base((int)((Agent)agent).GlobalID) { this.type = type; this.animIndex = animIndex; } public override void Write(ByteBuffer buffer) { ((Id)this).Write(buffer); BitHelper.WriteBytes(animIndex, buffer); BitHelper.WriteBytes((byte)type, buffer); } } [HarmonyPatch] internal static class EnemyScreamsAndAlerts { private static class Sync { private const string eventName = "Vanilla.Enemy.Alert"; private static ByteBuffer packet = new ByteBuffer(); [ReplayPluginLoad] private static void Load() { RNet.Register("Vanilla.Enemy.Alert", (Action>)OnReceive); } public static void Trigger(rEnemyAlert alert) { Replay.Trigger((ReplayEvent)(object)alert); ByteBuffer val = packet; val.Clear(); BitHelper.WriteBytes(((Id)alert).id, val); BitHelper.WriteBytes(alert.targetSlot, val); RNet.Trigger("Vanilla.Enemy.Alert", val); } private static void OnReceive(ulong sender, ArraySegment packet) { int num = 0; int id = BitHelper.ReadInt(packet, ref num); byte targetSlot = BitHelper.ReadByte(packet, ref num); Replay.Trigger((ReplayEvent)(object)new rEnemyAlert(id, targetSlot)); } } private static Dictionary enemiesWokenFromScream = new Dictionary(); private static bool wokenFromScream = false; private static bool triggered = false; [HarmonyPatch(typeof(ES_Scream), "ActivateState")] [HarmonyPostfix] private static void Postfix_Scream(ES_Scream __instance) { if (SNet.IsMaster) { Replay.Trigger((ReplayEvent)(object)new rEnemyScream(((ES_Base)__instance).m_ai.m_enemyAgent, (byte)__instance.m_lastAnimIndex)); } } [HarmonyPatch(typeof(ES_Scream), "Update")] [HarmonyPrefix] private static void Prefix_Scream(ES_Scream __instance) { if (SNet.IsMaster && !__instance.m_hasTriggeredPropagation && __instance.m_triggerPropgationAt < Clock.Time) { wokenFromScream = true; } } [HarmonyPatch(typeof(ES_Scream), "SetAI")] [HarmonyPostfix] private static void Scream(ES_Scream __instance) { ES_Scream __instance2 = __instance; if (!SNet.IsMaster) { Action previous = ((ES_ScreamBase)(object)__instance2).m_screamPacket.ReceiveAction; ((ES_ScreamBase)(object)__instance2).m_screamPacket.ReceiveAction = Action.op_Implicit((Action)delegate(pES_EnemyScreamData packet) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Replay.Trigger((ReplayEvent)(object)new rEnemyScream(((ES_Base)__instance2).m_ai.m_enemyAgent, packet.AnimIndex)); previous?.Invoke(packet); }); } } [HarmonyPatch(typeof(ES_Scream), "Update")] [HarmonyPostfix] private static void Postfix_Scream() { wokenFromScream = false; } [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] [HarmonyPrefix] private static void Prefix_ScoutScream(ES_ScoutScream __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (SNet.IsMaster) { wokenFromScream = true; } if ((int)__instance.m_state == 1 && __instance.m_stateDoneTimer < Clock.Time) { EnemyAgent enemyAgent = ((ES_Base)__instance).m_enemyAgent; Replay.Trigger((ReplayEvent)(object)new rEnemyScream(enemyAgent, (byte)__instance.m_lastAnimIndex, rEnemyScream.Type.Scout)); if (!SNet.IsMaster) { Replay.Trigger((ReplayEvent)(object)new rEnemyAlert(enemyAgent)); APILogger.Debug("Client-side scout wake up."); } } } [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] [HarmonyPostfix] private static void Postfix_ScoutScream() { wokenFromScream = false; } [HarmonyPatch(typeof(EnemyAI), "InjectPropagatedTarget")] [HarmonyPrefix] private static void InjectPropagatedTarget(EnemyAI __instance, Agent agent, AgentTargetPropagationType propagation) { if (SNet.IsMaster) { int instanceID = ((Object)__instance.m_enemyAgent).GetInstanceID(); if (wokenFromScream && !enemiesWokenFromScream.ContainsKey(instanceID)) { enemiesWokenFromScream.Add(instanceID, Raudy.Now); } } } [HarmonyPatch(typeof(ES_HibernateWakeUp), "DoWakeup")] [HarmonyPostfix] private static void WakeUp_State(ES_HibernateWakeUp __instance) { if (triggered) { return; } EnemyAgent enemyAgent = ((ES_Base)__instance).m_ai.m_enemyAgent; if (!SNet.IsMaster) { Replay.Trigger((ReplayEvent)(object)new rEnemyAlert(enemyAgent)); APILogger.Debug("Client-side enemy wake up."); return; } long now = Raudy.Now; int[] array = enemiesWokenFromScream.Keys.ToArray(); foreach (int key in array) { if (now - enemiesWokenFromScream[key] > 200) { enemiesWokenFromScream.Remove(key); } } int instanceID = ((Object)enemyAgent).GetInstanceID(); if (enemiesWokenFromScream.ContainsKey(instanceID)) { enemiesWokenFromScream.Remove(instanceID); Sync.Trigger(new rEnemyAlert(enemyAgent)); APILogger.Debug("Enemy was woken by a scream."); } else if (NoiseTracker.CurrentNoise != null) { PlayerAgent source = NoiseTracker.CurrentNoise.source; APILogger.Debug("Detection from noise manager."); Sync.Trigger(new rEnemyAlert(enemyAgent, source)); } else { Sync.Trigger(new rEnemyAlert(enemyAgent)); } } [HarmonyPatch(typeof(EnemyDetection), "UpdateHibernationDetection")] [HarmonyPostfix] private static void WakeUp_Detection(EnemyDetection __instance, AgentTarget target, bool __result) { if (!SNet.IsMaster || !__result) { return; } long now = Raudy.Now; int[] array = enemiesWokenFromScream.Keys.ToArray(); foreach (int key in array) { if (now - enemiesWokenFromScream[key] > 100) { enemiesWokenFromScream.Remove(key); } } EnemyAgent enemyAgent = __instance.m_ai.m_enemyAgent; int instanceID = ((Object)enemyAgent).GetInstanceID(); if (enemiesWokenFromScream.ContainsKey(instanceID)) { enemiesWokenFromScream.Remove(instanceID); Sync.Trigger(new rEnemyAlert(enemyAgent)); APILogger.Debug("Enemy was woken by a scream."); } else { PlayerAgent val = null; if (NoiseTracker.CurrentNoise != null) { val = NoiseTracker.CurrentNoise.source; APILogger.Debug("Detection from noise manager."); } else { val = ((Il2CppObjectBase)target.m_agent).TryCast(); } Sync.Trigger(new rEnemyAlert(enemyAgent, val)); } triggered = true; } [HarmonyPatch(typeof(EB_Hibernating), "UpdateDetection")] [HarmonyPostfix] private static void WakeUpTriggerReset() { triggered = false; } } [ReplayData("Vanilla.Enemy.Spitters.State", "0.0.1")] public class rSpitter : ReplayDynamic { public Vector3 position; public Quaternion rotation; public byte dimension; public float scale; private InfectionSpitter spitter; private eSpitterState _state; public override bool Active => (Object)(object)spitter != (Object)null; public override bool IsDirty => _state != state; private eSpitterState state => spitter.m_currentState; public rSpitter(InfectionSpitter spitter) : base((int)spitter.m_spitterIndex) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) this.spitter = spitter; position = ((Component)spitter).transform.position; rotation = ((Component)spitter).transform.rotation; dimension = (byte)spitter.m_courseNode.m_dimension.DimensionIndex; scale = ((Component)spitter).transform.localScale.x; } public override void Write(ByteBuffer buffer) { //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_000d: Unknown result type (might be due to invalid IL or missing references) _state = state; BitHelper.WriteBytes((byte)_state, buffer); } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); } } [ReplayData("Vanilla.Enemy.Spitter.Explode", "0.0.1")] public class rSpitterExplode : Id { public rSpitterExplode(int id) : base(id) { } } [HarmonyPatch] [ReplayData("Vanilla.Enemy.Spitters", "0.0.1")] public class rSpitters : ReplayHeader { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(InfectionSpitter), "AssignCourseNode")] [HarmonyPostfix] private static void Postfix_Setup(InfectionSpitter __instance) { spitters.Add(__instance.m_spitterIndex, new rSpitter(__instance)); } [HarmonyPatch(typeof(InfectionSpitter), "DoExplode")] [HarmonyPostfix] private static void Postfix_Explode(InfectionSpitter __instance) { Replay.Trigger((ReplayEvent)(object)new rSpitterExplode(__instance.m_spitterIndex)); } } private static Dictionary spitters = new Dictionary(); [ReplayOnElevatorStop] private static void Init() { Replay.Trigger((ReplayHeader)(object)new rSpitters()); foreach (rSpitter value in spitters.Values) { Replay.Spawn((ReplayDynamic)(object)value, true); } spitters.Clear(); } public override void Write(ByteBuffer buffer) { //IL_0043: 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) BitHelper.WriteBytes((ushort)spitters.Count, buffer); foreach (rSpitter value in spitters.Values) { BitHelper.WriteBytes(((ReplayDynamic)value).id, buffer); BitHelper.WriteBytes(value.dimension, buffer); BitHelper.WriteBytes(value.position, buffer); BitHelper.WriteHalf(value.rotation, buffer); BitHelper.WriteHalf(value.scale, buffer); } } } [HarmonyPatch] [ReplayData("Vanilla.Enemy.Tendril", "0.0.1")] public class rEnemyTendril : ReplayDynamic { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(ScoutAntenna), "DetailUpdate")] [HarmonyPostfix] private static void Postfix_Update(ScoutAntenna __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!Replay.Has(((Object)__instance).GetInstanceID()) && (Object)(object)__instance.m_detection != (Object)null && (int)__instance.m_detection.State != 0) { Replay.Spawn((ReplayDynamic)(object)new rEnemyTendril(__instance), true); } } [HarmonyPatch(typeof(ScoutAntenna), "Remove")] [HarmonyPostfix] private static void Postfix_Remove(ScoutAntenna __instance) { int instanceID = ((Object)__instance).GetInstanceID(); if (Replay.Has(instanceID)) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(instanceID), true); } } } private ScoutAntenna tendril; private EnemyAgent owner; private Vector3 _relPos; private Vector3 _sourcePos; private bool _detect; private Vector3 relPos => tendril.m_currentPos - ((Component)owner).transform.position; private Vector3 sourcePos => tendril.m_sourcePos - ((Component)owner).transform.position; private bool detect => (int)tendril.m_state == 2; public override bool Active { get { if ((Object)(object)tendril != (Object)null) { return (Object)(object)owner != (Object)null; } return false; } } public override bool IsDirty { get { //IL_0001: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!(_relPos != relPos)) { return _sourcePos != sourcePos; } return true; } } public rEnemyTendril(ScoutAntenna tendril) : base(((Object)tendril).GetInstanceID()) { owner = tendril.m_detection.m_owner; this.tendril = tendril; } public override void Write(ByteBuffer buffer) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) _sourcePos = sourcePos; BitHelper.WriteHalf(_sourcePos, buffer); _relPos = relPos; BitHelper.WriteHalf(_relPos, buffer); _detect = detect; BitHelper.WriteBytes(_detect, buffer); } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); BitHelper.WriteBytes(((Agent)owner).GlobalID, buffer); } } [HarmonyPatch] internal static class EnemyTongueReplayManager { [HarmonyPatch] private static class Patches { private static MovingEnemyTentacleBase? tongue; [HarmonyPatch(typeof(MovingEnemyTentacleBase), "DoAttack")] [HarmonyPrefix] [HarmonyWrapSafe] private static void Prefix_DoAttack(MovingEnemyTentacleBase __instance) { Spawn(__instance); } [HarmonyPatch(typeof(EnemySync), "OnDespawn")] [HarmonyPostfix] private static void Postfix_OnDespawn(EnemySync __instance) { Despawn(__instance.m_agent); } [HarmonyPatch(typeof(EnemyBehaviour), "ChangeState", new Type[] { typeof(EB_States) })] [HarmonyPrefix] private static void Prefix_Behaviour_ChangeState(EnemyBehaviour __instance, EB_States state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if (__instance.m_currentStateName != state && (int)state == 19) { Despawn(__instance.m_ai.m_enemyAgent); } } [HarmonyPatch(typeof(MovingEnemyTentacleBase), "DeAllocateGPUCurvy")] [HarmonyPostfix] private static void Postfix_Deallocate(MovingEnemyTentacleBase __instance) { Despawn(__instance); } [HarmonyPatch(typeof(MovingEnemyTentacleBase), "OnAttackIsOut")] [HarmonyPrefix] private static void Prefix_OnAttackIsOut(MovingEnemyTentacleBase __instance) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) tongue = __instance; PlayerAgent playerTarget = __instance.PlayerTarget; bool flag = __instance.CheckTargetInAttackTunnel(); if ((Object)(object)playerTarget != (Object)null && ((Dam_SyncedDamageBase)playerTarget.Damage).IsSetup) { bool flag2; if (__instance.m_owner.EnemyBalancingData.UseTentacleTunnelCheck) { flag2 = flag; } else { Vector3 tipPos = __instance.GetTipPos(); Vector3 val = ((Agent)playerTarget).TentacleTarget.position - tipPos; flag2 = ((Vector3)(ref val)).magnitude < __instance.m_owner.EnemyBalancingData.TentacleAttackDamageRadiusIfNoTunnelCheck; } if (!flag2) { Replay.Trigger((ReplayEvent)(object)new rEnemyTongueEvent(__instance)); } } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveTentacleAttackDamage")] [HarmonyPrefix] private static void Prefix_ReceiveTentacleAttackDamage(Dam_PlayerDamageBase __instance, pMediumDamageData data) { if ((Object)(object)tongue != (Object)null) { Replay.Trigger((ReplayEvent)(object)new rEnemyTongueEvent(tongue)); } } } public static Dictionary> tongueOwners = new Dictionary>(); [ReplayInit] private static void Init() { tongueOwners.Clear(); } public static void Spawn(MovingEnemyTentacleBase tongue) { if (Replay.Ready && !Replay.Has(((Object)tongue).GetInstanceID())) { rEnemyTongue rEnemyTongue2 = new rEnemyTongue(tongue); int globalID = ((Agent)tongue.m_owner).GlobalID; if (!tongueOwners.ContainsKey(globalID)) { tongueOwners.Add(globalID, new HashSet()); } tongueOwners[globalID].Add(rEnemyTongue2); Replay.Spawn((ReplayDynamic)(object)rEnemyTongue2, true); } } public static void Despawn(MovingEnemyTentacleBase tongue) { if (!Replay.Ready) { return; } int globalID = ((Agent)tongue.m_owner).GlobalID; if (tongueOwners.ContainsKey(globalID)) { rEnemyTongue rEnemyTongue2 = new rEnemyTongue(tongue); if (tongueOwners[globalID].Remove(rEnemyTongue2)) { Replay.Despawn((ReplayDynamic)(object)rEnemyTongue2, true); } } } public static void Despawn(EnemyAgent enemy) { int globalID = ((Agent)enemy).GlobalID; if (!tongueOwners.ContainsKey(globalID)) { return; } foreach (rEnemyTongue item in tongueOwners[globalID]) { Replay.Despawn((ReplayDynamic)(object)item, true); } tongueOwners.Remove(globalID); } } public class TongueTooLong : Exception { public TongueTooLong(string message) : base(message) { } } [ReplayData("Vanilla.Enemy.TongueEvent", "0.0.1")] internal class rEnemyTongueEvent : Id { private MovingEnemyTentacleBase tongue; public rEnemyTongueEvent(MovingEnemyTentacleBase tongue) : base(((Object)tongue).GetInstanceID()) { this.tongue = tongue; } public override void Write(ByteBuffer buffer) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) ((Id)this).Write(buffer); if (((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length > 255) { throw new TongueTooLong($"Tongue has too many segments: {((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length}."); } BitHelper.WriteBytes((byte)((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length, buffer); BitHelper.WriteBytes(((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments)[0].pos, buffer); for (int i = 1; i < ((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length; i++) { BitHelper.WriteHalf(((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments)[i].pos - ((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments)[i - 1].pos, buffer); } } } [ReplayData("Vanilla.Enemy.Tongue", "0.0.1")] public class rEnemyTongue : ReplayDynamic { private MovingEnemyTentacleBase tongue; public PlayerAgent? target; public bool attackOut; public override bool Active { get { if ((Object)(object)tongue != (Object)null) { return (Object)(object)tongue.m_owner != (Object)null; } return false; } } public override bool IsDirty => ((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length > 0; public rEnemyTongue(MovingEnemyTentacleBase tongue) : base(((Object)tongue).GetInstanceID()) { this.tongue = tongue; if ((Object)(object)tongue.PlayerTarget != (Object)null) { target = tongue.PlayerTarget; } else if (Replay.Has((int)((Agent)tongue.m_owner).GlobalID)) { rEnemy rEnemy2 = Replay.Get((int)((Agent)tongue.m_owner).GlobalID); if ((Object)(object)rEnemy2.targetPlayer != (Object)null) { target = rEnemy2.targetPlayer; } } } public override void Write(ByteBuffer buffer) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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) //IL_00d9: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length > 255) { throw new TongueTooLong($"Tongue has too many segments: {((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length}."); } BitHelper.WriteBytes((byte)((Agent)tongue.m_owner).DimensionIndex, buffer); BitHelper.WriteBytes((byte)(Mathf.Clamp01(tongue.TentacleRelLen) * 255f), buffer); BitHelper.WriteBytes((byte)((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length, buffer); BitHelper.WriteBytes(((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments)[0].pos, buffer); for (int i = 1; i < ((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments).Length; i++) { BitHelper.WriteHalf(((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments)[i].pos - ((Il2CppArrayBase)(object)tongue.m_GPUSplineSegments)[i - 1].pos, buffer); } } public override void Spawn(ByteBuffer buffer) { BitHelper.WriteBytes(((Agent)tongue.m_owner).GlobalID, buffer); ((ReplayDynamic)this).Write(buffer); } } } namespace Vanilla.DynamicItems { internal struct FogSphereTransform : IReplayTransform { private FogRepeller_Sphere sphere; private byte dimension; public bool active => (Object)(object)sphere != (Object)null; public byte dimensionIndex => dimension; public Vector3 position => ((Component)sphere).transform.position; public Quaternion rotation => ((Component)sphere).transform.rotation; public FogSphereTransform(FogRepeller_Sphere sphere, byte dimension) { this.sphere = sphere; this.dimension = dimension; } } [HarmonyPatch] [ReplayData("Vanilla.FogSphere", "0.0.1")] public class rFogSphere : DynamicPosition { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(FogRepeller_Sphere), "StartRepelling")] [HarmonyPostfix] private static void SpawnFogSphere(FogRepeller_Sphere __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)__instance).GetInstanceID(); if (Replay.Has(instanceID)) { rFogSphere rFogSphere2 = Replay.Get(instanceID); ((DynamicPosition)rFogSphere2).transform = (IReplayTransform)(object)new FogSphereTransform(__instance, ((DynamicPosition)rFogSphere2).transform.dimensionIndex); } else { Replay.Spawn((ReplayDynamic)(object)new rFogSphere(__instance, (byte)Dimension.GetDimensionFromPos(((Component)__instance).transform.position).DimensionIndex), true); } } [HarmonyPatch(typeof(FogRepeller_Sphere), "OnDestroy")] [HarmonyPrefix] private static void OnDestroy(FogRepeller_Sphere __instance) { Replay.TryDespawn(((Object)__instance).GetInstanceID()); } } private FogRepeller_Sphere sphere; private float _range; public override bool IsDirty { get { if (!((DynamicPosition)this).IsDirty) { return _range != range; } return true; } } private float range => sphere.m_currentRange; public rFogSphere(FogRepeller_Sphere sphere, byte dimension) : base(((Object)sphere).GetInstanceID(), (IReplayTransform)(object)new FogSphereTransform(sphere, dimension)) { this.sphere = sphere; } private void _Write(ByteBuffer buffer) { BitHelper.WriteHalf(range, buffer); _range = range; } public override void Write(ByteBuffer buffer) { ((DynamicPosition)this).Write(buffer); _Write(buffer); } public override void Spawn(ByteBuffer buffer) { ((DynamicPosition)this).Spawn(buffer); _Write(buffer); } } internal struct ItemTransform : IReplayTransform { private Item item; private byte dimension; public bool active => (Object)(object)item != (Object)null; public byte dimensionIndex => dimension; public Vector3 position => ((Component)item).transform.position; public Quaternion rotation => ((Component)item).transform.rotation; public ItemTransform(Item item, byte dimension) { this.item = item; this.dimension = dimension; } } [HarmonyPatch] [ReplayData("Vanilla.DynamicItem", "0.0.1")] public class rDynamicItem : DynamicTransform { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(ItemReplicationManager), "OnItemSpawn")] [HarmonyPostfix] private static void OnItemSpawn(ItemReplicationManager __instance, pItemSpawnData spawnData, ItemReplicator replicator) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (Replay.Active) { Item item = replicator.Item; Replay.Spawn((ReplayDynamic)(object)new rDynamicItem(dimension: (byte)Dimension.GetDimensionFromPos(spawnData.position).DimensionIndex, item: item, type: Identifier.From(item)), true); } } } private Item item; private Identifier type; public override bool IsDirty => ((DynamicTransform)this).IsDirty; public rDynamicItem(Item item, Identifier type, byte dimension) : base(((Object)((Component)item).gameObject).GetInstanceID(), (IReplayTransform)(object)new ItemTransform(item, dimension)) { this.item = item; this.type = type; } public override void Spawn(ByteBuffer buffer) { ((DynamicTransform)this).Spawn(buffer); BitHelper.WriteBytes((BufferWriteable)(object)type, buffer); } } } namespace Vanilla.Chat { [HarmonyPatch] internal class Chat { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(PUI_GameEventLog), "AddLogItem")] [HarmonyPrefix] private static void ReceivedMessage() { } } } } namespace Vanilla.ChainedPuzzles { [HarmonyPatch] public class rBioFake { [HarmonyPatch] private class Patches { } } internal struct BioscanTransform : IReplayTransform { private CP_Bioscan_Core bioscan; private byte _dimensionIndex; public bool active => (Object)(object)bioscan != (Object)null; public byte dimensionIndex => _dimensionIndex; public Vector3 position => ((Component)bioscan).transform.position; public Quaternion rotation => Quaternion.identity; public BioscanTransform(CP_Bioscan_Core bioscan) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) this.bioscan = bioscan; object obj; if (bioscan == null) { obj = null; } else { AIG_CourseNode courseNode = bioscan.m_courseNode; obj = ((courseNode != null) ? courseNode.m_dimension : null); } if (obj != null) { _dimensionIndex = (byte)bioscan.m_courseNode.m_dimension.DimensionIndex; return; } APILogger.Warn("Failed to get bioscan dimension, falling back to local player's dimension."); _dimensionIndex = (byte)((Agent)PlayerManager.GetLocalPlayerAgent()).DimensionIndex; } } [HarmonyPatch] [ReplayData("Vanilla.Bioscan", "0.0.1")] public class rBioscan : DynamicPosition { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(CP_Bioscan_Core), "OnSyncStateChange")] [HarmonyPostfix] private static void Postfix_Bioscan_SetState(CP_Bioscan_Core __instance, eBioscanStatus status, float progress, List playersInScan, int playersMax, bool[] reqItemStatus, bool isDropinState) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected I4, but got Unknown CP_PlayerScanner val = ((Il2CppObjectBase)__instance.m_playerScanner).TryCast(); if ((Object)(object)val == (Object)null) { APILogger.Error("Unable to find pscanner component for bioscan."); return; } int instanceID = ((Object)__instance).GetInstanceID(); switch ((int)status) { case 2: case 3: if (!Replay.Has(instanceID)) { Replay.Spawn((ReplayDynamic)(object)new rBioscan(__instance, val.m_scanRadius), true); } if (!Replay.Has(instanceID)) { Replay.Spawn((ReplayDynamic)(object)new rBioscanStatus(__instance), true); } break; case 0: case 1: case 4: case 5: if (Replay.Has(instanceID)) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(instanceID), true); } if (Replay.Has(instanceID)) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(instanceID), true); } break; } } } private CP_Bioscan_Core bioscan; private float radius; public rBioscan(CP_Bioscan_Core bioscan, float radius) : base(((Object)bioscan).GetInstanceID(), (IReplayTransform)(object)new BioscanTransform(bioscan)) { this.bioscan = bioscan; this.radius = radius; } public override void Spawn(ByteBuffer buffer) { ((DynamicPosition)this).Spawn(buffer); BitHelper.WriteHalf(radius, buffer); } } [ReplayData("Vanilla.Bioscan.Status", "0.0.1")] public class rBioscanStatus : ReplayDynamic { private CP_Bioscan_Core bioscan; private CP_Bioscan_Graphics graphics; private byte oldProgress; private byte oldR; private byte oldG; private byte oldB; public override bool Active => (Object)(object)bioscan != (Object)null; public override bool IsDirty { get { if (progress == oldProgress && r == oldR && g == oldG) { return b != oldB; } return true; } } private byte progress => (byte)(bioscan.m_sync.GetCurrentState().progress * 255f); private byte r => (byte)(graphics.m_currentCol.r * 255f); private byte g => (byte)(graphics.m_currentCol.g * 255f); private byte b => (byte)(graphics.m_currentCol.b * 255f); public rBioscanStatus(CP_Bioscan_Core bioscan) : base(((Object)bioscan).GetInstanceID()) { this.bioscan = bioscan; graphics = ((Il2CppObjectBase)bioscan.m_graphics).TryCast(); } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes(progress, buffer); BitHelper.WriteBytes(r, buffer); BitHelper.WriteBytes(g, buffer); BitHelper.WriteBytes(b, buffer); oldProgress = progress; oldR = r; oldG = g; oldB = b; } public override void Spawn(ByteBuffer buffer) { ((ReplayDynamic)this).Write(buffer); } } public class HolopathTooLong : Exception { public HolopathTooLong(string message) : base(message) { } } [HarmonyPatch] [ReplayData("Vanilla.Holopath", "0.0.1")] public class rHolopath : ReplayDynamic { [HarmonyPatch] private static class Patches { private static Dictionary splineDimensions = new Dictionary(); [ReplayInit] private static void Init() { splineDimensions.Clear(); } private static void RegisterSplineDimension(int instance, byte dimension) { if (!splineDimensions.ContainsKey(instance)) { splineDimensions.Add(instance, dimension); } } [HarmonyPatch(typeof(CP_Hack_Core), "Setup")] [HarmonyPostfix] private static void Postfix_CP_Hack_Core_Setup(CP_Hack_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, LG_Area sourceArea) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) CP_Holopath_Spline val = ((Il2CppObjectBase)__instance.m_spline).TryCast(); if (!((Object)(object)val == (Object)null)) { byte dimension = (byte)sourceArea.m_courseNode.m_dimension.DimensionIndex; RegisterSplineDimension(((Object)val).GetInstanceID(), dimension); } } [HarmonyPatch(typeof(CP_Cluster_Core), "Setup")] [HarmonyPostfix] private static void Postfix_CP_Cluster_Core_Setup(CP_Cluster_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, LG_Area sourceArea) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) CP_Holopath_Spline val = ((Il2CppObjectBase)__instance.m_spline).TryCast(); if (!((Object)(object)val == (Object)null)) { byte dimension = (byte)sourceArea.m_courseNode.m_dimension.DimensionIndex; RegisterSplineDimension(((Object)val).GetInstanceID(), dimension); } } [HarmonyPatch(typeof(CP_Bioscan_Core), "Setup")] [HarmonyPostfix] private static void Postfix_CP_Bioscan_Core_Setup(CP_Bioscan_Core __instance, int puzzleIndex, iChainedPuzzleOwner owner, LG_Area sourceArea) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) CP_Holopath_Spline val = ((Il2CppObjectBase)__instance.m_spline).TryCast(); if (!((Object)(object)val == (Object)null)) { byte dimension = (byte)sourceArea.m_courseNode.m_dimension.DimensionIndex; RegisterSplineDimension(((Object)val).GetInstanceID(), dimension); } } [HarmonyPatch(typeof(LG_BulkheadDoorController_Core), "BuildBulkheadLogic")] [HarmonyPostfix] private static void Postfix_LG_BulkheadDoorController_Core(LG_BulkheadDoorController_Core __instance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) byte dimension = (byte)__instance.SpawnNode.m_dimension.DimensionIndex; Enumerator enumerator = __instance.m_bulkheadDoorSplines.Values.GetEnumerator(); while (enumerator.MoveNext()) { CP_Holopath_Spline val = ((Il2CppObjectBase)enumerator.Current).TryCast(); if ((Object)(object)val == (Object)null) { break; } RegisterSplineDimension(((Object)val).GetInstanceID(), dimension); } } private static void SpawnHolopath(CP_Holopath_Spline holopath) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)holopath.CurvySpline == (Object)null) && holopath.CurvySpline.Length != 0f) { int instanceID = ((Object)holopath).GetInstanceID(); if (!Replay.Has(instanceID)) { byte dimension = ((!splineDimensions.ContainsKey(instanceID)) ? ((byte)Dimension.GetDimensionFromPos(((Component)holopath).transform.position).DimensionIndex) : splineDimensions[instanceID]); Replay.Spawn((ReplayDynamic)(object)new rHolopath(holopath, dimension), true); } } } [HarmonyPatch(typeof(CP_Holopath_Spline), "Reveal")] [HarmonyPostfix] private static void Postfix_CP_Holopath_Reveal(CP_Holopath_Spline __instance) { SpawnHolopath(__instance); } [HarmonyPatch(typeof(CP_Holopath_Spline), "SetVisible")] [HarmonyPostfix] private static void Postfix_CP_Holopath_Visible(CP_Holopath_Spline __instance, bool vis) { int instanceID = ((Object)__instance).GetInstanceID(); if (!vis && Replay.Has(instanceID)) { Replay.Despawn((ReplayDynamic)(object)Replay.Get(instanceID), true); } else { SpawnHolopath(__instance); } } } private CP_Holopath_Spline holopath; private float oldProgress; private byte dimension; public override bool Active => (Object)(object)holopath != (Object)null; public override bool IsDirty => (float)(int)progress != oldProgress; private byte progress => (byte)(holopath.CurvyExtrusion.To * 255f); public rHolopath(CP_Holopath_Spline holopath, byte dimension) : base(((Object)holopath).GetInstanceID()) { this.holopath = holopath; this.dimension = dimension; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes(progress, buffer); oldProgress = (int)progress; } public override void Spawn(ByteBuffer buffer) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) int count = holopath.CurvySpline.controlPoints.Count; if (count > 255) { throw new HolopathTooLong($"Holopath has too many segments: {count}."); } BitHelper.WriteBytes(dimension, buffer); BitHelper.WriteBytes((byte)count, buffer); BitHelper.WriteBytes(((Component)holopath.CurvySpline.controlPoints[0]).transform.position, buffer); for (int i = 1; i < count; i++) { BitHelper.WriteHalf(((Component)holopath.CurvySpline.controlPoints[i]).transform.position - ((Component)holopath.CurvySpline.controlPoints[i - 1]).transform.position, buffer); } } } } namespace Vanilla.Cfoam { internal struct CfoamTransform : IReplayTransform { private GlueGunProjectile projectile; private byte dimension; public bool active => (Object)(object)projectile != (Object)null; public byte dimensionIndex => dimension; public Vector3 position => ((Component)projectile).transform.position; public Quaternion rotation => ((Component)projectile).transform.rotation; public CfoamTransform(GlueGunProjectile projectile, byte dimension) { this.projectile = projectile; this.dimension = dimension; } } [HarmonyPatch] [ReplayData("Vanilla.Cfoam", "0.0.1")] public class rCfoam : DynamicPosition { [HarmonyPatch] private static class Patches { [HarmonyPatch(typeof(ProjectileManager), "SpawnGlueGunProjectileIfNeeded")] [HarmonyPostfix] private static void SpawnGlueGunProjectile(ProjectileManager __instance, GlueGunProjectile __result) { //IL_004a: 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) if (!((Object)(object)__result == (Object)null)) { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); SNet_Player val = default(SNet_Player); byte dimension; if (SNetUtils.TryGetSender((SNet_Packet)(object)((SNet_SyncedAction)(object)__instance.m_fireGlue).m_packet, ref val) && val.PlayerAgent != null) { dimension = (byte)((Agent)((Il2CppObjectBase)val.PlayerAgent).Cast()).DimensionIndex; } else if ((Object)(object)localPlayerAgent != (Object)null) { dimension = (byte)((Agent)localPlayerAgent).DimensionIndex; } else { dimension = 0; APILogger.Error("Could not get dimension of cfoam blob."); } int instanceID = ((Object)__result).GetInstanceID(); if (Replay.Has(instanceID)) { rCfoam rCfoam2 = Replay.Get(instanceID); ((DynamicPosition)rCfoam2).transform = (IReplayTransform)(object)new CfoamTransform(__result, ((DynamicPosition)rCfoam2).transform.dimensionIndex); } else { Replay.Spawn((ReplayDynamic)(object)new rCfoam(__result, dimension), true); } } } [HarmonyPatch(typeof(GlueGunProjectile), "Update")] [HarmonyPostfix] private static void CheckGlueWithinBounds(GlueGunProjectile __instance) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (Replay.Active && !__instance.m_landed && !__instance.m_landedOnEnemy && Replay.Has(((Object)__instance).GetInstanceID())) { rCfoam rCfoam2 = Replay.Get(((Object)__instance).GetInstanceID()); byte dimensionIndex = ((DynamicPosition)rCfoam2).transform.dimensionIndex; if (MapUtils.lowestPoint.ContainsKey(dimensionIndex) && ((Component)__instance).transform.position.y < MapUtils.lowestPoint[dimensionIndex]) { APILogger.Debug("Removed foam since it fell too far."); Replay.Despawn((ReplayDynamic)(object)rCfoam2, true); } } } [HarmonyPatch(typeof(ProjectileManager), "DoDestroyGlue")] [HarmonyPrefix] private static void DoDestroyGlue(pDestroyGlue data) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (ProjectileManager.Current.m_glueGunProjectiles.ContainsKey(data.syncID)) { Replay.TryDespawn(((Object)ProjectileManager.Current.m_glueGunProjectiles[data.syncID]).GetInstanceID()); } } } private GlueGunProjectile projectile; private float oldScale; public override bool IsDirty { get { if (!((DynamicPosition)this).IsDirty) { return oldScale != scale; } return true; } } private float scale => ((Component)projectile).transform.localScale.x; public rCfoam(GlueGunProjectile projectile, byte dimension) : base(((Object)projectile).GetInstanceID(), (IReplayTransform)(object)new CfoamTransform(projectile, dimension)) { this.projectile = projectile; } public override void Write(ByteBuffer buffer) { ((DynamicPosition)this).Write(buffer); BitHelper.WriteHalf(scale, buffer); oldScale = scale; } public override void Spawn(ByteBuffer buffer) { ((DynamicPosition)this).Spawn(buffer); BitHelper.WriteHalf(scale, buffer); oldScale = scale; } } }