using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using DM;
using HarmonyLib;
using Landfall.TABS;
using Landfall.TABS.AI;
using Landfall.TABS.AI.Components.Modifiers;
using Landfall.TABS.AI.Components.Tags;
using Landfall.TABS.AI.Systems;
using Landfall.TABS.GameMode;
using Landfall.TABS.Services;
using Landfall.TABS.UnitPlacement;
using Landfall.TABS.WinConditions;
using Landfall.TABS.Workshop;
using Microsoft.CodeAnalysis;
using Unity.Entities;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SCP173Mod
{
public static class DummyUnitFactory
{
public const string FactionName = "Scp-173";
public const string UnitName = "SCP-173";
private static readonly FieldInfo s_unitBlueprintEntityField = typeof(UnitBlueprint).GetField("m_entity", BindingFlags.Instance | BindingFlags.NonPublic);
public static Faction BuiltFaction { get; private set; }
public static UnitBlueprint BuiltBlueprint { get; private set; }
public static void BuildAndRegister()
{
//IL_002f: 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)
ContentDatabase val = ContentDatabase.Instance();
if (val == null)
{
return;
}
if ((Object)(object)BuiltFaction != (Object)null && (Object)(object)BuiltBlueprint != (Object)null)
{
Faction faction = val.GetFaction(BuiltFaction.Entity.GUID);
UnitBlueprint unitBlueprint = val.GetUnitBlueprint(BuiltBlueprint.Entity.GUID);
if (!((Object)(object)faction == (Object)(object)BuiltFaction) || !((Object)(object)unitBlueprint == (Object)(object)BuiltBlueprint))
{
if ((Object)(object)unitBlueprint == (Object)null)
{
val.AddUserUnitBlueprint(BuiltBlueprint);
}
if ((Object)(object)faction == (Object)null)
{
val.AddUserFaction(BuiltFaction);
}
}
}
else
{
GameObject val2 = FindTemplateUnitBase();
if (!((Object)(object)val2 == (Object)null))
{
BuiltBlueprint = CreateBlueprint(val2);
BuiltFaction = CreateFaction(BuiltBlueprint);
val.AddUserUnitBlueprint(BuiltBlueprint);
val.AddUserFaction(BuiltFaction);
}
}
}
public static bool IsDummy(Unit unit)
{
if ((Object)(object)unit != (Object)null && (Object)(object)BuiltBlueprint != (Object)null)
{
return unit.unitBlueprint == BuiltBlueprint;
}
return false;
}
private static GameObject FindTemplateUnitBase()
{
ContentDatabase val = ContentDatabase.Instance();
string[] array = new string[4] { "Farmer", "Peasant", "Peon", "Warrior" };
foreach (string name in array)
{
UnitBlueprint val2 = val.GetAllFactions().SelectMany((Faction f) => f.Units).FirstOrDefault((Func<UnitBlueprint, bool>)((UnitBlueprint u) => (Object)(object)u != (Object)null && u.Entity != null && u.Entity.Name == name));
if ((Object)(object)val2 != (Object)null && (Object)(object)val2.UnitBase != (Object)null)
{
return val2.UnitBase;
}
}
UnitBlueprint val3 = (from f in val.GetAllFactions()
where !f.IsSecret
select f).SelectMany((Faction f) => f.Units).FirstOrDefault((Func<UnitBlueprint, bool>)((UnitBlueprint u) => (Object)(object)u != (Object)null && (Object)(object)u.UnitBase != (Object)null && !u.HasMissingComponents));
if (!((Object)(object)val3 != (Object)null))
{
return null;
}
return val3.UnitBase;
}
private static void InitUnitBlueprintEntity(UnitBlueprint bp, string entityName)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
DatabaseEntity val = new DatabaseEntity((WorkshopContentType)0);
val.Name = entityName;
s_unitBlueprintEntityField.SetValue(bp, val);
}
private static UnitBlueprint CreateBlueprint(GameObject templateUnitBase)
{
//IL_0065: 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_007e: 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)
UnitBlueprint val = ScriptableObject.CreateInstance<UnitBlueprint>();
((Object)val).name = "SCP-173";
InitUnitBlueprintEntity(val, "SCP-173");
GameObject val2 = CloneTemplateInactive(templateUnitBase);
RemoveTeamColorComponents(val2);
val.UnitBase = val2;
val.RightWeapon = null;
val.LeftWeapon = null;
Unit component = val2.GetComponent<Unit>();
if ((Object)(object)component != (Object)null)
{
component.unitBlueprint = val;
}
val.excludeFromWinCondition = true;
val.MovementComponents = new List<IMovementComponent> { (IMovementComponent)(object)default(KeepPreferredDistance) };
val.TargetingComponent = (ITargetingComponent)(object)default(EnemyLeastWeightTargeting);
val.turnSpeed = 18f;
val.turnSpeedCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);
return val;
}
private static GameObject CloneTemplateInactive(GameObject template)
{
bool activeSelf = template.activeSelf;
if (activeSelf)
{
template.SetActive(false);
}
GameObject obj = Object.Instantiate<GameObject>(template);
((Object)obj).name = "SCP173_Dummy";
obj.SetActive(false);
Object.DontDestroyOnLoad((Object)(object)obj);
if (activeSelf)
{
template.SetActive(true);
}
return obj;
}
private static void RemoveTeamColorComponents(GameObject root)
{
if ((Object)(object)root == (Object)null)
{
return;
}
TeamColor[] componentsInChildren = root.GetComponentsInChildren<TeamColor>(true);
foreach (TeamColor val in componentsInChildren)
{
if ((Object)(object)val != (Object)null)
{
Object.DestroyImmediate((Object)(object)val);
}
}
}
private static void InitFactionEntity(Faction faction)
{
faction.Init();
faction.Entity.Name = "Scp-173";
}
private static Faction CreateFaction(UnitBlueprint blueprint)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
Faction val = ScriptableObject.CreateInstance<Faction>();
((Object)val).name = "Scp-173";
InitFactionEntity(val);
val.IsCustom = true;
val.m_displayFaction = true;
val.m_FactionCatagory = (FactionCatagory)1;
val.Units = (UnitBlueprint[])(object)new UnitBlueprint[1] { blueprint };
return val;
}
}
internal static class EmbeddedAssetLoader
{
private static readonly Assembly ModAssembly = typeof(EmbeddedAssetLoader).Assembly;
private static readonly object Gate = new object();
private static string CacheRoot;
private static readonly Dictionary<string, string> Extracted = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private static Dictionary<string, string> ResourceMap;
internal static void InitializeCache()
{
if (CacheRoot == null)
{
CacheRoot = Path.Combine(Path.GetTempPath(), "SCP173Mod_Embedded", "Assets");
Directory.CreateDirectory(CacheRoot);
BuildResourceMap();
}
}
internal static byte[] LoadBytes(string fileName)
{
string text = FindResource(fileName);
if (text == null)
{
return null;
}
using Stream stream = ModAssembly.GetManifestResourceStream(text);
if (stream == null)
{
return null;
}
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
internal static string LoadText(string fileName)
{
byte[] array = LoadBytes(fileName);
if (array != null)
{
return Encoding.UTF8.GetString(array);
}
return null;
}
internal static bool ExtractAllEmbeddedAssets()
{
InitializeCache();
bool result = true;
string[] manifestResourceNames = ModAssembly.GetManifestResourceNames();
foreach (string text in manifestResourceNames)
{
if (text.StartsWith("SCP173Mod.Assets.", StringComparison.OrdinalIgnoreCase))
{
string fileName = text.Substring("SCP173Mod.Assets.".Length);
if (ExtractResource(text, fileName) == null)
{
result = false;
}
}
}
return result;
}
internal static string ExtractToTemp(string fileName)
{
InitializeCache();
if (Extracted.TryGetValue(fileName, out var value) && File.Exists(value))
{
return value;
}
string text = FindResource(fileName);
if (text == null)
{
return null;
}
return ExtractResource(text, Path.GetFileName(fileName));
}
internal static string GetCachedPath(string fileName)
{
return ExtractToTemp(fileName);
}
private static void BuildResourceMap()
{
lock (Gate)
{
if (ResourceMap == null)
{
ResourceMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
string[] manifestResourceNames = ModAssembly.GetManifestResourceNames();
for (int i = 0; i < manifestResourceNames.Length; i++)
{
string key = manifestResourceNames[i].Replace('/', '.').Replace('\\', '.');
ResourceMap[key] = manifestResourceNames[i];
}
}
}
}
private static string FindResource(string fileName)
{
InitializeCache();
string text = fileName.Replace('\\', '.').Replace('/', '.');
if (text.StartsWith(".", StringComparison.Ordinal))
{
text = text.TrimStart(new char[1] { '.' });
}
if (ResourceMap.TryGetValue(text, out var value))
{
return value;
}
string value2 = "." + text;
foreach (KeyValuePair<string, string> item in ResourceMap)
{
if (item.Key.EndsWith(value2, StringComparison.OrdinalIgnoreCase))
{
return item.Value;
}
}
return null;
}
private static string ExtractResource(string resourceName, string fileName)
{
try
{
string fileName2 = Path.GetFileName(fileName);
string text = Path.Combine(CacheRoot, fileName2);
using (Stream stream = ModAssembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
return null;
}
using FileStream destination = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.Read);
stream.CopyTo(destination);
}
Extracted[fileName] = text;
return text;
}
catch
{
return null;
}
}
}
[HarmonyPatch(typeof(Unit), "Start")]
public static class Unit_Start_Patch
{
[HarmonyPostfix]
public static void Postfix(Unit __instance)
{
SCP173SpawnReplacer.ReplaceIfDummy(__instance);
if ((Object)(object)__instance != (Object)null && !SCP173Runtime.IsReferenceProxy(__instance))
{
UnitRegistry.Register(__instance);
}
}
}
[HarmonyPatch(typeof(Unit), "OnDestroy")]
public static class Unit_OnDestroy_Patch
{
[HarmonyPostfix]
public static void Postfix(Unit __instance)
{
if (!SCP173Runtime.IsReferenceProxy(__instance))
{
UnitRegistry.Unregister(__instance);
}
}
}
[HarmonyPatch(typeof(CustomContentLoaderModIO), "DoneDownloading")]
public static class CustomContentLoaderModIO_DoneDownloading_Patch
{
[HarmonyPostfix]
public static void Postfix()
{
DummyUnitFactory.BuildAndRegister();
}
}
[HarmonyPatch(typeof(UnitPlacementBrush), "PlaceUnitInternal")]
public static class UnitPlacementBrush_PlaceUnitInternal_Patch
{
[HarmonyPrefix]
public static bool Prefix(UnitBlueprint blueprint)
{
if ((Object)(object)blueprint == (Object)null || (Object)(object)DummyUnitFactory.BuiltBlueprint == (Object)null)
{
return true;
}
if (blueprint != DummyUnitFactory.BuiltBlueprint)
{
return true;
}
if (!SCP173Runtime.HasSpawned)
{
return !SCP173Runtime.SpawnInProgress;
}
return false;
}
}
public static class SceneResetHook
{
public static void Install()
{
SceneManager.activeSceneChanged -= OnChanged;
SceneManager.activeSceneChanged += OnChanged;
}
private static void OnChanged(Scene oldScene, Scene newScene)
{
SCP173Runtime.ResetSceneState();
}
}
public static class NeckSnapDeformer
{
public static void SnapNeck(Unit victim, float angleDegrees)
{
//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_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: 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_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: 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_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: 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_00fe: 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_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)victim == (Object)null || (Object)(object)victim.data == (Object)null)
{
return;
}
Transform head = victim.Head;
Transform torso = victim.data.torso;
if ((Object)(object)head == (Object)null || (Object)(object)torso == (Object)null)
{
return;
}
Vector3 right = torso.right;
Quaternion val = Quaternion.AngleAxis(angleDegrees, right);
head.rotation = val * head.rotation;
Rigidbody component = ((Component)head).GetComponent<Rigidbody>();
Rigidbody component2 = ((Component)torso).GetComponent<Rigidbody>();
if ((Object)(object)component != (Object)null)
{
component.angularVelocity = right * (angleDegrees * ((float)Math.PI / 180f)) * 6f;
if ((Object)(object)component2 != (Object)null)
{
Vector3 val2 = component2.position - component.position;
component.AddForce(((Vector3)(ref val2)).normalized * 2.5f, (ForceMode)2);
}
}
ConfigurableJoint val3 = ((Component)head).GetComponent<ConfigurableJoint>();
if ((Object)(object)val3 == (Object)null && (Object)(object)torso != (Object)null)
{
val3 = ((Component)torso).GetComponentInChildren<ConfigurableJoint>();
}
if ((Object)(object)val3 != (Object)null)
{
JointDrive val4 = default(JointDrive);
((JointDrive)(ref val4)).positionSpring = 0f;
((JointDrive)(ref val4)).positionDamper = 0f;
((JointDrive)(ref val4)).maximumForce = 0f;
JointDrive angularYZDrive = (val3.angularXDrive = val4);
val3.angularYZDrive = angularYZDrive;
}
}
}
public static class ObjRuntimeLoader
{
public static Mesh LoadMesh(string objPath)
{
//IL_0256: Unknown result type (might be due to invalid IL or missing references)
//IL_025d: Expected O, but got Unknown
//IL_00d5: 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_012e: Unknown result type (might be due to invalid IL or missing references)
if (!File.Exists(objPath))
{
return null;
}
List<Vector3> list = new List<Vector3>();
List<Vector2> list2 = new List<Vector2>();
List<Vector3> list3 = new List<Vector3>();
List<Vector3> list4 = new List<Vector3>();
List<Vector2> list5 = new List<Vector2>();
List<Vector3> list6 = new List<Vector3>();
List<int> list7 = new List<int>();
Dictionary<string, int> cache = new Dictionary<string, int>();
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
foreach (string item in File.ReadLines(objPath))
{
if (string.IsNullOrEmpty(item))
{
continue;
}
string text = item.Trim();
if (text.Length == 0 || text[0] == '#')
{
continue;
}
if (text.StartsWith("v "))
{
string[] array = SplitWhitespace(text.Substring(2));
float num = float.Parse(array[0], invariantCulture);
float num2 = float.Parse(array[1], invariantCulture);
float num3 = float.Parse(array[2], invariantCulture);
list.Add(new Vector3(num, num2, num3));
}
else if (text.StartsWith("vt "))
{
string[] array2 = SplitWhitespace(text.Substring(3));
float num4 = float.Parse(array2[0], invariantCulture);
float num5 = ((array2.Length > 1) ? float.Parse(array2[1], invariantCulture) : 0f);
list2.Add(new Vector2(num4, num5));
}
else if (text.StartsWith("vn "))
{
string[] array3 = SplitWhitespace(text.Substring(3));
float num6 = float.Parse(array3[0], invariantCulture);
float num7 = float.Parse(array3[1], invariantCulture);
float num8 = float.Parse(array3[2], invariantCulture);
list3.Add(new Vector3(num6, num7, num8));
}
else
{
if (!text.StartsWith("f "))
{
continue;
}
string[] array4 = SplitWhitespace(text.Substring(2));
if (array4.Length >= 3)
{
int[] array5 = new int[array4.Length];
for (int i = 0; i < array4.Length; i++)
{
array5[i] = ResolveVertex(array4[i], list, list2, list3, list4, list5, list6, cache);
}
for (int j = 1; j < array5.Length - 1; j++)
{
list7.Add(array5[0]);
list7.Add(array5[j]);
list7.Add(array5[j + 1]);
}
}
}
}
if (list4.Count == 0 || list7.Count == 0)
{
return null;
}
Mesh val = new Mesh();
((Object)val).name = "SCP173_Mesh";
val.indexFormat = (IndexFormat)(list4.Count > 65000);
val.SetVertices(list4);
if (list5.Count == list4.Count)
{
val.SetUVs(0, list5);
}
if (list6.Count == list4.Count)
{
val.SetNormals(list6);
}
val.SetTriangles(list7, 0);
if (list6.Count != list4.Count)
{
val.RecalculateNormals();
}
val.RecalculateBounds();
val.RecalculateTangents();
return val;
}
private static int ResolveVertex(string token, List<Vector3> positions, List<Vector2> uvs, List<Vector3> normals, List<Vector3> finalVerts, List<Vector2> finalUVs, List<Vector3> finalNormals, Dictionary<string, int> cache)
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
if (cache.TryGetValue(token, out var value))
{
return value;
}
string[] array = token.Split(new char[1] { '/' });
int index = ParseIndex(array[0], positions.Count);
int num = ((array.Length > 1 && array[1].Length > 0) ? ParseIndex(array[1], uvs.Count) : (-1));
int num2 = ((array.Length > 2 && array[2].Length > 0) ? ParseIndex(array[2], normals.Count) : (-1));
finalVerts.Add(positions[index]);
finalUVs.Add((num >= 0) ? uvs[num] : Vector2.zero);
finalNormals.Add((num2 >= 0) ? normals[num2] : Vector3.zero);
return cache[token] = finalVerts.Count - 1;
}
private static int ParseIndex(string s, int count)
{
int num = int.Parse(s, CultureInfo.InvariantCulture);
if (num > 0)
{
return num - 1;
}
return count + num;
}
private static string[] SplitWhitespace(string s)
{
return s.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
}
public static Mesh LoadMeshFromText(string objText)
{
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Expected O, but got Unknown
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrEmpty(objText))
{
return null;
}
List<Vector3> list = new List<Vector3>();
List<Vector2> list2 = new List<Vector2>();
List<Vector3> list3 = new List<Vector3>();
List<Vector3> list4 = new List<Vector3>();
List<Vector2> list5 = new List<Vector2>();
List<Vector3> list6 = new List<Vector3>();
List<int> list7 = new List<int>();
Dictionary<string, int> cache = new Dictionary<string, int>();
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
using (StringReader stringReader = new StringReader(objText))
{
string text;
while ((text = stringReader.ReadLine()) != null)
{
string text2 = text.Trim();
if (text2.Length == 0 || text2[0] == '#')
{
continue;
}
if (text2.StartsWith("v "))
{
string[] array = SplitWhitespace(text2.Substring(2));
list.Add(new Vector3(float.Parse(array[0], invariantCulture), float.Parse(array[1], invariantCulture), float.Parse(array[2], invariantCulture)));
}
else if (text2.StartsWith("vt "))
{
string[] array2 = SplitWhitespace(text2.Substring(3));
list2.Add(new Vector2(float.Parse(array2[0], invariantCulture), (array2.Length > 1) ? float.Parse(array2[1], invariantCulture) : 0f));
}
else if (text2.StartsWith("vn "))
{
string[] array3 = SplitWhitespace(text2.Substring(3));
list3.Add(new Vector3(float.Parse(array3[0], invariantCulture), float.Parse(array3[1], invariantCulture), float.Parse(array3[2], invariantCulture)));
}
else
{
if (!text2.StartsWith("f "))
{
continue;
}
string[] array4 = SplitWhitespace(text2.Substring(2));
if (array4.Length >= 3)
{
int[] array5 = new int[array4.Length];
for (int i = 0; i < array4.Length; i++)
{
array5[i] = ResolveVertex(array4[i], list, list2, list3, list4, list5, list6, cache);
}
for (int j = 1; j < array5.Length - 1; j++)
{
list7.Add(array5[0]);
list7.Add(array5[j]);
list7.Add(array5[j + 1]);
}
}
}
}
}
if (list4.Count == 0 || list7.Count == 0)
{
return null;
}
Mesh val = new Mesh();
((Object)val).name = "SCP173_Mesh";
val.indexFormat = (IndexFormat)(list4.Count > 65000);
val.SetVertices(list4);
if (list5.Count == list4.Count)
{
val.SetUVs(0, list5);
}
if (list6.Count == list4.Count)
{
val.SetNormals(list6);
}
else
{
val.RecalculateNormals();
}
val.SetTriangles(list7, 0);
val.RecalculateBounds();
val.RecalculateTangents();
return val;
}
public static Texture2D LoadTextureBytes(byte[] bytes, string name)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
if (bytes == null || bytes.Length == 0)
{
return null;
}
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
if (!ImageConversion.LoadImage(val, bytes))
{
return null;
}
((Object)val).name = name;
((Texture)val).wrapMode = (TextureWrapMode)0;
val.Apply(true, false);
return val;
}
public static Texture2D LoadTexture(string path)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
if (!File.Exists(path))
{
return null;
}
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
if (!ImageConversion.LoadImage(val, array))
{
return null;
}
((Object)val).name = Path.GetFileNameWithoutExtension(path);
((Texture)val).wrapMode = (TextureWrapMode)0;
val.Apply(true, false);
return val;
}
}
[BepInPlugin("belpinex.tabs.scp173", "SCP-173 (Faccion Custom)", "1.1.4")]
public class Plugin : BaseUnityPlugin
{
private Harmony m_harmony;
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
m_harmony = new Harmony("belpinex.tabs.scp173");
m_harmony.PatchAll();
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
EmbeddedAssetLoader.ExtractAllEmbeddedAssets();
SCP173Audio.EnsureLoaded();
((MonoBehaviour)this).StartCoroutine(DelayedVisualAssetWarmup());
SceneResetHook.Install();
((MonoBehaviour)this).StartCoroutine(WaitForContentDatabaseThenRegister());
}
private IEnumerator DelayedVisualAssetWarmup()
{
yield return null;
SCP173SpawnReplacer.PreloadAssets();
}
private IEnumerator WaitForContentDatabaseThenRegister()
{
float elapsed = 0f;
while (elapsed < 60f)
{
ContentDatabase val;
try
{
val = ContentDatabase.Instance();
}
catch
{
val = null;
}
if (val != null && val.GetAllFactions() != null && val.GetAllFactions().Any())
{
break;
}
elapsed += Time.unscaledDeltaTime;
yield return null;
}
if (!(elapsed >= 60f))
{
DummyUnitFactory.BuildAndRegister();
}
}
}
public sealed class SCP173Audio : MonoBehaviour
{
private sealed class NeckRequest
{
public Vector3 Position;
public NeckRequest(Vector3 position)
{
//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)
Position = position;
}
}
private static SCP173Audio s_instance;
private AudioClip m_neckSnap1;
private AudioClip m_neckSnap2;
private AudioClip m_moving;
private AudioSource m_neckSource;
private AudioSource m_movingSource;
private bool m_loading;
private bool m_loaded;
private bool m_loggedMissing;
private string m_neckPath1;
private string m_neckPath2;
private string m_movingPath;
private Coroutine m_neckQueueRoutine;
private readonly Queue<NeckRequest> m_neckQueue = new Queue<NeckRequest>();
private double m_nextNeckDspTime;
public static bool IsLoaded
{
get
{
if ((Object)(object)s_instance != (Object)null)
{
return s_instance.m_loaded;
}
return false;
}
}
public static void EnsureLoaded()
{
//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_001e: Expected O, but got Unknown
if (!((Object)(object)s_instance != (Object)null))
{
GameObject val = new GameObject("SCP173_Audio");
Object.DontDestroyOnLoad((Object)val);
s_instance = val.AddComponent<SCP173Audio>();
}
}
private void Awake()
{
if ((Object)(object)s_instance != (Object)null && (Object)(object)s_instance != (Object)(object)this)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
return;
}
s_instance = this;
m_neckSource = CreateSource("SCP173_NeckAudio", 0f, spatial: false);
m_movingSource = CreateSource("SCP173_MovingAudio", 1f, spatial: true);
StartLoading();
}
private AudioSource CreateSource(string name, float spatialBlend, bool spatial)
{
//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)
GameObject val = new GameObject(name);
val.transform.SetParent(((Component)this).transform, false);
AudioSource obj = val.AddComponent<AudioSource>();
obj.playOnAwake = false;
obj.loop = false;
obj.spatialBlend = spatialBlend;
obj.volume = 1f;
obj.ignoreListenerPause = true;
obj.dopplerLevel = 0f;
obj.rolloffMode = (AudioRolloffMode)1;
obj.minDistance = (spatial ? 2f : 1f);
obj.maxDistance = (spatial ? 80f : 500f);
return obj;
}
private void StartLoading()
{
if (!m_loading && !m_loaded)
{
m_loading = true;
((MonoBehaviour)this).StartCoroutine(LoadAllAudio());
}
}
private IEnumerator LoadAllAudio()
{
EmbeddedAssetLoader.InitializeCache();
EmbeddedAssetLoader.ExtractAllEmbeddedAssets();
string cachedPath = EmbeddedAssetLoader.GetCachedPath("Assets/neck_snap_1.mp3");
string neck2Path = EmbeddedAssetLoader.GetCachedPath("Assets/neck_snap_2.mp3");
string movingPath = EmbeddedAssetLoader.GetCachedPath("Assets/scp-173-moving.mp3");
m_neckPath1 = cachedPath;
m_neckPath2 = neck2Path;
m_movingPath = movingPath;
yield return ((MonoBehaviour)this).StartCoroutine(LoadMp3(cachedPath, "SCP173_NeckSnap_1", delegate(AudioClip clip)
{
m_neckSnap1 = clip;
}));
yield return ((MonoBehaviour)this).StartCoroutine(LoadMp3(neck2Path, "SCP173_NeckSnap_2", delegate(AudioClip clip)
{
m_neckSnap2 = clip;
}));
yield return ((MonoBehaviour)this).StartCoroutine(LoadMp3(movingPath, "SCP173_Moving", delegate(AudioClip clip)
{
m_moving = clip;
}));
m_loading = false;
m_loaded = (Object)(object)m_neckSnap1 != (Object)null || (Object)(object)m_neckSnap2 != (Object)null || (Object)(object)m_moving != (Object)null;
if (!m_loaded && !m_loggedMissing)
{
m_loggedMissing = true;
}
if (m_neckQueue.Count > 0 && m_neckQueueRoutine == null)
{
m_neckQueueRoutine = ((MonoBehaviour)this).StartCoroutine(ProcessNeckQueue());
}
}
private IEnumerator LoadMp3(string path, string clipName, Action<AudioClip> assign)
{
if (string.IsNullOrEmpty(path) || !File.Exists(path))
{
yield break;
}
WWW www = new WWW("file://" + path);
yield return www;
if (string.IsNullOrEmpty(www.error))
{
AudioClip audioClip = www.GetAudioClip(false, true, (AudioType)13);
if ((Object)(object)audioClip != (Object)null)
{
((Object)audioClip).name = clipName;
assign(audioClip);
}
}
}
public static void PlayNeckSnap(Vector3 worldPosition)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
EnsureLoaded();
if (!((Object)(object)s_instance == (Object)null))
{
s_instance.m_neckQueue.Enqueue(new NeckRequest(worldPosition));
if (s_instance.m_neckQueueRoutine == null)
{
s_instance.m_neckQueueRoutine = ((MonoBehaviour)s_instance).StartCoroutine(s_instance.ProcessNeckQueue());
}
}
}
private IEnumerator ProcessNeckQueue()
{
while (m_neckQueue.Count > 0)
{
while ((Object)(object)m_neckSnap1 == (Object)null && (Object)(object)m_neckSnap2 == (Object)null && m_loading)
{
yield return null;
}
if ((Object)(object)m_neckSnap1 == (Object)null && (Object)(object)m_neckSnap2 == (Object)null)
{
break;
}
NeckRequest neckRequest = m_neckQueue.Dequeue();
AudioClip val = ChooseRandomNeckSnap();
if (!((Object)(object)val == (Object)null))
{
double num = Math.Max(AudioSettings.dspTime + 0.01, m_nextNeckDspTime);
((Component)m_neckSource).transform.position = neckRequest.Position;
m_neckSource.clip = val;
m_neckSource.PlayScheduled(num);
double num2 = Math.Max(0.001, val.length);
double end = (m_nextNeckDspTime = num + num2);
while (AudioSettings.dspTime < end - 0.002)
{
yield return null;
}
m_neckSource.Stop();
m_neckSource.clip = null;
yield return null;
}
}
m_neckQueueRoutine = null;
if (m_neckQueue.Count > 0)
{
m_neckQueueRoutine = ((MonoBehaviour)this).StartCoroutine(ProcessNeckQueue());
}
}
private AudioClip ChooseRandomNeckSnap()
{
if ((Object)(object)m_neckSnap1 != (Object)null && (Object)(object)m_neckSnap2 != (Object)null)
{
if (Random.Range(0, 2) != 0)
{
return m_neckSnap2;
}
return m_neckSnap1;
}
return m_neckSnap1 ?? m_neckSnap2;
}
public static void PlayMovingTeleport(Vector3 worldPosition)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
EnsureLoaded();
if (!((Object)(object)s_instance == (Object)null) && !((Object)(object)s_instance.m_moving == (Object)null) && !((Object)(object)s_instance.m_movingSource == (Object)null))
{
((Behaviour)s_instance.m_movingSource).enabled = true;
((Component)s_instance.m_movingSource).transform.position = worldPosition;
s_instance.m_movingSource.PlayOneShot(s_instance.m_moving, 1f);
}
}
}
public static class SCP173Config
{
public const string PluginGuid = "belpinex.tabs.scp173";
public const string PluginName = "SCP-173 (Faccion Custom)";
public const string PluginVersion = "1.1.4";
public const string ObjResource = "Assets/SCP173.obj";
public const string DiffuseResource = "Assets/SCP173_Diffuse.jpg";
public const string NormalResource = "Assets/SCP173_Normal.jpg";
public const string SpecResource = "Assets/SCP173_Spec.jpg";
public const string NeckSnapResource = "Assets/neck_snap_2.mp3";
public const string NeckSnapResource1 = "Assets/neck_snap_1.mp3";
public const string NeckSnapResource2 = "Assets/neck_snap_2.mp3";
public const string MovingResource = "Assets/scp-173-moving.mp3";
public const float TeleportRange = 6f;
public const float BlindTeleportSpeed = 400f;
public const float KillDistance = 1.6f;
public const float AttackCooldown = 1.25f;
public const float EnemyVisionConeAngle = 140f;
public const float EnemyVisionRange = 60f;
public const string OcclusionLayerMaskName = "Default";
public const float NeckSnapDuration = 0.35f;
public const float NeckSnapAngle = 110f;
public const float OutOfMapY = -250f;
public const float GroundProbeHeight = 8f;
public const float GroundProbeDistance = 2000f;
public const float GroundEpsilon = 0.015f;
public static string PluginFolder => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
public static string AssetsFolder => Path.Combine(PluginFolder, "Assets");
public static string ObjPath => Path.Combine(AssetsFolder, "SCP173.obj");
public static string DiffusePath => Path.Combine(AssetsFolder, "SCP173_Diffuse.jpg");
public static string NormalPath => Path.Combine(AssetsFolder, "SCP173_Normal.jpg");
public static string SpecPath => Path.Combine(AssetsFolder, "SCP173_Spec.jpg");
public static string NeckSnapAudioPath => Path.Combine(AssetsFolder, "neck_snap_2.mp3");
}
public static class SCP173CorpseFactory
{
public static GameObject Create(Unit victim, float neckAngle)
{
//IL_001e: 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)
if ((Object)(object)victim == (Object)null)
{
return null;
}
GameObject val = null;
SCP173Runtime.BeginInternalMutation();
try
{
val = Object.Instantiate<GameObject>(((Component)victim).gameObject, ((Component)victim).transform.position, ((Component)victim).transform.rotation);
if ((Object)(object)val == (Object)null)
{
return null;
}
((Object)val).name = ((Object)((Component)victim).gameObject).name + " [SCP-173 Ragdoll]";
val.tag = "Untagged";
DisableBehaviourComponents(val);
MakeRagdollOnly(val);
TwistAndBreakNeck(val.transform, neckAngle);
val.SetActive(true);
}
catch (Exception)
{
if ((Object)(object)val != (Object)null)
{
Object.DestroyImmediate((Object)(object)val);
}
val = null;
}
finally
{
SCP173Runtime.EndInternalMutation();
}
return val;
}
private static void DisableBehaviourComponents(GameObject corpse)
{
MonoBehaviour[] componentsInChildren = corpse.GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null))
{
Object.DestroyImmediate((Object)(object)val);
}
}
}
private static void MakeRagdollOnly(GameObject corpse)
{
//IL_004b: 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)
Component[] componentsInChildren = corpse.GetComponentsInChildren<Component>(true);
foreach (Component val in componentsInChildren)
{
if ((Object)(object)val == (Object)null || val is Transform)
{
continue;
}
Rigidbody val2 = (Rigidbody)(object)((val is Rigidbody) ? val : null);
if (val2 != null)
{
val2.isKinematic = false;
val2.detectCollisions = true;
val2.useGravity = true;
val2.constraints = (RigidbodyConstraints)0;
val2.velocity = Vector3.zero;
val2.angularVelocity = Vector3.zero;
}
else
{
Collider val3 = (Collider)(object)((val is Collider) ? val : null);
if (val3 != null)
{
val3.enabled = true;
}
else if (!(val is Joint) && !(val is Renderer) && !(val is MeshFilter))
{
Object.DestroyImmediate((Object)(object)val);
}
}
}
}
private static void TwistAndBreakNeck(Transform root, float angleDegrees)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: 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_008c: 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_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
Rigidbody val = FindBody(root, "Head", "head");
Rigidbody val2 = FindBody(root, "Torso", "torso", "Chest", "chest");
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
return;
}
Vector3 right = ((Component)val2).transform.right;
((Component)val).transform.rotation = Quaternion.AngleAxis(angleDegrees, right) * ((Component)val).transform.rotation;
val.angularVelocity = right * (angleDegrees * ((float)Math.PI / 180f)) * 5f;
Vector3 val3 = val.worldCenterOfMass - val2.worldCenterOfMass;
if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f)
{
val.AddForce(((Vector3)(ref val3)).normalized * 1.5f, (ForceMode)2);
}
Joint[] componentsInChildren = ((Component)root).GetComponentsInChildren<Joint>(true);
foreach (Joint val4 in componentsInChildren)
{
if (!((Object)(object)val4 == (Object)null))
{
Rigidbody connectedBody = val4.connectedBody;
Rigidbody component = ((Component)val4).GetComponent<Rigidbody>();
if ((Object)(object)((Component)val4).transform == (Object)(object)((Component)val).transform || ((Component)val4).transform.IsChildOf(((Component)val).transform) || (Object)(object)component == (Object)(object)val || (Object)(object)connectedBody == (Object)(object)val || ((Object)(object)component == (Object)(object)val2 && (Object)(object)connectedBody == (Object)(object)val) || ((Object)(object)connectedBody == (Object)(object)val2 && (Object)(object)component == (Object)(object)val))
{
Object.DestroyImmediate((Object)(object)val4);
}
}
}
}
private static Rigidbody FindBody(Transform root, params string[] names)
{
Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
string name = ((Object)componentsInChildren[i]).name;
for (int j = 0; j < names.Length; j++)
{
if (string.Equals(name, names[j], StringComparison.OrdinalIgnoreCase))
{
return ((Component)componentsInChildren[i]).GetComponent<Rigidbody>();
}
}
}
return null;
}
}
public class SCP173HazardController : MonoBehaviour
{
private struct VisionCandidate
{
internal Unit unit;
internal Transform eye;
internal Vector3 direction;
internal float distance;
internal float score;
internal VisionCandidate(Unit u, Transform e, Vector3 d, float dist, float s)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
unit = u;
eye = e;
direction = d;
distance = dist;
score = s;
}
internal static int Compare(VisionCandidate a, VisionCandidate b)
{
return b.score.CompareTo(a.score);
}
}
private Transform m_currentTarget;
private Unit m_currentTargetUnit;
private bool m_isBeingSeen;
private readonly List<Unit> m_allEnemyUnitsBuffer = new List<Unit>();
private float m_targetRescanTimer;
private float m_nextAttackTime;
private Vector3 m_lastSafePosition;
private const float TargetRescanInterval = 0.25f;
private LayerMask m_occlusionMask;
private const int MaxVisionRaycastsPerFrame = 24;
private const float VisionCacheDuration = 0.035f;
private float m_nextVisionCheckTime;
private bool m_cachedBeingSeen;
private static readonly List<VisionCandidate> s_visionCandidates = new List<VisionCandidate>(64);
private void Awake()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
m_occlusionMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { "Default" }));
}
private void Start()
{
//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)
if (SCP173Runtime.TryRegisterInstance(this))
{
m_lastSafePosition = ((Component)this).transform.position;
SCP173Audio.EnsureLoaded();
RescanTarget();
}
}
private void OnDestroy()
{
SCP173Runtime.NotifyInstanceDestroyed(this);
}
private void Update()
{
MaintainGroundedAndRecover();
m_isBeingSeen = IsBeingSeenByAnyEnemy();
if (!m_isBeingSeen)
{
m_targetRescanTimer -= Time.unscaledDeltaTime;
if ((Object)(object)m_currentTargetUnit == (Object)null || m_currentTargetUnit.dead || m_targetRescanTimer <= 0f)
{
RescanTarget();
m_targetRescanTimer = 0.25f;
}
if (!((Object)(object)m_currentTarget == (Object)null))
{
StepTeleportTowardsTarget();
}
}
}
private void MaintainGroundedAndRecover()
{
//IL_0006: 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_0014: 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_0028: 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_008b: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: 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_006a: 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)
//IL_00b3: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = ((Component)this).transform.position;
if (!IsFinite(val) || val.y < -250f)
{
if (TryGetGroundedPosition(m_lastSafePosition, out var grounded))
{
SCP173Runtime.BeginInternalMutation();
try
{
((Component)this).transform.position = grounded;
}
finally
{
SCP173Runtime.EndInternalMutation();
}
val = grounded;
}
else
{
if (!TryGetGroundedPosition(val, out grounded))
{
return;
}
SCP173Runtime.BeginInternalMutation();
try
{
((Component)this).transform.position = grounded;
}
finally
{
SCP173Runtime.EndInternalMutation();
}
val = grounded;
}
}
if (!TryGetGroundedPosition(val, out var grounded2))
{
return;
}
float num = Mathf.Abs(grounded2.y - val.y);
if (num > 0.01f && num < 12f)
{
SCP173Runtime.BeginInternalMutation();
try
{
((Component)this).transform.position = grounded2;
}
finally
{
SCP173Runtime.EndInternalMutation();
}
val = grounded2;
}
m_lastSafePosition = grounded2;
SCP173Runtime.RememberTransform(((Component)this).transform);
}
private bool TryGetGroundedPosition(Vector3 candidate, out Vector3 grounded)
{
//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_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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_0026: 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_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: 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_00c3: 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_00cc: 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)
grounded = candidate;
if (!IsFinite(candidate))
{
return false;
}
RaycastHit[] array = Physics.RaycastAll(candidate + Vector3.up * 60f, Vector3.down, 4060f, -1, (QueryTriggerInteraction)1);
float num = float.NegativeInfinity;
bool flag = false;
for (int i = 0; i < array.Length; i++)
{
RaycastHit val = array[i];
Transform transform = ((RaycastHit)(ref val)).transform;
if (!((Object)(object)transform == (Object)null) && !IsPartOfSCP173(transform) && !((Object)(object)((Component)transform).GetComponentInParent<Unit>() != (Object)null))
{
float y = ((RaycastHit)(ref val)).point.y;
if (y > num)
{
num = y;
flag = true;
}
}
}
if (!flag)
{
return false;
}
Renderer componentInChildren = ((Component)this).GetComponentInChildren<Renderer>();
float num2 = 0f;
if ((Object)(object)componentInChildren != (Object)null)
{
float y2 = candidate.y;
Bounds bounds = componentInChildren.bounds;
num2 = y2 - ((Bounds)(ref bounds)).min.y;
}
grounded = new Vector3(candidate.x, num + num2 + 0.015f, candidate.z);
if (IsFinite(grounded))
{
return grounded.y > -250f;
}
return false;
}
private bool IsBeingSeenByAnyEnemy()
{
//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_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: 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_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
float unscaledTime = Time.unscaledTime;
if (unscaledTime < m_nextVisionCheckTime)
{
return m_cachedBeingSeen;
}
m_nextVisionCheckTime = unscaledTime + 0.035f;
m_allEnemyUnitsBuffer.Clear();
UnitRegistry.GetAllLivingUnits(m_allEnemyUnitsBuffer);
Vector3 position = ((Component)this).transform.position;
float num = 3600f;
List<VisionCandidate> list = s_visionCandidates;
list.Clear();
for (int i = 0; i < m_allEnemyUnitsBuffer.Count; i++)
{
Unit val = m_allEnemyUnitsBuffer[i];
if ((Object)(object)val == (Object)null || SCP173Runtime.HasNeckBeenBroken(val) || val.dead || (Object)(object)val.data == (Object)null || (Object)(object)val.Head == (Object)null)
{
continue;
}
Transform head = val.Head;
Vector3 val2 = position - head.position;
float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
if (!(sqrMagnitude <= 0.0001f) && !(sqrMagnitude > num))
{
float num2 = 1f / Mathf.Sqrt(sqrMagnitude);
Vector3 val3 = val2 * num2;
float num3 = Vector3.Dot(head.forward, val3);
float num4 = Mathf.Cos(1.2217305f);
if (!(num3 < num4))
{
float s = num3 * 2f - sqrMagnitude / num;
list.Add(new VisionCandidate(val, head, val3, Mathf.Sqrt(sqrMagnitude), s));
}
}
}
list.Sort(VisionCandidate.Compare);
int num5 = Mathf.Min(24, list.Count);
RaycastHit val4 = default(RaycastHit);
for (int j = 0; j < num5; j++)
{
VisionCandidate visionCandidate = list[j];
if (!Physics.Raycast(visionCandidate.eye.position, visionCandidate.direction, ref val4, visionCandidate.distance + 0.5f, LayerMask.op_Implicit(m_occlusionMask), (QueryTriggerInteraction)1) || IsPartOfSCP173(((RaycastHit)(ref val4)).transform))
{
m_cachedBeingSeen = true;
return true;
}
}
m_cachedBeingSeen = false;
return false;
}
private bool IsPartOfSCP173(Transform t)
{
if (!((Object)(object)t == (Object)(object)((Component)this).transform))
{
return t.IsChildOf(((Component)this).transform);
}
return true;
}
private static bool IsFinite(Vector3 p)
{
//IL_0000: 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_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_0041: Unknown result type (might be due to invalid IL or missing references)
if (!float.IsNaN(p.x) && !float.IsNaN(p.y) && !float.IsNaN(p.z) && !float.IsInfinity(p.x) && !float.IsInfinity(p.y))
{
return !float.IsInfinity(p.z);
}
return false;
}
private void RescanTarget()
{
//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_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_008d: 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)
m_allEnemyUnitsBuffer.Clear();
UnitRegistry.GetAllLivingUnits(m_allEnemyUnitsBuffer);
float num = float.MaxValue;
Unit val = null;
Vector3 position = ((Component)this).transform.position;
for (int i = 0; i < m_allEnemyUnitsBuffer.Count; i++)
{
Unit val2 = m_allEnemyUnitsBuffer[i];
if (!((Object)(object)val2 == (Object)null) && !SCP173Runtime.HasNeckBeenBroken(val2) && !val2.dead && !((Object)(object)val2.data == (Object)null) && !((Object)(object)val2.data.mainRig == (Object)null))
{
Vector3 val3 = val2.data.mainRig.position - position;
float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
if (sqrMagnitude < num)
{
num = sqrMagnitude;
val = val2;
}
}
}
m_currentTargetUnit = val;
m_currentTarget = (((Object)(object)val != (Object)null) ? ((Component)val.data.mainRig).transform : null);
}
private void StepTeleportTowardsTarget()
{
//IL_0006: 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_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_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)
//IL_002c: 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_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
Vector3 position = ((Component)this).transform.position;
Vector3 position2 = m_currentTarget.position;
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(position2.x - position.x, 0f, position2.z - position.z);
float magnitude = ((Vector3)(ref val)).magnitude;
if (magnitude <= 1.6f)
{
float unscaledTime = Time.unscaledTime;
if (unscaledTime >= m_nextAttackTime)
{
ExecuteInstantKill(m_currentTargetUnit);
m_nextAttackTime = unscaledTime + 1.25f;
}
return;
}
float num = 400f * Time.unscaledDeltaTime;
num = Mathf.Min(new float[3] { num, 6f, magnitude });
if (num <= 0f)
{
return;
}
Vector3 val2 = val / magnitude;
Vector3 candidate = position + val2 * num;
if (!TryGetGroundedPosition(candidate, out var grounded))
{
return;
}
SCP173Runtime.BeginInternalMutation();
try
{
((Component)this).transform.position = grounded;
}
finally
{
SCP173Runtime.EndInternalMutation();
}
SCP173Audio.PlayMovingTeleport(grounded);
m_lastSafePosition = grounded;
SCP173Runtime.RememberTransform(((Component)this).transform);
if (!(((Vector3)(ref val2)).sqrMagnitude > 0.0001f))
{
return;
}
SCP173Runtime.BeginInternalMutation();
try
{
((Component)this).transform.rotation = Quaternion.LookRotation(val2, Vector3.up);
}
finally
{
SCP173Runtime.EndInternalMutation();
}
}
private void ExecuteInstantKill(Unit victim)
{
//IL_004b: 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)
if ((Object)(object)victim == (Object)null || victim.dead || (Object)(object)victim.data == (Object)null)
{
return;
}
SCP173Audio.PlayNeckSnap(((Object)(object)victim.data.mainRig != (Object)null) ? victim.data.mainRig.position : ((Component)victim).transform.position);
NeckSnapDeformer.SnapNeck(victim, 110f);
GameObject val = SCP173CorpseFactory.Create(victim, 110f);
UnitRegistry.Unregister(victim);
SCP173ReferencePurger.Purge(victim);
SCP173Runtime.BeginInternalMutation();
try
{
if ((Object)(object)victim != (Object)null)
{
Object.DestroyImmediate((Object)(object)((Component)victim).gameObject);
}
}
finally
{
SCP173Runtime.EndInternalMutation();
}
if ((Object)(object)val != (Object)null)
{
Rigidbody[] componentsInChildren = val.GetComponentsInChildren<Rigidbody>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
if ((Object)(object)componentsInChildren[i] != (Object)null)
{
componentsInChildren[i].WakeUp();
}
}
}
m_currentTarget = null;
m_currentTargetUnit = null;
}
}
public static class SCP173ReferencePurger
{
public static void Purge(Unit victim)
{
if ((Object)(object)victim == (Object)null)
{
return;
}
Guid guid = ((victim.RuntimeReference != null) ? ((RuntimeReference)victim.RuntimeReference).Guid : Guid.Empty);
UnitBlueprint unitBlueprint = victim.unitBlueprint;
victim.RuntimeReference = null;
RemoveRuntimeReference(guid);
RemoveFromTeamSystem(victim);
ClearRuntimeReferenceFields(((Component)victim).gameObject);
try
{
if ((Object)(object)unitBlueprint != (Object)null)
{
UnitBlueprint val = Object.Instantiate<UnitBlueprint>(unitBlueprint);
((Object)val).name = ((Object)unitBlueprint).name + " [SCP173_CORRUPTED_RUNTIME]";
val.UnitBase = null;
val.RightWeapon = null;
val.LeftWeapon = null;
val.fistRef = null;
victim.unitBlueprint = val;
}
}
catch (Exception)
{
victim.unitBlueprint = null;
}
}
private static void RemoveRuntimeReference(Guid guid)
{
if (guid == Guid.Empty)
{
return;
}
try
{
RuntimeReferenceService val = Object.FindObjectOfType<RuntimeReferenceService>();
if ((Object)(object)val == (Object)null)
{
return;
}
FieldInfo field = typeof(RuntimeReferenceService).GetField("m_references", BindingFlags.Instance | BindingFlags.NonPublic);
((field != null) ? (field.GetValue(val) as IDictionary) : null)?.Remove(guid);
List<RuntimeReference> allReferencesRequests = val.GetAllReferencesRequests();
if (allReferencesRequests == null)
{
return;
}
for (int num = allReferencesRequests.Count - 1; num >= 0; num--)
{
RuntimeReference val2 = allReferencesRequests[num];
if (val2 != null && val2.Guid == guid)
{
allReferencesRequests.RemoveAt(num);
}
}
}
catch (Exception)
{
}
}
private static void RemoveFromTeamSystem(Unit victim)
{
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
try
{
World active = World.Active;
if (active == null)
{
return;
}
TeamSystem existingManager = active.GetExistingManager<TeamSystem>();
if (existingManager == null)
{
return;
}
Component val = FindComponentByName(((Component)victim).gameObject, "GameObjectEntity");
if ((Object)(object)val != (Object)null)
{
object obj = ((object)val).GetType().GetProperty("Entity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(val, null);
MethodInfo method = typeof(TeamSystem).GetMethod("RemoveEntity", BindingFlags.Instance | BindingFlags.Public);
if (method != null && obj != null)
{
method.Invoke(existingManager, new object[3] { obj, victim.Team, victim });
return;
}
}
RemoveUnitFromPrivateList(existingManager, "m_allUnits", victim);
RemoveUnitFromPrivateList(existingManager, "m_teamUnits", victim);
RemoveUnitFromPrivateList(existingManager, "m_winConditionUnits", victim);
}
catch (Exception)
{
}
}
private static Component FindComponentByName(GameObject go, string typeName)
{
Component[] components = go.GetComponents<Component>();
for (int i = 0; i < components.Length; i++)
{
if ((Object)(object)components[i] != (Object)null && ((object)components[i]).GetType().Name == typeName)
{
return components[i];
}
}
return null;
}
private static void RemoveUnitFromPrivateList(TeamSystem teams, string fieldName, Unit victim)
{
object obj = typeof(TeamSystem).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(teams);
if (obj is IDictionary dictionary)
{
{
foreach (object item in new ArrayList(dictionary.Keys))
{
(dictionary[item] as IList)?.Remove(victim);
}
return;
}
}
(obj as IList)?.Remove(victim);
}
private static void ClearRuntimeReferenceFields(GameObject root)
{
MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val in componentsInChildren)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
FieldInfo[] fields = ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (typeof(RuntimeReference).IsAssignableFrom(fieldInfo.FieldType))
{
try
{
fieldInfo.SetValue(val, null);
}
catch
{
}
}
}
}
}
}
public static class SCP173Runtime
{
private static Unit s_referenceProxy;
private static SCP173HazardController s_instance;
private static GameObject s_instanceObject;
private static Vector3 s_lastPosition;
private static Quaternion s_lastRotation = Quaternion.identity;
private static string s_sceneName;
private static Guid s_referenceGuid = Guid.Empty;
private static bool s_referenceBound;
private static bool s_spawnInProgress;
private static int s_timeServiceTouchCount;
private static bool s_internalMutation;
private static readonly HashSet<Guid> s_neckBrokenRuntimeGuids = new HashSet<Guid>();
private static Vector3 s_expectedScale = Vector3.one;
private static Mesh s_expectedMesh;
private static Material s_expectedMaterial;
public static SCP173HazardController Instance => s_instance;
public static GameObject InstanceObject => s_instanceObject;
public static Unit ReferenceProxy => s_referenceProxy;
public static Guid ReferenceGuid => s_referenceGuid;
public static bool HasReference
{
get
{
if (s_referenceBound)
{
return s_referenceGuid != Guid.Empty;
}
return false;
}
}
public static bool HasSpawned => IsValid((Object)(object)s_instance);
public static bool SpawnInProgress => s_spawnInProgress;
public static string SceneName => s_sceneName;
public static int TimeServiceTouchCount => s_timeServiceTouchCount;
public static bool InternalMutation => s_internalMutation;
public static Vector3 ExpectedScale => s_expectedScale;
public static Mesh ExpectedMesh => s_expectedMesh;
public static Material ExpectedMaterial => s_expectedMaterial;
public static Vector3 LastPosition => s_lastPosition;
public static Quaternion LastRotation => s_lastRotation;
public static void MarkTimeServiceTouched()
{
s_timeServiceTouchCount++;
}
public static void BeginInternalMutation()
{
s_internalMutation = true;
}
public static void EndInternalMutation()
{
s_internalMutation = false;
}
public static bool IsReferenceProxy(Unit unit)
{
if ((Object)(object)unit != (Object)null)
{
return (Object)(object)s_referenceProxy == (Object)(object)unit;
}
return false;
}
public static bool IsProtectedReference(RuntimeReference reference)
{
if (reference != null && HasReference)
{
return reference.Guid == s_referenceGuid;
}
return false;
}
public static bool IsProtectedUnit(Unit unit)
{
if (!IsReferenceProxy(unit))
{
if ((Object)(object)unit != (Object)null && unit.RuntimeReference != null)
{
return IsProtectedReference((RuntimeReference)(object)unit.RuntimeReference);
}
return false;
}
return true;
}
public static bool HasNeckBeenBroken(Unit unit)
{
if ((Object)(object)unit == (Object)null)
{
return true;
}
if (unit.RuntimeReference != null && ((RuntimeReference)unit.RuntimeReference).Guid != Guid.Empty && s_neckBrokenRuntimeGuids.Contains(((RuntimeReference)unit.RuntimeReference).Guid))
{
return true;
}
return false;
}
public static void MarkNeckBroken(Unit unit)
{
if (!((Object)(object)unit == (Object)null) && unit.RuntimeReference != null && ((RuntimeReference)unit.RuntimeReference).Guid != Guid.Empty)
{
s_neckBrokenRuntimeGuids.Add(((RuntimeReference)unit.RuntimeReference).Guid);
}
}
public static void BindReference(Unit proxy)
{
if (!((Object)(object)proxy == (Object)null) && DummyUnitFactory.IsDummy(proxy))
{
s_referenceProxy = proxy;
if (proxy.RuntimeReference != null)
{
s_referenceGuid = ((RuntimeReference)proxy.RuntimeReference).Guid;
s_referenceBound = s_referenceGuid != Guid.Empty;
}
}
}
public static bool TryRegisterInstance(SCP173HazardController controller)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: 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 ((Object)(object)controller == (Object)null)
{
return false;
}
if (IsValid((Object)(object)s_instance) && (Object)(object)s_instance != (Object)(object)controller)
{
BeginInternalMutation();
try
{
Object.DestroyImmediate((Object)(object)((Component)controller).gameObject);
}
finally
{
EndInternalMutation();
}
return false;
}
s_instance = controller;
s_instanceObject = ((Component)controller).gameObject;
s_lastPosition = ((Component)controller).transform.position;
s_lastRotation = ((Component)controller).transform.rotation;
Scene activeScene = SceneManager.GetActiveScene();
s_sceneName = ((Scene)(ref activeScene)).name;
MeshFilter component = ((Component)controller).GetComponent<MeshFilter>();
MeshRenderer component2 = ((Component)controller).GetComponent<MeshRenderer>();
s_expectedScale = ((Component)controller).transform.localScale;
s_expectedMesh = (((Object)(object)component != (Object)null) ? component.sharedMesh : null);
s_expectedMaterial = (((Object)(object)component2 != (Object)null) ? ((Renderer)component2).sharedMaterial : null);
return true;
}
public static void RememberTransform(Transform transform)
{
//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_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 (!((Object)(object)transform == (Object)null) && !InternalMutation)
{
s_lastPosition = transform.position;
s_lastRotation = transform.rotation;
}
}
public static bool IsSameScene()
{
//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)
if (!string.IsNullOrEmpty(s_sceneName))
{
Scene activeScene = SceneManager.GetActiveScene();
return ((Scene)(ref activeScene)).name == s_sceneName;
}
return false;
}
public static void SetSpawnInProgress(bool value)
{
s_spawnInProgress = value;
}
public static void NotifyInstanceDestroyed(SCP173HazardController controller)
{
if (!((Object)(object)s_instance != (Object)(object)controller))
{
if (!InternalMutation)
{
RememberTransform(((Component)controller).transform);
}
s_instance = null;
s_instanceObject = null;
}
}
public static bool TryGetLiveInstance(out SCP173HazardController controller)
{
controller = s_instance;
return IsValid((Object)(object)controller);
}
public static void ResetSceneState()
{
//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_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)
s_referenceProxy = null;
s_instance = null;
s_instanceObject = null;
s_lastPosition = Vector3.zero;
s_referenceGuid = Guid.Empty;
s_referenceBound = false;
s_sceneName = null;
s_spawnInProgress = false;
s_timeServiceTouchCount = 0;
s_internalMutation = false;
s_neckBrokenRuntimeGuids.Clear();
s_expectedScale = Vector3.one;
s_expectedMesh = null;
s_expectedMaterial = null;
}
private static bool IsValid(Object obj)
{
return obj != (Object)null;
}
}
public static class SCP173SpawnReplacer
{
private static Mesh s_cachedMesh;
private static Material s_cachedMaterial;
private static Texture2D s_cachedDiffuse;
private static Texture2D s_cachedNormal;
private static Texture2D s_cachedSpec;
public static void ReplaceIfDummy(Unit unit)
{
//IL_002f: 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)
if (!DummyUnitFactory.IsDummy(unit))
{
return;
}
if (SCP173Runtime.HasSpawned || SCP173Runtime.SpawnInProgress)
{
Object.Destroy((Object)(object)((Component)unit).gameObject);
return;
}
SCP173Runtime.SetSpawnInProgress(value: true);
try
{
SpawnRealSCP173(((Component)unit).transform.position, ((Component)unit).transform.rotation);
NeutralizeReferenceProxy(unit);
}
finally
{
SCP173Runtime.SetSpawnInProgress(value: false);
}
}
private static void NeutralizeReferenceProxy(Unit unit)
{
if ((Object)(object)unit == (Object)null)
{
return;
}
unit.ShowRenderers(false);
Collider[] componentsInChildren = ((Component)unit).GetComponentsInChildren<Collider>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
if ((Object)(object)componentsInChildren[i] != (Object)null)
{
componentsInChildren[i].enabled = false;
}
}
MonoBehaviour[] componentsInChildren2 = ((Component)unit).GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val in componentsInChildren2)
{
if (!((Object)(object)val == (Object)null) && !(val is Unit))
{
((Behaviour)val).enabled = false;
}
}
try
{
UnitAPI component = ((Component)unit).GetComponent<UnitAPI>();
if ((Object)(object)component != (Object)null)
{
component.SetIsDead();
((Behaviour)component).enabled = false;
}
}
catch
{
}
((Behaviour)unit).enabled = false;
}
private static GameObject SpawnRealSCP173(Vector3 position, Quaternion rotation)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0027: 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_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_0050: 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_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
EnsureAssetsLoaded();
GameObject instanceObject = SCP173Runtime.InstanceObject;
if ((Object)(object)instanceObject != (Object)null)
{
return instanceObject;
}
GameObject val = new GameObject("SCP-173");
val.transform.SetPositionAndRotation(position, rotation);
float num;
Bounds bounds;
if (!((Object)(object)s_cachedMesh != (Object)null))
{
num = 0f;
}
else
{
bounds = s_cachedMesh.bounds;
num = ((Bounds)(ref bounds)).size.y;
}
float num2 = num;
float num3 = ((num2 > 0.001f) ? (2.7f / num2) : 1f);
val.transform.localScale = Vector3.one * num3;
if ((Object)(object)s_cachedMesh != (Object)null)
{
bounds = s_cachedMesh.bounds;
float num4 = ((Bounds)(ref bounds)).min.y * num3;
Transform transform = val.transform;
transform.position += Vector3.up * (0f - num4);
}
val.AddComponent<MeshFilter>().sharedMesh = s_cachedMesh;
MeshRenderer obj = val.AddComponent<MeshRenderer>();
((Renderer)obj).sharedMaterial = s_cachedMaterial;
((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
MeshCollider obj2 = val.AddComponent<MeshCollider>();
obj2.sharedMesh = s_cachedMesh;
obj2.convex = true;
if (!SCP173Runtime.TryRegisterInstance(val.AddComponent<SCP173HazardController>()))
{
Object.Destroy((Object)(object)val);
return null;
}
return val;
}
internal static Material CreateProtectedMaterial()
{
EnsureAssetsLoaded();
return s_cachedMaterial;
}
public static void PreloadAssets()
{
EnsureAssetsLoaded();
}
private static void EnsureAssetsLoaded()
{
//IL_01a1: 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_01b2: Expected O, but got Unknown
if ((Object)(object)s_cachedMesh == (Object)null)
{
string cachedPath = EmbeddedAssetLoader.GetCachedPath("Assets/SCP173.obj");
if (!string.IsNullOrEmpty(cachedPath))
{
s_cachedMesh = ObjRuntimeLoader.LoadMesh(cachedPath);
}
if ((Object)(object)s_cachedMesh == (Object)null)
{
s_cachedMesh = ObjRuntimeLoader.LoadMeshFromText(EmbeddedAssetLoader.LoadText("Assets/SCP173.obj"));
}
}
if ((Object)(object)s_cachedDiffuse == (Object)null)
{
string cachedPath2 = EmbeddedAssetLoader.GetCachedPath("Assets/SCP173_Diffuse.jpg");
if (!string.IsNullOrEmpty(cachedPath2))
{
s_cachedDiffuse = ObjRuntimeLoader.LoadTexture(cachedPath2);
}
if ((Object)(object)s_cachedDiffuse == (Object)null)
{
s_cachedDiffuse = ObjRuntimeLoader.LoadTextureBytes(EmbeddedAssetLoader.LoadBytes("Assets/SCP173_Diffuse.jpg"), "SCP173_Diffuse");
}
}
if ((Object)(object)s_cachedNormal == (Object)null)
{
string cachedPath3 = EmbeddedAssetLoader.GetCachedPath("Assets/SCP173_Normal.jpg");
if (!string.IsNullOrEmpty(cachedPath3))
{
s_cachedNormal = ObjRuntimeLoader.LoadTexture(cachedPath3);
}
if ((Object)(object)s_cachedNormal == (Object)null)
{
s_cachedNormal = ObjRuntimeLoader.LoadTextureBytes(EmbeddedAssetLoader.LoadBytes("Assets/SCP173_Normal.jpg"), "SCP173_Normal");
}
}
if ((Object)(object)s_cachedSpec == (Object)null)
{
string cachedPath4 = EmbeddedAssetLoader.GetCachedPath("Assets/SCP173_Spec.jpg");
if (!string.IsNullOrEmpty(cachedPath4))
{
s_cachedSpec = ObjRuntimeLoader.LoadTexture(cachedPath4);
}
if ((Object)(object)s_cachedSpec == (Object)null)
{
s_cachedSpec = ObjRuntimeLoader.LoadTextureBytes(EmbeddedAssetLoader.LoadBytes("Assets/SCP173_Spec.jpg"), "SCP173_Spec");
}
}
if ((Object)(object)s_cachedMaterial != (Object)null)
{
return;
}
Shader val = Shader.Find("Standard") ?? Shader.Find("Legacy Shaders/Bumped Specular") ?? Shader.Find("Legacy Shaders/Diffuse") ?? Shader.Find("Diffuse") ?? Shader.Find("Unlit/Texture");
if (!((Object)(object)val == (Object)null))
{
Material val2 = new Material(val)
{
name = "SCP173_Material"
};
if ((Object)(object)s_cachedDiffuse != (Object)null)
{
val2.SetTexture("_MainTex", (Texture)(object)s_cachedDiffuse);
}
if ((Object)(object)s_cachedNormal != (Object)null)
{
val2.SetTexture("_BumpMap", (Texture)(object)s_cachedNormal);
val2.EnableKeyword("_NORMALMAP");
}
if ((Object)(object)s_cachedSpec != (Object)null)
{
val2.SetTexture("_SpecGlossMap", (Texture)(object)s_cachedSpec);
val2.EnableKeyword("_SPECGLOSSMAP");
}
s_cachedMaterial = val2;
}
}
}
public static class SCP173UnityProtectionPatches
{
internal static bool Is173(GameObject go)
{
if ((Object)(object)go == (Object)null || SCP173Runtime.InternalMutation)
{
return false;
}
GameObject instanceObject = SCP173Runtime.InstanceObject;
if ((Object)(object)instanceObject == (Object)null)
{
return false;
}
if (!((Object)(object)go == (Object)(object)instanceObject))
{
return go.transform.IsChildOf(instanceObject.transform);
}
return true;
}
internal static bool Is173(Component component)
{
if ((Object)(object)component != (Object)null)
{
return Is173(component.gameObject);
}
return false;
}
}
[HarmonyPatch(typeof(Transform), "set_position")]
internal static class Transform_set_position_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Transform __instance, ref Vector3 value)
{
//IL_000b: 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 (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
if (!Finite(value))
{
value = __instance.position;
}
return false;
}
private static bool Finite(Vector3 v)
{
//IL_0000: 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_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_0041: Unknown result type (might be due to invalid IL or missing references)
if (!float.IsNaN(v.x) && !float.IsNaN(v.y) && !float.IsNaN(v.z) && !float.IsInfinity(v.x) && !float.IsInfinity(v.y))
{
return !float.IsInfinity(v.z);
}
return false;
}
}
[HarmonyPatch(typeof(Transform), "set_rotation")]
internal static class Transform_set_rotation_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Transform __instance, ref Quaternion value)
{
//IL_000b: 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 (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
if (!Finite(value))
{
value = __instance.rotation;
}
return false;
}
private static bool Finite(Quaternion q)
{
//IL_0000: 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_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_0041: 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_005b: Unknown result type (might be due to invalid IL or missing references)
if (!float.IsNaN(q.x) && !float.IsNaN(q.y) && !float.IsNaN(q.z) && !float.IsNaN(q.w) && !float.IsInfinity(q.x) && !float.IsInfinity(q.y) && !float.IsInfinity(q.z))
{
return !float.IsInfinity(q.w);
}
return false;
}
}
[HarmonyPatch(typeof(Transform), "set_localScale")]
internal static class Transform_set_localScale_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Transform __instance, ref Vector3 value)
{
//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)
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = SCP173Runtime.ExpectedScale;
return false;
}
}
[HarmonyPatch(typeof(Transform), "SetPositionAndRotation")]
internal static class Transform_SetPositionAndRotation_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Transform __instance)
{
return !SCP173UnityProtectionPatches.Is173((Component)(object)__instance);
}
}
[HarmonyPatch(typeof(Transform), "set_localPosition")]
internal static class Transform_set_localPosition_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Transform __instance)
{
return !SCP173UnityProtectionPatches.Is173((Component)(object)__instance);
}
}
[HarmonyPatch(typeof(Transform), "set_localRotation")]
internal static class Transform_set_localRotation_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Transform __instance)
{
return !SCP173UnityProtectionPatches.Is173((Component)(object)__instance);
}
}
[HarmonyPatch(typeof(Transform), "SetParent", new Type[]
{
typeof(Transform),
typeof(bool)
})]
internal static class Transform_SetParent_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Transform __instance)
{
return !SCP173UnityProtectionPatches.Is173((Component)(object)__instance);
}
}
[HarmonyPatch(typeof(GameObject), "SetActive")]
internal static class GameObject_SetActive_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(GameObject __instance, bool value)
{
if (!SCP173UnityProtectionPatches.Is173(__instance))
{
return true;
}
return value;
}
}
[HarmonyPatch(typeof(Behaviour), "set_enabled")]
internal static class Behaviour_set_enabled_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Behaviour __instance, ref bool value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
if (__instance is SCP173HazardController)
{
value = true;
}
else
{
value = __instance.enabled;
}
return false;
}
}
[HarmonyPatch(typeof(Renderer), "set_enabled")]
internal static class Renderer_set_enabled_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Renderer __instance, ref bool value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = true;
return false;
}
}
[HarmonyPatch(typeof(Renderer), "set_forceRenderingOff")]
internal static class Renderer_set_forceRenderingOff_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Renderer __instance, ref bool value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = false;
return false;
}
}
[HarmonyPatch(typeof(MeshFilter), "set_sharedMesh")]
internal static class MeshFilter_set_sharedMesh_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(MeshFilter __instance, ref Mesh value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = SCP173Runtime.ExpectedMesh;
return false;
}
}
[HarmonyPatch(typeof(MeshCollider), "set_sharedMesh")]
internal static class MeshCollider_set_sharedMesh_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(MeshCollider __instance, ref Mesh value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = SCP173Runtime.ExpectedMesh;
return false;
}
}
[HarmonyPatch(typeof(Renderer), "set_sharedMaterials")]
internal static class MeshRenderer_set_sharedMaterials_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(MeshRenderer __instance, ref Material[] value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
Material expectedMaterial = SCP173Runtime.ExpectedMaterial;
value = (Material[])(((Object)(object)expectedMaterial == (Object)null) ? ((Array)value) : ((Array)new Material[1] { expectedMaterial }));
return false;
}
}
[HarmonyPatch(typeof(Renderer), "set_sharedMaterial")]
internal static class MeshRenderer_set_sharedMaterial_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(MeshRenderer __instance, ref Material value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = SCP173Runtime.ExpectedMaterial;
return false;
}
}
[HarmonyPatch(typeof(Renderer), "set_material")]
internal static class Renderer_set_material_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Renderer __instance, ref Material value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = SCP173Runtime.ExpectedMaterial;
return false;
}
}
[HarmonyPatch(typeof(GameObject), "AddComponent", new Type[] { typeof(Type) })]
internal static class GameObject_AddComponent_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(GameObject __instance, Type componentType)
{
if (!SCP173UnityProtectionPatches.Is173(__instance))
{
return true;
}
return false;
}
}
[HarmonyPatch(typeof(Collider), "set_enabled")]
internal static class Collider_set_enabled_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Collider __instance, ref bool value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = true;
return false;
}
}
[HarmonyPatch(typeof(Rigidbody), "set_isKinematic")]
internal static class Rigidbody_set_isKinematic_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Rigidbody __instance, ref bool value)
{
if (!SCP173UnityProtectionPatches.Is173((Component)(object)__instance))
{
return true;
}
value = true;
return false;
}
}
[HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object) })]
internal static class Object_Destroy_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Object obj)
{
if (SCP173Runtime.InternalMutation)
{
return true;
}
if (!SCP173UnityProtectionPatches.Is173((Component)(object)((obj is Component) ? obj : null)))
{
return !SCP173UnityProtectionPatches.Is173((GameObject)(object)((obj is GameObject) ? obj : null));
}
return false;
}
}
[HarmonyPatch(typeof(Object), "DestroyImmediate", new Type[] { typeof(Object) })]
internal static class Object_DestroyImmediate_SCP173_Patch
{
[HarmonyPrefix]
private static bool Prefix(Object obj)
{
if (SCP173Runtime.InternalMutation)
{
return true;
}
if (!SCP173UnityProtectionPatches.Is173((Component)(object)((obj is Component) ? obj : null)))
{
return !SCP173UnityProtectionPatches.Is173((GameObject)(object)((obj is GameObject) ? obj : null));
}
return false;
}
}
public static class UnitRegistry
{
private static readonly HashSet<Unit> s_liveUnits = new HashSet<Unit>();
public static void Register(Unit unit)
{
if (!((Object)(object)unit == (Object)null) && !SCP173Runtime.IsReferenceProxy(unit))
{
s_liveUnits.Add(unit);
}
}
public static void Unregister(Unit unit)
{
if (!((Object)(object)unit == (Object)null))
{
s_liveUnits.Remove(unit);
}
}
public static void GetAllLivingUnits(List<Unit> buffer)
{
buffer.Clear();
foreach (Unit s_liveUnit in s_liveUnits)
{
if ((Object)(object)s_liveUnit != (Object)null && !SCP173Runtime.IsReferenceProxy(s_liveUnit) && !SCP173Runtime.HasNeckBeenBroken(s_liveUnit) && !s_liveUnit.dead)
{
buffer.Add(s_liveUnit);
}
}
}
public static void Clear()
{
s_liveUnits.Clear();
}
}
public static class WinAndProtectionPatches
{
[HarmonyPatch(typeof(Unit), "set_RuntimeReference")]
private static class Unit_RuntimeReference_Patch
{
[HarmonyPostfix]
private static void Postfix(Unit __instance)
{
if (DummyUnitFactory.IsDummy(__instance))
{
SCP173Runtime.BindReference(__instance);
}
}
}
[HarmonyPatch(typeof(Unit), "DestroyUnit")]
private static class Unit_DestroyUnit_Patch
{
[HarmonyPrefix]
private static bool Prefix(Unit __instance)
{
return !SCP173Runtime.IsProtectedUnit(__instance);
}
}
[HarmonyPatch(typeof(HealthHandler), "TakeDamage")]
private static class HealthHandler_TakeDamage_Patch
{
[HarmonyPrefix]
private static bool Prefix(HealthHandler __instance)
{
return !SCP173Runtime.IsProtectedUnit(((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent<Unit>() : null);
}
}
[HarmonyPatch(typeof(HealthHandler), "Die", new Type[] { typeof(Unit) })]
private static class HealthHandler_Die_Patch
{
[HarmonyPrefix]
private static bool Prefix(HealthHandler __instance)
{
return !SCP173Runtime.IsProtectedUnit(((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent<Unit>() : null);
}
}
[HarmonyPatch(typeof(WinConditionPropagator), "OnUnitDied")]
private static class WinConditionPropagator_OnUnitDied_Patch
{
[HarmonyPrefix]
private static bool Prefix(Unit unit)
{
return !SCP173Runtime.IsProtectedUnit(unit);
}
}
[HarmonyPatch(typeof(WinConditionPropagator), "IsUnitMustKill")]
private static class WinConditionPropagator_IsUnitMustKill_Patch
{
[HarmonyPrefix]
private static bool Prefix(Unit unit, ref WinCondition mustKillUnitWinCondition)
{
if (!SCP173Runtime.IsProtectedUnit(unit))
{
return true;
}
mustKillUnitWinCondition = null;
return false;
}
}
[HarmonyPatch(typeof(WinConditionEvaluator), "IsUnitMustKill")]
private static class WinConditionEvaluator_IsUnitMustKill_Patch
{
[HarmonyPostfix]
private static void Postfix(Unit unit, ref bool __result, ref WinCondition mustKillUnitWinCondition)
{
if (SCP173Runtime.IsProtectedUnit(unit))
{
__result = false;
mustKillUnitWinCondition = null;
}
}
}
[HarmonyPatch(typeof(TeamSystem), "TriggerUnitDeathAction")]
private static class TeamSystem_TriggerUnitDeathAction_Patch
{
[HarmonyPrefix]
private static bool Prefix(Unit unit)
{
return !SCP173Runtime.IsProtectedUnit(unit);
}
}
[HarmonyPatch(typeof(BaseGameMode), "DecideWinner")]
private static class BaseGameMode_DecideWinner_Patch
{
[HarmonyPrefix]
private static bool Prefix()
{
return !SCP173Runtime.HasSpawned;
}
}
[HarmonyPatch(typeof(BaseGameMode), "OnWinnerDecided")]
private static class BaseGameMode_OnWinnerDecided_Patch
{
[HarmonyPrefix]
private static bool Prefix()
{
return !SCP173Runtime.HasSpawned;
}
}
[HarmonyPatch(typeof(OnlineMultiplayerGameMode), "DecideWinner")]
private static class Online_DecideWinner_Patch
{
[HarmonyPrefix]
private static bool Prefix()
{
return !SCP173Runtime.HasSpawned;
}
}
[HarmonyPatch(typeof(OnlineMultiplayerGameMode), "OnWinnerDecided")]
private static class Online_OnWinnerDecided_Patch
{
[HarmonyPrefix]
private static bool Prefix()
{
return !SCP173Runtime.HasSpawned;
}
}
[HarmonyPatch(typeof(BaseGameMode), "set_MatchOver")]
private static class BaseGameMode_MatchOverSetter_Patch
{
[HarmonyPrefix]
private static bool Prefix(bool value)
{
if (value && SCP173Runtime.HasSpawned)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(TimeService), "Pause")]
private static class TimeService_Pause_Patch
{
[HarmonyPostfix]
private static void Postfix()
{
SCP173Runtime.MarkTimeServiceTouched();
}
}
[HarmonyPatch(typeof(TimeService), "UnPause")]
private static class TimeService_UnPause_Patch
{
[HarmonyPostfix]
private static void Postfix()
{
SCP173Runtime.MarkTimeServiceTouched();
}
}
[HarmonyPatch(typeof(TimeService), "SetState", new Type[]
{
typeof(float),
typeof(float),
typeof(bool)
})]
private static class TimeService_SetState_Patch
{
[HarmonyPostfix]
private static void Postfix()
{
SCP173Runtime.MarkTimeServiceTouched();
}
}
}
}