using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MoreMonsters")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7f96bbc17733f661ae61317e555408d81bbe3f9e")]
[assembly: AssemblyProduct("MoreMonsters")]
[assembly: AssemblyTitle("MoreMonsters")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 MoreMonsters
{
internal sealed class MonsterDef
{
public byte Id;
public string Name;
public string Model;
public bool Flies;
public bool Ranged;
public string Blurb;
public string BaseEnemy;
public float Chance;
public float Health;
public float Damage;
public float Speed;
public float Size;
public int FirstWave;
public bool InWaves = true;
public ConfigEntry<bool> Enabled;
public ConfigEntry<float> ChanceCfg;
public ConfigEntry<float> HealthCfg;
public ConfigEntry<float> DamageCfg;
public ConfigEntry<float> SpeedCfg;
public ConfigEntry<float> SizeCfg;
public ConfigEntry<int> FirstWaveCfg;
public ConfigEntry<string> BaseCfg;
public bool On
{
get
{
if (Enabled != null)
{
return Enabled.Value;
}
return true;
}
}
}
internal static class Defs
{
internal static readonly List<MonsterDef> All = new List<MonsterDef>
{
new MonsterDef
{
Id = 1,
Name = "Zanne",
Model = "Big_Orc",
Blurb = "A big green orc with a spiked club: tough, slow, hits hard, and little orcs jump out when she falls.",
BaseEnemy = "Crabling",
Chance = 5f,
FirstWave = 2,
Health = 6f,
Damage = 1.5f,
Speed = 0.75f,
Size = 2.2f
},
new MonsterDef
{
Id = 2,
Name = "ZanneSmall",
Model = "Blob_Orc",
InWaves = false,
Blurb = "The little orcs that jump out of Zanne.",
BaseEnemy = "Crabling",
Chance = 0f,
FirstWave = 1,
Health = 1.5f,
Damage = 1f,
Speed = 1.25f,
Size = 1.1f
},
new MonsterDef
{
Id = 3,
Name = "Boomshroom",
Model = "Blob_Mushnub_Evolved",
Blurb = "A spiky mushroom that waddles up to you and explodes.",
BaseEnemy = "ExplodingTick",
Chance = 3f,
FirstWave = 3,
Health = 1.5f,
Damage = 1.3f,
Speed = 1f,
Size = 1.4f
},
new MonsterDef
{
Id = 4,
Name = "Cactoro",
Model = "Big_Cactoro",
Ranged = true,
Blurb = "A cactus in a sombrero that keeps its distance and spits at you.",
BaseEnemy = "Spitter",
Chance = 3f,
FirstWave = 4,
Health = 2f,
Damage = 1f,
Speed = 1f,
Size = 1.6f
},
new MonsterDef
{
Id = 5,
Name = "Wraith",
Model = "Flying_Ghost",
Flies = true,
Blurb = "A ghost: fast and fragile, flies straight at you.",
BaseEnemy = "Crabling",
Chance = 3f,
FirstWave = 1,
Health = 0.6f,
Damage = 1f,
Speed = 1.7f,
Size = 1.3f
},
new MonsterDef
{
Id = 6,
Name = "Prickles",
Model = "Blob_GreenSpikyBlob",
Blurb = "A spiky green blob: slow, very tough, and it hurts to touch.",
BaseEnemy = "FleshCrab",
Chance = 3f,
FirstWave = 5,
Health = 3f,
Damage = 1.5f,
Speed = 0.7f,
Size = 1.5f
},
new MonsterDef
{
Id = 7,
Name = "Buzz",
Model = "Flying_Armabee_Evolved",
Flies = true,
Blurb = "An armoured bee that flies in from above.",
BaseEnemy = "FlyingManta",
Chance = 3f,
FirstWave = 6,
Health = 1.2f,
Damage = 1f,
Speed = 1.2f,
Size = 1.2f
},
new MonsterDef
{
Id = 8,
Name = "Yeti",
Model = "Big_Yeti",
Blurb = "A yeti: slow and very tough, punches hard.",
BaseEnemy = "FleshCrab",
Chance = 2f,
FirstWave = 6,
Health = 4f,
Damage = 1.4f,
Speed = 0.8f,
Size = 2f
},
new MonsterDef
{
Id = 9,
Name = "Demon",
Model = "Big_Demon",
Blurb = "A red demon with a trident.",
BaseEnemy = "Crabling",
Chance = 2f,
FirstWave = 5,
Health = 2.5f,
Damage = 1.5f,
Speed = 1.1f,
Size = 1.7f
},
new MonsterDef
{
Id = 10,
Name = "Dragon",
Model = "Flying_Dragon_Evolved",
Flies = true,
Blurb = "A winged dragon: tough and hits hard.",
BaseEnemy = "FlyingManta",
Chance = 2f,
FirstWave = 8,
Health = 4f,
Damage = 1.5f,
Speed = 1f,
Size = 1.8f
},
new MonsterDef
{
Id = 11,
Name = "Ninja",
Model = "Big_Ninja",
Blurb = "A ninja: very fast, not very tough.",
BaseEnemy = "Crabling",
Chance = 2f,
FirstWave = 4,
Health = 1.2f,
Damage = 1.2f,
Speed = 1.6f,
Size = 1.5f
},
new MonsterDef
{
Id = 12,
Name = "MushroomKing",
Model = "Big_MushroomKing",
Blurb = "A rare giant: the Mushroom King and his mace. Huge health.",
BaseEnemy = "FleshCrab",
Chance = 0.5f,
FirstWave = 10,
Health = 15f,
Damage = 2f,
Speed = 0.7f,
Size = 3f
},
new MonsterDef
{
Id = 13,
Name = "Squidle",
Model = "Flying_Squidle",
Flies = true,
Ranged = true,
Blurb = "A horned flying imp that spits from a distance.",
BaseEnemy = "Spitter",
Chance = 2f,
FirstWave = 7,
Health = 1.5f,
Damage = 1f,
Speed = 1f,
Size = 1.5f
},
new MonsterDef
{
Id = 14,
Name = "Tribal",
Model = "Big_Tribal",
Blurb = "A masked warrior.",
BaseEnemy = "Crabling",
Chance = 2f,
FirstWave = 9,
Health = 3f,
Damage = 1.5f,
Speed = 1f,
Size = 1.8f
}
};
internal static MonsterDef ById(int id)
{
foreach (MonsterDef item in All)
{
if (item.Id == id)
{
return item;
}
}
return null;
}
internal static MonsterDef ByName(string name)
{
foreach (MonsterDef item in All)
{
if (item.Name == name)
{
return item;
}
}
return null;
}
internal static void Bind(ConfigFile cfg)
{
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Expected O, but got Unknown
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Expected O, but got Unknown
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Expected O, but got Unknown
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: Expected O, but got Unknown
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Expected O, but got Unknown
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
foreach (MonsterDef item in All)
{
string name = item.Name;
if (item.InWaves)
{
item.Enabled = cfg.Bind<bool>(name, "Enabled", true, item.Blurb + " (host)");
item.ChanceCfg = cfg.Bind<float>(name, "ChancePercent", item.Chance, new ConfigDescription("Chance that a normal wave enemy is a " + name + " instead.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
item.FirstWaveCfg = cfg.Bind<int>(name, "FirstWave", item.FirstWave, new ConfigDescription("First wave of a run a " + name + " can appear in.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
}
item.BaseCfg = cfg.Bind<string>(name, "BaseEnemy", item.BaseEnemy, "The game enemy a " + name + " is built on: its movement and attacks (an EnemyType name: Crabling, FleshCrab, Spitter, ExplodingTick, FlyingManta, Toad...).");
item.HealthCfg = cfg.Bind<float>(name, "HealthMultiplier", item.Health, new ConfigDescription("Health compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
item.DamageCfg = cfg.Bind<float>(name, "DamageMultiplier", item.Damage, new ConfigDescription("Touch damage compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
item.SpeedCfg = cfg.Bind<float>(name, "SpeedMultiplier", item.Speed, new ConfigDescription("Speed compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
item.SizeCfg = cfg.Bind<float>(name, "Size", item.Size, new ConfigDescription("Size compared to the enemy it's built on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 6f), Array.Empty<object>()));
}
}
}
internal static class HostConfig
{
private static ConfigFile cfg;
private static string messageName;
private static string[] personal;
private static Dictionary<string, string> whenHostLacksMod;
private static Func<bool> active;
private static HandleNamedMessageDelegate handler;
private static IntPtr registeredOn;
private static float nextSend;
private static float joinedAt;
private static string lastSent;
private static string lastApplied;
private static bool overriding;
private static bool heardFromHost;
private static bool warnedMissing;
private static bool savedFlag;
private static bool savingPersonal;
private static readonly Dictionary<ConfigEntryBase, string> originals = new Dictionary<ConfigEntryBase, string>();
internal static bool FromHost
{
get
{
if (overriding)
{
return heardFromHost;
}
return false;
}
}
internal static void Init(BasePlugin plugin, string guid, string[] personalKeys, Dictionary<string, string> offWithoutHost, Func<bool> isActive = null)
{
cfg = plugin.Config;
messageName = guid + ".HostConfig";
personal = personalKeys ?? Array.Empty<string>();
whenHostLacksMod = offWithoutHost ?? new Dictionary<string, string>();
active = isActive;
cfg.SettingChanged += OnSettingChanged;
plugin.AddComponent<HostConfigRunner>();
}
private static void OnSettingChanged(object sender, SettingChangedEventArgs e)
{
try
{
if (overriding && !savingPersonal && IsPersonal(e.ChangedSetting.Definition))
{
SavePersonal();
}
}
catch
{
}
}
private static string Id(ConfigDefinition d)
{
return d.Section + "." + d.Key;
}
private static bool IsPersonal(ConfigDefinition d)
{
string[] array = personal;
foreach (string text in array)
{
if (text.EndsWith(".*") ? (d.Section == text.Substring(0, text.Length - 2)) : (Id(d) == text))
{
return true;
}
}
return false;
}
internal static void Tick()
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
try
{
NetworkManager singleton = NetworkManager.Singleton;
bool flag = (Object)(object)singleton != (Object)null && singleton.IsListening;
if (!flag || singleton.IsServer || (active != null && !active()))
{
if (overriding)
{
Restore();
}
if (flag && singleton.IsServer)
{
HostTick(singleton);
}
if (!flag)
{
registeredOn = IntPtr.Zero;
}
}
else
{
ClientTick(singleton);
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag2 = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(15, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Host settings: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
private static void HostTick(NetworkManager nm)
{
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
if (Time.unscaledTime < nextSend || nm.CustomMessagingManager == null)
{
return;
}
nextSend = Time.unscaledTime + 1.5f;
List<string> list = new List<string>();
foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in cfg)
{
if (!IsPersonal(item.Key))
{
list.Add(item.Key.Section + "\u001f" + item.Key.Key + "\u001f" + item.Value.GetSerializedValue());
}
}
string text = string.Join("\u001e", list);
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(text.Length * 2 + 64, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
nm.CustomMessagingManager.SendNamedMessageToAll(messageName, val, (NetworkDelivery)4);
}
finally
{
((FastBufferWriter)(ref val)).Dispose();
}
if (text != lastSent)
{
lastSent = text;
Plugin.Log.LogInfo((object)"Sending this game's settings to all players.");
}
}
private static void ClientTick(NetworkManager nm)
{
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
CustomMessagingManager customMessagingManager = nm.CustomMessagingManager;
if (customMessagingManager != null && registeredOn != ((Il2CppObjectBase)customMessagingManager).Pointer)
{
if (handler == null)
{
handler = DelegateSupport.ConvertDelegate<HandleNamedMessageDelegate>((Delegate)new Action<ulong, FastBufferReader>(OnReceived));
}
customMessagingManager.RegisterNamedMessageHandler(messageName, handler);
registeredOn = ((Il2CppObjectBase)customMessagingManager).Pointer;
}
if (!overriding)
{
Begin();
joinedAt = Time.unscaledTime;
foreach (KeyValuePair<string, string> item in whenHostLacksMod)
{
Set(item.Key, item.Value);
}
}
if (!heardFromHost && !warnedMissing && Time.unscaledTime - joinedAt > 15f)
{
warnedMissing = true;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(88, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No settings from the host: the host doesn't seem to have ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MoreMonsters");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", so it stays off in this game.");
}
log.LogWarning(val);
}
}
private static void OnReceived(ulong sender, FastBufferReader reader)
{
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
bool flag = default(bool);
try
{
string text = default(string);
((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
if (!overriding)
{
Begin();
}
heardFromHost = true;
if (text == lastApplied)
{
return;
}
lastApplied = text;
int num = 0;
string[] array = text.Split('\u001e');
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split('\u001f');
if (array2.Length == 3)
{
ConfigDefinition d = new ConfigDefinition(array2[0], array2[1]);
if (!IsPersonal(d) && Set(Id(d), array2[2]))
{
num++;
}
}
}
ManualLogSource log = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Using the host's settings (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" values).");
}
log.LogInfo(val);
}
catch (Exception ex)
{
ManualLogSource log2 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Host settings (receive): ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
log2.LogError(val2);
}
}
private static void Begin()
{
overriding = true;
heardFromHost = false;
warnedMissing = false;
lastApplied = null;
savedFlag = cfg.SaveOnConfigSet;
cfg.SaveOnConfigSet = false;
}
private static bool Set(string id, string value)
{
foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in cfg)
{
if (!(Id(item.Key) != id))
{
ConfigEntryBase value2 = item.Value;
if (!originals.ContainsKey(value2))
{
originals[value2] = value2.GetSerializedValue();
}
if (value2.GetSerializedValue() != value)
{
value2.SetSerializedValue(value);
}
return true;
}
}
return false;
}
private static void SavePersonal()
{
savingPersonal = true;
Dictionary<ConfigEntryBase, string> dictionary = new Dictionary<ConfigEntryBase, string>();
try
{
foreach (KeyValuePair<ConfigEntryBase, string> original in originals)
{
dictionary[original.Key] = original.Key.GetSerializedValue();
original.Key.SetSerializedValue(original.Value);
}
cfg.Save();
}
finally
{
foreach (KeyValuePair<ConfigEntryBase, string> item in dictionary)
{
try
{
item.Key.SetSerializedValue(item.Value);
}
catch
{
}
}
savingPersonal = false;
}
}
private static void Restore()
{
foreach (KeyValuePair<ConfigEntryBase, string> original in originals)
{
try
{
original.Key.SetSerializedValue(original.Value);
}
catch
{
}
}
originals.Clear();
overriding = false;
heardFromHost = false;
lastApplied = null;
cfg.SaveOnConfigSet = savedFlag;
try
{
cfg.Save();
}
catch
{
}
Plugin.Log.LogInfo((object)"Left the game; back to this computer's own settings.");
}
}
public class HostConfigRunner : MonoBehaviour
{
public HostConfigRunner(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
HostConfig.Tick();
}
}
[HarmonyPatch]
internal static class Monsters
{
private const string MessageName = "girthy_mods.MoreMonsters.Marks";
private static HandleNamedMessageDelegate handler;
private static IntPtr registeredOn;
private static MonsterDef pending;
private static int pendingFrame;
private static readonly Dictionary<ulong, MonsterDef> marked = new Dictionary<ulong, MonsterDef>();
private static readonly HashSet<IntPtr> applied = new HashSet<IntPtr>();
private static readonly Dictionary<ulong, (MonsterDef def, float until)> waiting = new Dictionary<ulong, (MonsterDef, float)>();
private static readonly List<(Vector3 pos, int count)> splits = new List<(Vector3, int)>();
private static readonly HashSet<string> missingBase = new HashSet<string>();
private static readonly HashSet<string> seenThisRun = new HashSet<string>();
private static float nextBroadcast;
private static float nextLookup;
private static int debugNext;
private static bool IsHost
{
get
{
try
{
NetworkManager singleton = NetworkManager.Singleton;
return (Object)(object)singleton == (Object)null || !singleton.IsListening || singleton.IsServer;
}
catch
{
return true;
}
}
}
[HarmonyPatch(typeof(EnemySpawner), "GetRandomEnemyForWave")]
[HarmonyPostfix]
private static void WavePick_Postfix(EnemySpawner __instance, ref NetworkObject __result)
{
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Expected O, but got Unknown
try
{
if ((Object)(object)__result == (Object)null || !IsHost)
{
return;
}
int num = WaveNumber();
float num2 = Random.value * 100f;
foreach (MonsterDef item in Defs.All)
{
if (!item.InWaves || !item.On || num < item.FirstWaveCfg.Value)
{
continue;
}
num2 -= item.ChanceCfg.Value;
if (!(num2 >= 0f))
{
NetworkObject val = BasePrefab(__instance, item);
if (!((Object)(object)val == (Object)null))
{
__result = val;
pending = item;
pendingFrame = Time.frameCount;
}
break;
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("MoreMonsters (wave pick): ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
log.LogError(val2);
}
}
[HarmonyPatch(typeof(EnemySpawner), "SpawnEnemy")]
[HarmonyPrefix]
private static void SpawnEnemy_Prefix()
{
if (pending != null && pendingFrame != Time.frameCount)
{
pending = null;
}
}
[HarmonyPatch(typeof(EnemyHealthContainer), "CalculateMaxHealth")]
[HarmonyPostfix]
private static void MaxHealth_Postfix(ref float __result)
{
if (pending != null)
{
__result *= pending.HealthCfg.Value;
}
}
[HarmonyPatch(typeof(EnemySpawner), "SpawnEnemy")]
[HarmonyPostfix]
private static void SpawnEnemy_Postfix(NetworkObject __result)
{
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
MonsterDef monsterDef = pending;
pending = null;
if (monsterDef == null || (Object)(object)__result == (Object)null)
{
return;
}
bool flag = default(bool);
try
{
marked[__result.NetworkObjectId] = monsterDef;
Enemy component = ((Component)__result).GetComponent<Enemy>();
if ((Object)(object)component != (Object)null)
{
SetSpeed(component, monsterDef.SpeedCfg.Value);
Apply(component, monsterDef);
}
nextBroadcast = 0f;
if (monsterDef.InWaves && seenThisRun.Add(monsterDef.Name))
{
ManualLogSource log = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("First ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(monsterDef.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" of this run has appeared.");
}
log.LogInfo(val);
}
}
catch (Exception ex)
{
ManualLogSource log2 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("MoreMonsters (after spawn): ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
log2.LogError(val2);
}
}
private static NetworkObject BasePrefab(EnemySpawner s, MonsterDef d)
{
//IL_0022: 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_005a: Expected O, but got Unknown
Dictionary<EnemyType, NetworkObject> enemyTypeToPrefab = s.enemyTypeToPrefab;
if (enemyTypeToPrefab == null)
{
return null;
}
NetworkObject val = default(NetworkObject);
if (Enum.TryParse<EnemyType>(d.BaseCfg.Value, ignoreCase: true, out EnemyType result) && enemyTypeToPrefab.TryGetValue(result, ref val) && (Object)(object)val != (Object)null)
{
return val;
}
if (missingBase.Add(d.Name))
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(53, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(d.Name);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": no '");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(d.BaseCfg.Value);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' enemy in this game; using a Crabling instead.");
}
log.LogWarning(val2);
}
NetworkObject result2 = default(NetworkObject);
if (!enemyTypeToPrefab.TryGetValue((EnemyType)0, ref result2))
{
return null;
}
return result2;
}
private static void SetSpeed(Enemy e, float mult)
{
if (Mathf.Approximately(mult, 1f))
{
return;
}
try
{
NavMeshEnemyNavigator componentInChildren = ((Component)e).GetComponentInChildren<NavMeshEnemyNavigator>();
if ((Object)(object)componentInChildren != (Object)null)
{
componentInChildren.baseSpeed *= mult;
}
}
catch
{
}
try
{
NavMeshAgent componentInChildren2 = ((Component)e).GetComponentInChildren<NavMeshAgent>();
if ((Object)(object)componentInChildren2 != (Object)null)
{
componentInChildren2.speed *= mult;
}
}
catch
{
}
}
private static int WaveNumber()
{
try
{
RunManager val = Object.FindObjectOfType<RunManager>();
return (((val != null) ? val.CurrentWave : null) != null) ? (val.CurrentWave.Value + 1) : 0;
}
catch
{
return 0;
}
}
[HarmonyPatch(typeof(EnemyHealthContainer), "SetHealthDepletedOnOwner")]
[HarmonyPostfix]
private static void Depleted_Postfix(EnemyHealthContainer __instance)
{
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Expected O, but got Unknown
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!IsHost)
{
return;
}
NetworkObject componentInParent = ((Component)__instance).GetComponentInParent<NetworkObject>();
if (!((Object)(object)componentInParent == (Object)null) && marked.TryGetValue(componentInParent.NetworkObjectId, out var value))
{
marked.Remove(componentInParent.NetworkObjectId);
if (value.Name == "Zanne" && Plugin.ZanneSplits.Value > 0)
{
splits.Add((((Component)componentInParent).transform.position, Plugin.ZanneSplits.Value));
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters (death): ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
private static void SpawnSplits()
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: 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_00bb: 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)
if (splits.Count == 0)
{
return;
}
MonsterDef monsterDef = Defs.ByName("ZanneSmall");
EnemySpawner val = Spawner();
NetworkObject val2 = (((Object)(object)val != (Object)null && monsterDef != null) ? BasePrefab(val, monsterDef) : null);
List<(Vector3, int)> list = new List<(Vector3, int)>(splits);
splits.Clear();
if ((Object)(object)val2 == (Object)null)
{
return;
}
foreach (var item3 in list)
{
Vector3 item = item3.Item1;
int item2 = item3.Item2;
for (int i = 0; i < item2; i++)
{
float num = ((float)i + Random.value * 0.5f) / (float)item2 * (float)Math.PI * 2f;
SpawnOne(val, val2, item + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 1.6f, monsterDef);
}
}
}
private static void SpawnOne(EnemySpawner s, NetworkObject prefab, Vector3 at, MonsterDef def)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
pending = def;
pendingFrame = Time.frameCount;
try
{
s.SpawnEnemy(prefab, at, (EnemySpawnRotation)0);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(23, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters (spawn ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
finally
{
pending = null;
}
}
private static EnemySpawner Spawner()
{
try
{
return Object.FindObjectOfType<EnemySpawner>();
}
catch
{
return null;
}
}
private static void SpawnKey()
{
//IL_001e: 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_00c9: 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_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: 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_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: 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_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Expected O, but got Unknown
//IL_0101: 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)
string value = Plugin.SpawnKey.Value;
if (string.IsNullOrEmpty(value) || !Enum.TryParse<Key>(value, ignoreCase: true, out Key result) || (int)result == 0)
{
return;
}
Keyboard current = Keyboard.current;
KeyControl val = ((current != null) ? current[result] : null);
if (val == null || !((ButtonControl)val).wasPressedThisFrame)
{
return;
}
List<MonsterDef> list = Defs.All.FindAll((MonsterDef d) => d.InWaves);
if (list.Count == 0)
{
return;
}
MonsterDef monsterDef = list[debugNext++ % list.Count];
EnemySpawner val2 = Spawner();
NetworkObject val3 = (((Object)(object)val2 != (Object)null) ? BasePrefab(val2, monsterDef) : null);
if ((Object)(object)val3 == (Object)null)
{
Plugin.Log.LogWarning((object)"MoreMonsters: no run (or no enemy to build on) right now.");
return;
}
Vector3 val4 = Vector3.zero;
foreach (GameplayPlayer item in Object.FindObjectsOfType<GameplayPlayer>())
{
if ((Object)(object)item != (Object)null && ((NetworkBehaviour)item).IsOwner)
{
val4 = ((Component)item).transform.position;
break;
}
}
Vector2 insideUnitCircle = Random.insideUnitCircle;
Vector2 val5 = ((Vector2)(ref insideUnitCircle)).normalized * 7f;
SpawnOne(val2, val3, val4 + new Vector3(val5.x, 0f, val5.y), monsterDef);
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val6 = new BepInExInfoLogInterpolatedStringHandler(23, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Spawned a ");
((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(monsterDef.Name);
((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(" (debug key).");
}
log.LogInfo(val6);
}
private static void Apply(Enemy e, MonsterDef def)
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
//IL_0027: 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)e == (Object)null || def == null || !applied.Add(((Il2CppObjectBase)e).Pointer))
{
return;
}
try
{
Transform transform = ((Component)e).transform;
transform.localScale *= def.SizeCfg.Value;
}
catch
{
}
if (!Mathf.Approximately(def.DamageCfg.Value, 1f))
{
try
{
e.contactDamage *= def.DamageCfg.Value;
e.SetDamageInfo();
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(11, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(def.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (damage): ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogWarning(val);
}
}
Visuals.Attach(e, def);
}
[HarmonyPatch(typeof(EnemyHealthContainer), "PerformHitFeedback")]
[HarmonyPostfix]
private static void Hit_Postfix(EnemyHealthContainer __instance)
{
try
{
Enemy componentInParent = ((Component)__instance).GetComponentInParent<Enemy>();
if ((Object)(object)componentInParent != (Object)null && Visuals.Has(componentInParent))
{
Visuals.Hit(componentInParent);
}
}
catch
{
}
}
[HarmonyPatch(typeof(EnemyHealthContainer), "HealthDepleted")]
[HarmonyPostfix]
private static void Died_Postfix(EnemyHealthContainer __instance)
{
try
{
Enemy componentInParent = ((Component)__instance).GetComponentInParent<Enemy>();
if ((Object)(object)componentInParent != (Object)null && Visuals.Has(componentInParent))
{
Visuals.Died(componentInParent);
}
}
catch
{
}
}
[HarmonyPatch(typeof(RunManager), "OnDestroy")]
[HarmonyPostfix]
private static void RunEnded()
{
marked.Clear();
applied.Clear();
waiting.Clear();
splits.Clear();
missingBase.Clear();
seenThisRun.Clear();
Visuals.Clear();
}
internal static void Tick()
{
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Expected O, but got Unknown
try
{
NetworkManager singleton = NetworkManager.Singleton;
bool flag = (Object)(object)singleton != (Object)null && singleton.IsListening;
if (flag && singleton.CustomMessagingManager != null && registeredOn != ((Il2CppObjectBase)singleton.CustomMessagingManager).Pointer)
{
if (handler == null)
{
handler = DelegateSupport.ConvertDelegate<HandleNamedMessageDelegate>((Delegate)new Action<ulong, FastBufferReader>(OnMessage));
}
singleton.CustomMessagingManager.RegisterNamedMessageHandler("girthy_mods.MoreMonsters.Marks", handler);
registeredOn = ((Il2CppObjectBase)singleton.CustomMessagingManager).Pointer;
}
if (!flag)
{
registeredOn = IntPtr.Zero;
}
if (IsHost)
{
SpawnSplits();
SpawnKey();
if (flag && Time.unscaledTime >= nextBroadcast)
{
nextBroadcast = Time.unscaledTime + 2f;
Broadcast(singleton);
}
}
else if (waiting.Count > 0 && Time.unscaledTime >= nextLookup)
{
nextLookup = Time.unscaledTime + 0.1f;
Resolve(singleton);
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag2 = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(14, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
try
{
Visuals.Tick();
}
catch
{
}
}
private static void Broadcast(NetworkManager nm)
{
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
if (nm.CustomMessagingManager == null)
{
return;
}
NetworkSpawnManager spawnManager = nm.SpawnManager;
Dictionary<ulong, NetworkObject> val = ((spawnManager != null) ? spawnManager.SpawnedObjects : null);
if (val != null)
{
List<ulong> list = new List<ulong>();
foreach (ulong key in marked.Keys)
{
if (!val.ContainsKey(key))
{
list.Add(key);
}
}
foreach (ulong item in list)
{
marked.Remove(item);
}
}
if (marked.Count == 0)
{
return;
}
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<ulong, MonsterDef> item2 in marked)
{
if (stringBuilder.Length > 0)
{
stringBuilder.Append(',');
}
stringBuilder.Append(item2.Key.ToString(CultureInfo.InvariantCulture)).Append(':').Append(item2.Value.Id);
}
string text = stringBuilder.ToString();
FastBufferWriter val2 = default(FastBufferWriter);
((FastBufferWriter)(ref val2))..ctor(text.Length * 2 + 64, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val2)).WriteValueSafe(text, false);
nm.CustomMessagingManager.SendNamedMessageToAll("girthy_mods.MoreMonsters.Marks", val2, (NetworkDelivery)4);
}
finally
{
((FastBufferWriter)(ref val2)).Dispose();
}
}
private static void OnMessage(ulong sender, FastBufferReader reader)
{
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
try
{
string text = default(string);
((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
float item = Time.unscaledTime + 10f;
string[] array = text.Split(',');
foreach (string text2 in array)
{
int num = text2.IndexOf(':');
if (num > 0 && ulong.TryParse(text2.Substring(0, num), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(text2.Substring(num + 1), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
{
MonsterDef monsterDef = Defs.ById(result2);
if (monsterDef != null && !waiting.ContainsKey(result))
{
waiting[result] = (monsterDef, item);
}
}
}
Resolve(NetworkManager.Singleton);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoreMonsters (receive): ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
private static void Resolve(NetworkManager nm)
{
object obj;
if (nm == null)
{
obj = null;
}
else
{
NetworkSpawnManager spawnManager = nm.SpawnManager;
obj = ((spawnManager != null) ? spawnManager.SpawnedObjects : null);
}
Dictionary<ulong, NetworkObject> val = (Dictionary<ulong, NetworkObject>)obj;
if (val == null)
{
return;
}
List<ulong> list = new List<ulong>();
NetworkObject val2 = default(NetworkObject);
foreach (KeyValuePair<ulong, (MonsterDef, float)> item in waiting)
{
if (val.TryGetValue(item.Key, ref val2) && (Object)(object)val2 != (Object)null)
{
Enemy component = ((Component)val2).GetComponent<Enemy>();
if ((Object)(object)component != (Object)null)
{
Apply(component, item.Value.Item1);
}
list.Add(item.Key);
}
else if (Time.unscaledTime > item.Value.Item2)
{
list.Add(item.Key);
}
}
foreach (ulong item2 in list)
{
waiting.Remove(item2);
}
}
}
public class Runner : MonoBehaviour
{
public Runner(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
Monsters.Tick();
}
}
[BepInPlugin("girthy_mods.MoreMonsters", "MoreMonsters", "2.0.2")]
public class Plugin : BasePlugin
{
public const string Guid = "girthy_mods.MoreMonsters";
public const string Name = "MoreMonsters";
public const string Version = "2.0.2";
internal static ManualLogSource Log;
internal static ConfigEntry<int> ZanneSplits;
internal static ConfigEntry<string> SpawnKey;
public override void Load()
{
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Expected O, but got Unknown
//IL_0124: 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_014f: Expected O, but got Unknown
Log = ((BasePlugin)this).Log;
Dictionary<string, string> dictionary = new Dictionary<string, string>();
foreach (MonsterDef item in Defs.All)
{
if (item.InWaves)
{
dictionary[item.Name + ".Enabled"] = "false";
}
}
HostConfig.Init((BasePlugin)(object)this, "girthy_mods.MoreMonsters", new string[1] { "Debug.SpawnKey" }, dictionary);
Defs.Bind(((BasePlugin)this).Config);
ZanneSplits = ((BasePlugin)this).Config.Bind<int>("Zanne", "SplitsInto", 3, new ConfigDescription("Small Zannes that pop out when she dies (0 = none). Their stats are under [ZanneSmall].", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), Array.Empty<object>()));
SpawnKey = ((BasePlugin)this).Config.Bind<string>("Debug", "SpawnKey", "F2", "Host: key that spawns a monster near you to try it out; each press brings the next kind (Unity Input System key name). Empty = no key.");
int num = Visuals.LoadAll();
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" monster looks.");
}
log.LogInfo(val);
new Harmony("girthy_mods.MoreMonsters").PatchAll(typeof(Monsters));
((BasePlugin)this).AddComponent<Runner>();
ManualLogSource log2 = Log;
val = new BepInExInfoLogInterpolatedStringHandler(8, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MoreMonsters");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("2.0.2");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ready.");
}
log2.LogInfo(val);
}
}
internal static class Visuals
{
private sealed class Clip
{
public string Name;
public float Fps;
public int Frames;
public int Bones;
public float[] Data;
public float Length => Mathf.Max(0.01f, (float)(Frames - 1) / Fps);
}
private sealed class Model
{
public string Name;
public Mesh Mesh;
public int Bones;
public Material Mat;
public Clip Idle;
public Clip Walk;
public Clip Run;
public Clip Attack;
public Clip Hit;
public Clip Death;
public float AttackHit;
}
private enum Act
{
Idle,
Walk,
Run,
Attack,
Hit,
Death
}
private sealed class View
{
public MonsterDef Def;
public Model Model;
public Enemy Enemy;
public Transform Root;
public Transform Visuals;
public Transform T;
public GameObject Go;
public SkinnedMeshRenderer Renderer;
public Transform[] Bones;
public Vector3[] LastScale;
public readonly List<Renderer> Hidden = new List<Renderer>();
public float Width = 1f;
public float Lift;
public float Speed;
public float SpawnedAt;
public float FlashUntil;
public float NextHide;
public float NextAttack;
public float NextHit;
public float DiedAt = -1f;
public Vector3 LastPos;
public Quaternion Facing = Quaternion.identity;
public bool Detached;
public Act Act;
public Clip Cur;
public Clip Prev;
public float CurT;
public float PrevT;
public float FadeStart = -9f;
public float FadeLen = 0.15f;
public float Rate = 1f;
public bool OneShot;
public int Slot;
public int Posed;
public float[] PoseA;
public float[] PoseB;
}
private static readonly Dictionary<string, Model> models = new Dictionary<string, Model>();
private static Texture2D atlas;
private static Texture2D white;
private static Material flash;
private static Shader shader;
private static bool shaderSearched;
private static readonly string[] ShaderNames = new string[6] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "Universal Render Pipeline/Baked Lit", "Universal Render Pipeline/Unlit", "Standard", "Unlit/Texture" };
private static readonly Dictionary<IntPtr, View> views = new Dictionary<IntPtr, View>();
private static int Busy;
private static int nextSlot;
private static readonly List<View> corpses = new List<View>();
private static readonly HashSet<string> loggedLook = new HashSet<string>();
private static readonly List<Transform> players = new List<Transform>();
private static float nextPlayerScan;
private static int frameNo;
internal static int LoadAll()
{
//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_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Expected O, but got Unknown
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Expected O, but got Unknown
white = MakeTexture(1, 1, (Color32[])(object)new Color32[1]
{
new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
}, (FilterMode)0);
atlas = LoadTexture("Atlas");
if ((Object)(object)atlas == (Object)null)
{
Plugin.Log.LogError((object)"The monsters' colour atlas is missing.");
}
int num = 0;
bool flag = default(bool);
foreach (MonsterDef item in Defs.All)
{
if (models.ContainsKey(item.Model))
{
continue;
}
try
{
Model model = Load(item.Model);
if (model == null)
{
ManualLogSource log = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(17, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": model ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Model);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" missing.");
}
log.LogError(val);
}
else
{
models[item.Model] = model;
num++;
}
}
catch (Exception ex)
{
ManualLogSource log2 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(10, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s model: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log2.LogError(val);
}
}
return num;
}
private static Stream Resource(string name)
{
return typeof(Visuals).Assembly.GetManifestResourceStream("MoreMonsters." + name);
}
private static string ReadName(BinaryReader r)
{
int count = r.ReadUInt16();
return Encoding.UTF8.GetString(r.ReadBytes(count));
}
private static Model Load(string name)
{
//IL_00c9: 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_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: 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_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: 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_0240: Unknown result type (might be due to invalid IL or missing references)
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
//IL_024d: Unknown result type (might be due to invalid IL or missing references)
//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
//IL_05d8: Expected O, but got Unknown
//IL_0642: Unknown result type (might be due to invalid IL or missing references)
//IL_0649: Expected O, but got Unknown
using Stream stream = Resource(name + ".mon");
if (stream == null)
{
return null;
}
using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
using MemoryStream memoryStream = new MemoryStream();
gZipStream.CopyTo(memoryStream);
memoryStream.Position = 0L;
using BinaryReader binaryReader = new BinaryReader(memoryStream);
if (new string(binaryReader.ReadChars(4)) != "MON1")
{
throw new InvalidDataException("not a monster file");
}
int num = binaryReader.ReadInt32();
int num2 = binaryReader.ReadInt32();
int num3 = binaryReader.ReadInt32();
int num4 = binaryReader.ReadInt32();
Il2CppStructArray<Vector3> val = new Il2CppStructArray<Vector3>((long)num);
Il2CppStructArray<Vector3> val2 = new Il2CppStructArray<Vector3>((long)num);
Il2CppStructArray<Vector2> val3 = new Il2CppStructArray<Vector2>((long)num);
Il2CppStructArray<BoneWeight> val4 = new Il2CppStructArray<BoneWeight>((long)num);
for (int i = 0; i < num; i++)
{
((Il2CppArrayBase<Vector3>)(object)val)[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
((Il2CppArrayBase<Vector3>)(object)val2)[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
((Il2CppArrayBase<Vector2>)(object)val3)[i] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
byte boneIndex = binaryReader.ReadByte();
byte boneIndex2 = binaryReader.ReadByte();
byte boneIndex3 = binaryReader.ReadByte();
byte boneIndex4 = binaryReader.ReadByte();
int num5 = i;
BoneWeight val5 = default(BoneWeight);
((BoneWeight)(ref val5)).boneIndex0 = boneIndex;
((BoneWeight)(ref val5)).boneIndex1 = boneIndex2;
((BoneWeight)(ref val5)).boneIndex2 = boneIndex3;
((BoneWeight)(ref val5)).boneIndex3 = boneIndex4;
((BoneWeight)(ref val5)).weight0 = binaryReader.ReadSingle();
((BoneWeight)(ref val5)).weight1 = binaryReader.ReadSingle();
((BoneWeight)(ref val5)).weight2 = binaryReader.ReadSingle();
((BoneWeight)(ref val5)).weight3 = binaryReader.ReadSingle();
((Il2CppArrayBase<BoneWeight>)(object)val4)[num5] = val5;
}
Il2CppStructArray<int> val6 = new Il2CppStructArray<int>((long)(num2 * 3));
for (int j = 0; j < num2 * 3; j++)
{
((Il2CppArrayBase<int>)(object)val6)[j] = binaryReader.ReadInt32();
}
Il2CppStructArray<Matrix4x4> val7 = new Il2CppStructArray<Matrix4x4>((long)num3);
for (int k = 0; k < num3; k++)
{
ReadName(binaryReader);
Vector4[] array = (Vector4[])(object)new Vector4[4];
for (int l = 0; l < 4; l++)
{
array[l] = new Vector4(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
}
((Il2CppArrayBase<Matrix4x4>)(object)val7)[k] = new Matrix4x4(array[0], array[1], array[2], array[3]);
}
Model model = new Model
{
Name = name,
Bones = num3
};
Model model2;
for (int m = 0; m < num4; m++)
{
Clip clip = new Clip
{
Name = ReadName(binaryReader),
Fps = binaryReader.ReadSingle(),
Frames = binaryReader.ReadInt32(),
Bones = num3
};
clip.Data = new float[clip.Frames * num3 * 10];
for (int n = 0; n < clip.Data.Length; n++)
{
clip.Data[n] = binaryReader.ReadSingle();
}
switch (clip.Name)
{
case "Idle":
case "Flying_Idle":
model2 = model;
if (model2.Idle == null)
{
model2.Idle = clip;
}
break;
case "Walk":
model.Walk = clip;
break;
case "Fast_Flying":
case "Run":
model.Run = clip;
break;
case "Punch":
case "Bite_Front":
case "Headbutt":
case "Weapon":
case "Bite_InPlace":
model2 = model;
if (model2.Attack == null)
{
model2.Attack = clip;
}
break;
case "HitRecieve":
case "HitReact":
model.Hit = clip;
break;
case "Death":
model.Death = clip;
break;
}
}
model2 = model;
if (model2.Walk == null)
{
model2.Walk = model.Run ?? model.Idle;
}
model2 = model;
if (model2.Run == null)
{
model2.Run = model.Walk;
}
model2 = model;
if (model2.Idle == null)
{
model2.Idle = model.Walk;
}
model.AttackHit = 0.45f;
Mesh val8 = new Mesh
{
name = "MoreMonsters." + name
};
if (num > 65000)
{
val8.indexFormat = (IndexFormat)1;
}
val8.vertices = val;
val8.normals = val2;
val8.uv = val3;
val8.triangles = val6;
val8.boneWeights = val4;
val8.bindposes = val7;
val8.RecalculateBounds();
((Object)val8).hideFlags = (HideFlags)61;
model.Mesh = val8;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val9 = new BepInExInfoLogInterpolatedStringHandler(34, 4, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<string>(name);
((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(": ");
((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<int>(num2);
((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" triangles, ");
((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<int>(num3);
((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" bones, ");
((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<int>(num4);
((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" animations.");
}
log.LogInfo(val9);
return model;
}
private static Texture2D LoadTexture(string name)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
using Stream stream = Resource(name + ".tex");
if (stream == null)
{
return null;
}
using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
using MemoryStream memoryStream = new MemoryStream();
gZipStream.CopyTo(memoryStream);
byte[] array = memoryStream.ToArray();
int num = BitConverter.ToInt32(array, 0);
int num2 = BitConverter.ToInt32(array, 4);
Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false);
Il2CppStructArray<byte> val2 = new Il2CppStructArray<byte>((long)(num * num2 * 4));
for (int i = 0; i < ((Il2CppArrayBase<byte>)(object)val2).Length; i++)
{
((Il2CppArrayBase<byte>)(object)val2)[i] = array[8 + i];
}
val.LoadRawTextureData(val2);
val.Apply(false, false);
((Texture)val).filterMode = (FilterMode)1;
((Texture)val).wrapMode = (TextureWrapMode)1;
((Object)val).hideFlags = (HideFlags)61;
return val;
}
private static Texture2D MakeTexture(int tw, int th, Color32[] px, FilterMode filter)
{
//IL_0004: 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_0015: 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_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
Texture2D val = new Texture2D(tw, th, (TextureFormat)4, false);
val.SetPixels32(new Il2CppStructArray<Color32>(px));
val.Apply();
((Texture)val).filterMode = filter;
((Texture)val).wrapMode = (TextureWrapMode)1;
((Object)val).hideFlags = (HideFlags)61;
return val;
}
private static Shader FindShader()
{
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Expected O, but got Unknown
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Expected O, but got Unknown
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Expected O, but got Unknown
if (shaderSearched)
{
return shader;
}
shaderSearched = true;
bool flag = default(bool);
try
{
Il2CppArrayBase<Shader> val = Resources.FindObjectsOfTypeAll<Shader>();
Dictionary<string, Shader> dictionary = new Dictionary<string, Shader>();
for (int i = 0; i < val.Length; i++)
{
Shader val2 = val[i];
if (!((Object)(object)val2 == (Object)null))
{
string name = ((Object)val2).name;
if (!string.IsNullOrEmpty(name) && !dictionary.ContainsKey(name))
{
dictionary[name] = val2;
}
}
}
string[] shaderNames = ShaderNames;
foreach (string key in shaderNames)
{
if (dictionary.TryGetValue(key, out var value) && value.isSupported)
{
shader = value;
break;
}
}
if ((Object)(object)shader == (Object)null)
{
List<string> list = new List<string>();
foreach (string key2 in dictionary.Keys)
{
if (list.Count < 40)
{
list.Add(key2);
}
}
ManualLogSource log = Plugin.Log;
BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(43, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("No plain lit shader found. Shaders loaded: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(string.Join(", ", list));
}
log.LogWarning(val3);
}
else
{
ManualLogSource log2 = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Monster shader: ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((Object)shader).name);
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(".");
}
log2.LogInfo(val4);
}
}
catch (Exception ex)
{
ManualLogSource log3 = Plugin.Log;
BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Finding a shader: ");
((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
}
log3.LogError(val5);
}
return shader;
}
private static Material MakeMaterial(Texture2D t)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
Shader val = FindShader();
Material val2 = null;
try
{
if ((Object)(object)val != (Object)null)
{
val2 = new Material(val);
}
}
catch
{
}
if ((Object)(object)val2 == (Object)null)
{
return null;
}
try
{
val2.mainTexture = (Texture)(object)t;
}
catch
{
}
try
{
val2.color = Color.white;
}
catch
{
}
try
{
val2.SetFloat("_Smoothness", 0.12f);
}
catch
{
}
try
{
val2.SetFloat("_Metallic", 0f);
}
catch
{
}
((Object)val2).hideFlags = (HideFlags)61;
return val2;
}
private static Material MaterialFor(Model m)
{
if ((Object)(object)m.Mat == (Object)null || ((Il2CppObjectBase)m.Mat).WasCollected)
{
m.Mat = MakeMaterial(atlas ?? white);
}
return m.Mat;
}
private static Material Flash()
{
if ((Object)(object)flash == (Object)null || ((Il2CppObjectBase)flash).WasCollected)
{
flash = MakeMaterial(white);
}
return flash;
}
internal static bool Has(Enemy e)
{
if ((Object)(object)e != (Object)null)
{
return views.ContainsKey(((Il2CppObjectBase)e).Pointer);
}
return false;
}
internal static void Attach(Enemy e, MonsterDef def)
{
//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_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_046c: Unknown result type (might be due to invalid IL or missing references)
//IL_0473: Expected O, but got Unknown
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_04af: 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_0255: Unknown result type (might be due to invalid IL or missing references)
//IL_025c: Expected O, but got Unknown
//IL_0293: Unknown result type (might be due to invalid IL or missing references)
//IL_029f: 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_0231: 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_0132: 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)
//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0377: Unknown result type (might be due to invalid IL or missing references)
//IL_038b: Unknown result type (might be due to invalid IL or missing references)
//IL_0390: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)e == (Object)null || def == null || views.ContainsKey(((Il2CppObjectBase)e).Pointer) || !models.TryGetValue(def.Model, out var value))
{
return;
}
Material val = MaterialFor(value);
if ((Object)(object)val == (Object)null)
{
return;
}
Transform transform = ((Component)e).transform;
Transform val2 = null;
try
{
val2 = e.visualsRoot;
}
catch
{
}
if ((Object)(object)val2 == (Object)null)
{
val2 = transform;
}
View view = new View
{
Def = def,
Model = value,
Enemy = e,
Root = transform,
Visuals = val2,
SpawnedAt = Time.time,
LastPos = transform.position,
Slot = nextSlot++
};
Bounds val3 = default(Bounds);
bool flag = false;
foreach (Renderer componentsInChild in ((Component)val2).GetComponentsInChildren<Renderer>(true))
{
if ((Object)(object)componentsInChild == (Object)null)
{
continue;
}
string name = ((MemberInfo)((Object)componentsInChild).GetIl2CppType()).Name;
if (name != "MeshRenderer" && name != "SkinnedMeshRenderer")
{
continue;
}
try
{
if (componentsInChild.enabled && ((Component)componentsInChild).gameObject.activeInHierarchy)
{
if (!flag)
{
val3 = componentsInChild.bounds;
flag = true;
}
else
{
((Bounds)(ref val3)).Encapsulate(componentsInChild.bounds);
}
}
componentsInChild.forceRenderingOff = true;
view.Hidden.Add(componentsInChild);
}
catch
{
}
}
foreach (Animator componentsInChild2 in ((Component)e).GetComponentsInChildren<Animator>(true))
{
try
{
componentsInChild2.cullingMode = (AnimatorCullingMode)0;
}
catch
{
}
}
float num = Mathf.Max(0.01f, transform.lossyScale.x);
view.Width = (flag ? Mathf.Clamp(Mathf.Max(((Bounds)(ref val3)).size.x, ((Bounds)(ref val3)).size.z) / num, 0.6f, 2.5f) : 1.2f);
if (flag && def.Flies)
{
view.Lift = Mathf.Max(0f, transform.InverseTransformPoint(((Bounds)(ref val3)).min).y);
}
GameObject val4 = new GameObject("MoreMonsters." + def.Name);
val4.layer = ((Component)val2).gameObject.layer;
Transform transform2 = val4.transform;
transform2.SetParent(transform, false);
transform2.localPosition = new Vector3(0f, view.Lift, 0f);
transform2.localScale = Vector3.zero;
view.Bones = (Transform[])(object)new Transform[value.Bones];
view.LastScale = (Vector3[])(object)new Vector3[value.Bones];
Il2CppReferenceArray<Transform> val5 = new Il2CppReferenceArray<Transform>((long)value.Bones);
for (int i = 0; i < value.Bones; i++)
{
Transform transform3 = new GameObject("b" + i).transform;
transform3.SetParent(transform2, false);
view.Bones[i] = transform3;
((Il2CppArrayBase<Transform>)(object)val5)[i] = transform3;
}
SkinnedMeshRenderer val6 = val4.AddComponent<SkinnedMeshRenderer>();
val6.sharedMesh = value.Mesh;
val6.bones = val5;
val6.rootBone = transform2;
((Renderer)val6).sharedMaterial = val;
val6.updateWhenOffscreen = false;
((Renderer)val6).localBounds = new Bounds(new Vector3(0f, 0.5f, 0f), new Vector3(1.6f, 1.6f, 1.6f));
try
{
((Renderer)val6).shadowCastingMode = (ShadowCastingMode)1;
}
catch
{
}
try
{
val6.quality = (SkinQuality)4;
}
catch
{
}
view.Go = val4;
view.T = transform2;
view.Renderer = val6;
view.PoseA = new float[value.Bones * 10];
view.PoseB = new float[value.Bones * 10];
view.NextAttack = Time.time + Random.Range(0.3f, 1.2f);
Play(view, Act.Idle, value.Idle, oneShot: false, 0f);
Animate(view, Time.time, 0.016f);
views[((Il2CppObjectBase)e).Pointer] = view;
if (!loggedLook.Add(def.Name))
{
return;
}
try
{
ManualLogSource log = Plugin.Log;
bool flag2 = default(bool);
BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(59, 7, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(def.Name);
((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("'s look: ");
((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(value.Name);
((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" on ");
((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<EnemyType>(e.EnemyType);
((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" (");
((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(view.Hidden.Count);
((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" parts hidden, ");
((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<float>(view.Width, "0.##");
((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" wide, lifted ");
((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<float>(view.Lift, "0.##");
((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("), drawn with ");
Shader obj6 = val.shader;
((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>((obj6 != null) ? ((Object)obj6).name : null);
((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(".");
}
log.LogInfo(val7);
}
catch
{
}
}
internal static void Hit(Enemy e)
{
if (!((Object)(object)e == (Object)null) && views.TryGetValue(((Il2CppObjectBase)e).Pointer, out var value))
{
float time = Time.time;
value.FlashUntil = time + 0.08f;
if (value.Model.Hit != null && time >= value.NextHit && value.Act != Act.Attack && value.Act != Act.Death)
{
value.NextHit = time + Random.Range(2.2f, 3.5f);
Play(value, Act.Hit, value.Model.Hit, oneShot: true, 0.08f);
}
}
}
internal static void Died(Enemy e)
{
if ((Object)(object)e == (Object)null || !views.TryGetValue(((Il2CppObjectBase)e).Pointer, out var value) || value.DiedAt >= 0f)
{
return;
}
value.DiedAt = Time.time;
try
{
if ((Object)(object)value.Go != (Object)null && value.Model.Death != null)
{
value.T.SetParent((Transform)null, true);
value.Detached = true;
views.Remove(((Il2CppObjectBase)e).Pointer);
corpses.Add(value);
Play(value, Act.Death, value.Model.Death, oneShot: true, 0.08f);
}
}
catch
{
}
}
internal static void Clear()
{
views.Clear();
foreach (View corpse in corpses)
{
try
{
if ((Object)(object)corpse.Go != (Object)null && !((Il2CppObjectBase)corpse.Go).WasCollected)
{
Object.Destroy((Object)(object)corpse.Go);
}
}
catch
{
}
}
corpses.Clear();
}
private static void ScanPlayers(float now)
{
if (now < nextPlayerScan)
{
return;
}
nextPlayerScan = now + 1.5f;
players.Clear();
try
{
foreach (GameplayPlayer item in Object.FindObjectsOfType<GameplayPlayer>())
{
if ((Object)(object)item != (Object)null && ((Component)item).gameObject.activeInHierarchy)
{
players.Add(((Component)item).transform);
}
}
}
catch
{
}
}
private static float NearestPlayer(Vector3 at)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
float num = float.MaxValue;
foreach (Transform player in players)
{
try
{
if (!((Object)(object)player == (Object)null) && !((Il2CppObjectBase)player).WasCollected)
{
Vector3 val = player.position - at;
val.y = 0f;
num = Mathf.Min(num, ((Vector3)(ref val)).magnitude);
}
}
catch
{
}
}
return num;
}
internal static void Tick()
{
if (views.Count == 0 && corpses.Count == 0)
{
return;
}
frameNo++;
Busy = views.Count + corpses.Count;
float time = Time.time;
float dt = Mathf.Max(Time.deltaTime, 0.0001f);
ScanPlayers(time);
List<IntPtr> list = null;
foreach (KeyValuePair<IntPtr, View> view2 in views)
{
View value = view2.Value;
try
{
if ((Object)(object)value.Enemy == (Object)null || ((Il2CppObjectBase)value.Enemy).WasCollected || (Object)(object)value.Go == (Object)null || ((Il2CppObjectBase)value.Go).WasCollected)
{
(list ?? (list = new List<IntPtr>())).Add(view2.Key);
}
else if (((Component)value.Enemy).gameObject.activeInHierarchy)
{
Decide(value, time, dt);
Animate(value, time, dt);
}
}
catch
{
(list ?? (list = new List<IntPtr>())).Add(view2.Key);
}
}
if (list != null)
{
foreach (IntPtr item in list)
{
views.Remove(item);
}
}
for (int num = corpses.Count - 1; num >= 0; num--)
{
View view = corpses[num];
bool flag;
try
{
flag = (Object)(object)view.Go == (Object)null || ((Il2CppObjectBase)view.Go).WasCollected || !Corpse(view, time, dt);
}
catch
{
flag = true;
}
if (flag)
{
try
{
if ((Object)(object)view.Go != (Object)null && !((Il2CppObjectBase)view.Go).WasCollected)
{
Object.Destroy((Object)(object)view.Go);
}
}
catch
{
}
corpses.RemoveAt(num);
}
}
}
private static void Decide(View v, float now, float dt)
{
//IL_006d: 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_0073: 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_007a: 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_008d: 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)
//IL_00d5: 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_0143: 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_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: 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_0103: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
if (now >= v.NextHide)
{
v.NextHide = now + 0.5f;
foreach (Renderer item in v.Hidden)
{
try
{
if ((Object)(object)item != (Object)null && !item.forceRenderingOff)
{
item.forceRenderingOff = true;
}
}
catch
{
}
}
}
Vector3 position = v.Root.position;
Vector3 val = position - v.LastPos;
val.y = 0f;
v.LastPos = position;
float num = ((Vector3)(ref val)).magnitude / dt;
if (num > 40f)
{
num = 0f;
}
v.Speed = Mathf.Lerp(v.Speed, num, 1f - Mathf.Exp(-8f * dt));
Vector3 val2 = v.Visuals.forward;
val2.y = 0f;
if (((Vector3)(ref val2)).sqrMagnitude < 0.01f && ((Vector3)(ref val)).sqrMagnitude > 0.0001f)
{
val2 = val;
}
if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
{
v.Facing = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up);
}
Model model = v.Model;
float num2 = v.Width * Mathf.Max(0.01f, v.Root.lossyScale.x);
if (v.OneShot && v.CurT < v.Cur.Length)
{
return;
}
float num3 = (v.Def.Ranged ? 13f : (0.9f + num2 * 0.7f));
if (model.Attack != null && now >= v.NextAttack && (!v.Def.Ranged || v.Speed < 1.2f) && NearestPlayer(position) <= num3)
{
v.NextAttack = now + (v.Def.Ranged ? Random.Range(2.2f, 3.2f) : Random.Range(1.2f, 1.8f));
Play(v, Act.Attack, model.Attack, oneShot: true, 0.1f);
return;
}
float num4 = v.Speed / Mathf.Max(0.2f, num2);
if (num4 < 0.15f)
{
Play(v, Act.Idle, model.Idle, oneShot: false, 0.25f);
}
else if (num4 > 1.6f && model.Run != model.Walk)
{
Play(v, Act.Run, model.Run, oneShot: false, 0.2f);
}
else
{
Play(v, Act.Walk, model.Walk, oneShot: false, 0.2f);
}
if (v.Act == Act.Walk)
{
v.Rate = Mathf.Clamp(num4 / 0.9f, 0.6f, 1.8f);
}
else if (v.Act == Act.Run)
{
v.Rate = Mathf.Clamp(num4 / 2.2f, 0.7f, 1.6f);
}
else
{
v.Rate = 1f;
}
}
private static void Play(View v, Act act, Clip clip, bool oneShot, float fade)
{
if (clip != null && (oneShot || v.Act != act || v.Cur != clip))
{
if (v.Cur != null)
{
v.Prev = v.Cur;
v.PrevT = v.CurT;
v.FadeStart = Time.time;
v.FadeLen = Mathf.Max(0.01f, fade);
}
v.Act = act;
v.Cur = clip;
v.CurT = 0f;
v.OneShot = oneShot;
v.Rate = 1f;
}
}
private static void Animate(View v, float now, float dt)
{
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
v.CurT += dt * v.Rate;
float num = ((v.Prev != null) ? Mathf.Clamp01((now - v.FadeStart) / v.FadeLen) : 1f);
if (num < 1f)
{
v.PrevT += dt;
}
else
{
v.Prev = null;
}
bool flag = v.Posed == 0 || Busy <= 10 || ((frameNo + v.Slot) & 1) == 0;
if (flag && v.Posed > 0)
{
try
{
flag = ((Renderer)v.Renderer).isVisible;
}
catch
{
}
}
if (flag)
{
Sample(v.Cur, v.CurT, !v.OneShot, v.PoseA);
if (v.Prev != null)
{
Sample(v.Prev, v.PrevT, loop: true, v.PoseB);
Blend(v.PoseB, v.PoseA, num, v.PoseA);
}
Apply(v);
v.Posed++;
}
float num2 = Mathf.Clamp01((now - v.SpawnedAt) / 0.35f);
float num3 = v.Width * ((num2 < 1f) ? EaseOutBack(num2) : 1f);
if (!v.Detached)
{
v.T.rotation = v.Facing;
v.T.localScale = new Vector3(num3, num3, num3);
v.T.localPosition = new Vector3(0f, v.Lift, 0f);
}
Material val = ((now < v.FlashUntil) ? Flash() : v.Model.Mat);
if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)v.Renderer).sharedMaterial != (Object)(object)val)
{
((Renderer)v.Renderer).sharedMaterial = val;
}
}
private static bool Corpse(View v, float now, float dt)
{
//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_0064: 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)
Animate(v, now, dt);
float num = now - v.DiedAt - (v.Cur?.Length ?? 0f);
if (num > 0.7f)
{
if ((num - 0.7f) / 0.6f >= 1f)
{
return false;
}
Transform t = v.T;
t.position += Vector3.down * (dt * 1.2f * v.T.lossyScale.y);
}
return now - v.DiedAt < 8f;
}
private static void Sample(Clip c, float t, bool loop, float[] outPose)
{
float num = t * c.Fps;
int num2 = c.Frames - 1;
if (loop && num2 > 0)
{
num %= (float)num2;
if (num < 0f)
{
num += (float)num2;
}
}
else
{
num = Mathf.Clamp(num, 0f, (float)num2);
}
int num3 = Mathf.Min((int)num, num2);
int num4 = Mathf.Min(num3 + 1, num2);
float num5 = num - (float)num3;
int num6 = c.Bones * 10;
int num7 = num3 * num6;
int num8 = num4 * num6;
float[] data = c.Data;
int num9 = 0;
int num10 = 0;
while (num9 < c.Bones)
{
int num11 = num7 + num10;
int num12 = num8 + num10;
for (int i = 0; i < 3; i++)
{
outPose[num10 + i] = data[num11 + i] + (data[num12 + i] - data[num11 + i]) * num5;
}
float num13 = ((data[num11 + 3] * data[num12 + 3] + data[num11 + 4] * data[num12 + 4] + data[num11 + 5] * data[num12 + 5] + data[num11 + 6] * data[num12 + 6] < 0f) ? (-1f) : 1f);
float num14 = 0f;
for (int j = 3; j < 7; j++)
{
outPose[num10 + j] = data[num11 + j] + (num13 * data[num12 + j] - data[num11 + j]) * num5;
num14 += outPose[num10 + j] * outPose[num10 + j];
}
num14 = ((num14 > 1E-12f) ? (1f / Mathf.Sqrt(num14)) : 1f);
for (int k = 3; k < 7; k++)
{
outPose[num10 + k] *= num14;
}
for (int l = 7; l < 10; l++)
{
outPose[num10 + l] = data[num11 + l] + (data[num12 + l] - data[num11 + l]) * num5;
}
num9++;
num10 += 10;
}
}
private static void Blend(float[] from, float[] to, float a, float[] outPose)
{
for (int i = 0; i < from.Length; i += 10)
{
for (int j = 0; j < 3; j++)
{
outPose[i + j] = from[i + j] + (to[i + j] - from[i + j]) * a;
}
float num = ((from[i + 3] * to[i + 3] + from[i + 4] * to[i + 4] + from[i + 5] * to[i + 5] + from[i + 6] * to[i + 6] < 0f) ? (-1f) : 1f);
float num2 = 0f;
for (int k = 3; k < 7; k++)
{
outPose[i + k] = from[i + k] + (num * to[i + k] - from[i + k]) * a;
num2 += outPose[i + k] * outPose[i + k];
}
num2 = ((num2 > 1E-12f) ? (1f / Mathf.Sqrt(num2)) : 1f);
for (int l = 3; l < 7; l++)
{
outPose[i + l] *= num2;
}
for (int m = 7; m < 10; m++)
{
outPose[i + m] = from[i + m] + (to[i + m] - from[i + m]) * a;
}
}
}
private static void Apply(View v)
{
//IL_0027: 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_0061: 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_0085: 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_0095: Unknown result type (might be due to invalid IL or missing references)
float[] poseA = v.PoseA;
int num = 0;
int num2 = 0;
Vector3 val2 = default(Vector3);
while (num < v.Bones.Length)
{
Transform val = v.Bones[num];
val.SetLocalPositionAndRotation(new Vector3(poseA[num2], poseA[num2 + 1], poseA[num2 + 2]), new Quaternion(poseA[num2 + 3], poseA[num2 + 4], poseA[num2 + 5], poseA[num2 + 6]));
((Vector3)(ref val2))..ctor(poseA[num2 + 7], poseA[num2 + 8], poseA[num2 + 9]);
Vector3 val3 = val2 - v.LastScale[num];
if (((Vector3)(ref val3)).sqrMagnitude > 1E-06f)
{
val.localScale = val2;
v.LastScale[num] = val2;
}
num++;
num2 += 10;
}
}
private static float EaseOutBack(float x)
{
return 1f + 2.70158f * Mathf.Pow(x - 1f, 3f) + 1.70158f * Mathf.Pow(x - 1f, 2f);
}
}
}