using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[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 NullscapeOperator
{
internal sealed class OperatorEncounter : IDisposable
{
private enum Phase
{
Intro,
Waiting,
Leaving,
Warning,
Attacking,
Finished
}
private const float IntroDuration = 0.65f;
private const float YellowDuration = 5f;
private const float ReleaseGracePeriod = 0.1f;
private const float LeaveDuration = 0.55f;
private const float RedWarningDuration = 1f;
private const float AttackFrameDuration = 0.14f;
private const float StickDeadZone = 0.26f;
private readonly Component player;
private readonly Texture2D[] textures;
private readonly Action dealFatalDamage;
private readonly ManualLogSource logger;
private readonly OperatorSounds sounds;
private readonly float screenHeightFraction;
private readonly float leftCenterFraction;
private readonly float swayAngle;
private Phase phase;
private float elapsedInPhase;
private float releasedFor;
private float alpha = 1f;
private static bool horizontalAxisAvailable = true;
private static bool verticalAxisAvailable = true;
public bool Finished => phase == Phase.Finished;
public OperatorEncounter(Component player, Texture2D[] textures, float height, float left, float sway, Action dealFatalDamage, OperatorSounds sounds, ManualLogSource logger)
{
this.player = player;
this.textures = textures;
this.dealFatalDamage = dealFatalDamage;
this.sounds = sounds;
this.logger = logger;
screenHeightFraction = Mathf.Clamp(height, 0.2f, 0.75f);
leftCenterFraction = Mathf.Clamp(left, 0.12f, 0.36f);
swayAngle = Mathf.Clamp(sway, 0f, 14f);
sounds?.Play(0);
}
public void Update(float deltaTime)
{
if (Finished)
{
return;
}
if ((Object)(object)player == (Object)null || !player.gameObject.activeInHierarchy)
{
Finish();
}
else
{
if (Time.timeScale <= 0.001f)
{
return;
}
float num = Mathf.Max(0f, deltaTime);
elapsedInPhase += num;
switch (phase)
{
case Phase.Intro:
if (elapsedInPhase >= 0.65f)
{
Enter(Phase.Waiting);
}
break;
case Phase.Waiting:
if (!AnyControlsHeld())
{
releasedFor += num;
if (releasedFor >= 0.1f || elapsedInPhase >= 5f)
{
Enter(Phase.Leaving);
break;
}
}
else
{
releasedFor = 0f;
}
if (elapsedInPhase >= 5f)
{
Enter(Phase.Warning);
}
break;
case Phase.Leaving:
alpha = 1f - Mathf.Clamp01(elapsedInPhase / 0.55f);
if (elapsedInPhase >= 0.55f)
{
Finish();
}
break;
case Phase.Warning:
if (elapsedInPhase >= 1f)
{
Enter(Phase.Attacking);
}
break;
case Phase.Attacking:
if (elapsedInPhase >= 0.14f)
{
try
{
dealFatalDamage();
}
catch (Exception ex)
{
logger.LogError((object)("Operator could not damage player: " + ex));
}
Finish();
}
break;
}
}
}
private static bool AnyControlsHeld()
{
if (Input.anyKey)
{
return true;
}
if (!StickMoved("Horizontal", ref horizontalAxisAvailable))
{
return StickMoved("Vertical", ref verticalAxisAvailable);
}
return true;
}
private static bool StickMoved(string axis, ref bool available)
{
if (!available)
{
return false;
}
try
{
return Mathf.Abs(Input.GetAxisRaw(axis)) > 0.26f;
}
catch (ArgumentException)
{
available = false;
return false;
}
catch (UnityException)
{
available = false;
return false;
}
}
public void Draw()
{
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
if (Finished)
{
return;
}
int num;
switch (phase)
{
default:
return;
case Phase.Intro:
case Phase.Leaving:
num = 0;
break;
case Phase.Waiting:
num = 1;
break;
case Phase.Warning:
num = 2;
break;
case Phase.Attacking:
num = 3;
break;
}
Texture2D val = textures[num];
if ((Object)(object)val == (Object)null)
{
return;
}
float num2 = (float)Screen.height * screenHeightFraction;
float num3 = num2 * (float)((Texture)val).width / (float)((Texture)val).height;
bool flag = phase == Phase.Waiting;
float num4 = elapsedInPhase;
float num5 = swayAngle * Mathf.Sin(num4 * (flag ? 5.1f : 2.7f)) * (flag ? 1f : 0.45f);
float num6 = (float)Screen.width * (flag ? 0.04f : 0.008f) * Mathf.Sin(num4 * (flag ? 3.3f : 1.6f));
float num7 = (float)Screen.height * (flag ? 0.054f : 0.012f) * Mathf.Sin(num4 * (flag ? 3.3f : 2f) + 0.6f);
float num8 = Mathf.Clamp(Mathf.Max(num3 / 2f + 12f, (float)Screen.width * leftCenterFraction) + num6 - num3 / 2f, 0f, Mathf.Max(0f, (float)Screen.width - num3));
float num9 = Mathf.Clamp((float)Screen.height * 0.52f - num2 / 2f - num7, 0f, Mathf.Max(0f, (float)Screen.height - num2));
Rect val2 = default(Rect);
((Rect)(ref val2))..ctor(num8, num9, num3, num2);
Matrix4x4 matrix = GUI.matrix;
Color color = GUI.color;
int depth = GUI.depth;
try
{
GUI.depth = -500;
GUI.color = new Color(1f, 1f, 1f, alpha);
GUIUtility.RotateAroundPivot(num5, ((Rect)(ref val2)).center);
GUI.DrawTexture(val2, (Texture)(object)val, (ScaleMode)2, true);
}
finally
{
GUI.matrix = matrix;
GUI.color = color;
GUI.depth = depth;
}
}
private void Enter(Phase next)
{
phase = next;
elapsedInPhase = 0f;
releasedFor = 0f;
alpha = 1f;
if (sounds != null)
{
sounds.StopWaitingLoop();
}
if (sounds != null)
{
switch (next)
{
case Phase.Waiting:
sounds.StartWaitingLoop();
break;
case Phase.Leaving:
sounds.Play(2);
break;
case Phase.Attacking:
sounds.Play(3);
break;
case Phase.Warning:
break;
}
}
}
private void Finish()
{
if (!Finished)
{
phase = Phase.Finished;
if (sounds != null)
{
sounds.StopWaitingLoop();
}
}
}
public void Dispose()
{
Finish();
}
}
internal sealed class OperatorSounds : IDisposable
{
internal const int Spawn = 0;
internal const int Waiting = 1;
internal const int Vanish = 2;
internal const int Kill = 3;
private static readonly string[] Names = new string[4] { "spawn.wav", "waiting.wav", "vanish.wav", "kill.wav" };
private readonly AudioClip[] clips = (AudioClip[])(object)new AudioClip[4];
private readonly ManualLogSource log;
private readonly GameObject host;
private readonly AudioSource effects;
private readonly AudioSource waiting;
private bool disposed;
private float volume;
internal float Volume
{
get
{
return volume;
}
set
{
volume = Mathf.Clamp01(value);
if ((Object)(object)effects != (Object)null)
{
effects.volume = volume;
}
if ((Object)(object)waiting != (Object)null)
{
waiting.volume = volume;
}
}
}
internal OperatorSounds(string directory, float initialVolume, ManualLogSource logger)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
log = logger;
host = new GameObject("NullscapeOperator_Audio");
Object.DontDestroyOnLoad((Object)(object)host);
effects = host.AddComponent<AudioSource>();
waiting = host.AddComponent<AudioSource>();
Configure(effects, looping: false);
Configure(waiting, looping: true);
Volume = initialVolume;
for (int i = 0; i < Names.Length; i++)
{
try
{
clips[i] = LoadPcm16Wav(Path.Combine(directory, Names[i]));
}
catch (Exception ex)
{
log.LogWarning((object)("Audio indisponivel (" + Names[i] + "): " + ex.Message));
}
}
}
private static void Configure(AudioSource source, bool looping)
{
source.playOnAwake = false;
source.spatialBlend = 0f;
source.loop = looping;
source.dopplerLevel = 0f;
}
internal void Play(int index)
{
if (!disposed && index >= 0 && index < clips.Length && !((Object)(object)clips[index] == (Object)null) && !(volume <= 0f))
{
effects.PlayOneShot(clips[index], 1f);
}
}
internal void StartWaitingLoop()
{
if (!disposed && !((Object)(object)clips[1] == (Object)null) && !(volume <= 0f))
{
waiting.Stop();
waiting.clip = clips[1];
waiting.Play();
}
}
internal void StopWaitingLoop()
{
if (!disposed)
{
waiting.Stop();
waiting.clip = null;
}
}
private static AudioClip LoadPcm16Wav(string filename)
{
using FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
using BinaryReader binaryReader = new BinaryReader(fileStream);
if (new string(binaryReader.ReadChars(4)) != "RIFF")
{
throw new InvalidDataException("RIFF ausente");
}
binaryReader.ReadUInt32();
if (new string(binaryReader.ReadChars(4)) != "WAVE")
{
throw new InvalidDataException("WAVE ausente");
}
ushort num = 0;
ushort num2 = 0;
ushort num3 = 0;
int num4 = 0;
byte[] array = null;
while (fileStream.Position + 8 <= fileStream.Length)
{
string text = new string(binaryReader.ReadChars(4));
uint num5 = binaryReader.ReadUInt32();
long num6 = fileStream.Position + num5 + (num5 & 1);
if (num6 > fileStream.Length + 1)
{
throw new InvalidDataException("Chunk WAV invalido");
}
if (text == "fmt " && num5 >= 16)
{
num = binaryReader.ReadUInt16();
num2 = binaryReader.ReadUInt16();
num4 = binaryReader.ReadInt32();
binaryReader.ReadUInt32();
binaryReader.ReadUInt16();
num3 = binaryReader.ReadUInt16();
}
else if (text == "data")
{
if (num5 > 2205000)
{
throw new InvalidDataException("Audio muito grande");
}
array = binaryReader.ReadBytes((int)num5);
}
fileStream.Position = Math.Min(num6, fileStream.Length);
}
if (num != 1 || num2 != 1 || num3 != 16 || num4 < 8000 || num4 > 96000 || array == null || array.Length < 2 || array.Length % 2 != 0)
{
throw new InvalidDataException("Esperado audio WAV mono PCM16");
}
float[] array2 = new float[array.Length / 2];
for (int i = 0; i < array2.Length; i++)
{
short num7 = (short)(array[i * 2] | (array[i * 2 + 1] << 8));
array2[i] = (float)num7 / 32768f;
}
AudioClip val = AudioClip.Create(Path.GetFileNameWithoutExtension(filename), array2.Length, 1, num4, false);
if (!val.SetData(array2, 0))
{
Object.Destroy((Object)(object)val);
throw new IOException("AudioClip.SetData falhou");
}
return val;
}
public void Dispose()
{
if (disposed)
{
return;
}
StopWaitingLoop();
disposed = true;
if ((Object)(object)effects != (Object)null)
{
effects.Stop();
}
AudioClip[] array = clips;
foreach (AudioClip val in array)
{
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
}
if ((Object)(object)host != (Object)null)
{
Object.Destroy((Object)(object)host);
}
}
}
[BepInPlugin("gooin.ultrakill.nullscapeoperator", "Nullscape Operator", "1.3.6")]
public sealed class Plugin : BaseUnityPlugin
{
private static readonly Dictionary<string, string> KnownScenes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "241a6a8caec7a13438a5ee786040de32", "Intro" },
{ "b3e7f2f8052488a45b35549efb98d902", "Main Menu" },
{ "4f8ecffaa98c2614f89922daf31fa22d", "Bootstrap" },
{ "eb57c9574cb2e624799753de0f8ffcad", "Level 0-1" },
{ "7927c42db92e4164cae682a55e6b7725", "Level 0-2" },
{ "5bcb2e0461e7fce408badfcb6778c271", "Level 0-3" },
{ "3e978dea8d12a0146b46cb0c302d66e2", "Level 0-4" },
{ "5541f073d290f4348884fa3f76072afd", "Level 0-5" },
{ "bed42b2b2baee8e4e91e0dce20965c80", "Level 1-1" },
{ "8038b251ea4683b4db4ef432205184f6", "Level 1-2" },
{ "8bb7c995619939c449fa474a046a0e10", "Level 1-3" },
{ "36abcaae9708abc4d9e89e6ec73a2846", "Level 1-4" },
{ "55e17289238a28d488af367454267a0d", "Level 2-1" },
{ "6440445a799e22842babe18edf7da792", "Level 2-2" },
{ "4e039f071c1fba04a82a7b6b44feadc2", "Level 2-3" },
{ "e33f259a6c8241e46a5cbe4869cf059f", "Level 2-4" },
{ "eedb12c9580191843af569e5c1f747d0", "Level 3-1" },
{ "f1aa2efdf8dccae45b1396aef397ed79", "Level 3-2" },
{ "35e79ad18419eb54c99acadb947ec056", "Level 4-1" },
{ "3ccffeb3aeb6d3848be2264c18b62a52", "Level 4-2" },
{ "38748a67bc9e67a43956a92f87d1e742", "Level 4-3" },
{ "ac1675e648695a343bd064c6d0c56e57", "Level 4-4" },
{ "fba3bcfce7b99ae4d90356c81c5586b3", "Level 5-1" },
{ "e964cf0ffaa9e0e4e940b5c738983796", "Level 5-2" },
{ "05467c3b58b659d488c34adf5963fd5e", "Level 5-3" },
{ "37e4fc7501da6c44a9d2154603fdcad5", "Level 5-4" },
{ "e6c1048e72392b94ab51eadc3d5bb481", "Level 6-1" },
{ "28553bdf5ebfbd94a848afd933e0dfb1", "Level 6-2" },
{ "401a07bc9536abc4d88d37641bf1d12c", "Level 7-1" },
{ "aa55551f768b5224997a4b5e0ef315ea", "Level 7-2" },
{ "a952d42adc8d6724887c991e5376f170", "Level 7-3" },
{ "6e981b1865c649749a610aafc471e198", "Level 7-4" },
{ "07b47256f0da7f941947e74905ad16b4", "Level 0-S" },
{ "5d90a7ae80eab2244b5bd784a77d3724", "Level 1-S" },
{ "9dcce8702f56e7349ba1ecc71ba5f42a", "Level 2-S" },
{ "388594c020ef7c240afc673f062e6425", "Level 4-S" },
{ "1567f75bc4488644684d7a25471dbe95", "Level 5-S" },
{ "aa8b84f8b1443ef4783afbc6b1db1e30", "Level 7-S" },
{ "005a4f2ce549277458596ee0f0d6e88c", "Level P-1" },
{ "1f290c2101e628540bf9c6d1d2140750", "Level P-2" },
{ "36c5b4853d1d63d4686ea9a23ca61f8c", "Level E-0" },
{ "920eb5e368b1f154a800f39c4c78c41c", "Level E-1" },
{ "4c18368dae54f154da2ae65baf0e630e", "Intermission1" },
{ "d8e7c3bbb0c2f3940aa7c51dc5849781", "Intermission2" },
{ "9240e656c89994d44b21940f65ab57da", "Cybergrind" },
{ "7b3cb6a0a342eb54dafe5552d4820eeb", "Sandbox" },
{ "e92f893de47503a4f959f7d5bca84261", "Museum" }
};
private ConfigEntry<bool> enabled;
private ConfigEntry<bool> runOnSecrets;
private ConfigEntry<float> uiHeight;
private ConfigEntry<float> leftPosition;
private ConfigEntry<float> swayAngle;
private ConfigEntry<float> soundVolume;
private OperatorSounds soundEffects;
private readonly Texture2D[] textures = (Texture2D[])(object)new Texture2D[4];
private Type playerType;
private Component player;
private OperatorEncounter encounter;
private int currentSceneHandle = int.MinValue;
private bool spawnedThisLevel;
private float elapsed;
private float nextLookup;
private float spawnDelay;
private bool texturesReady;
private string sceneLabel;
private bool gameplayScene;
private bool stoppedForSafety;
private float nextSceneCheck;
private FieldInfo cachedHp;
private FieldInfo cachedDead;
private Type cachedFieldsForType;
private void Awake()
{
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable Operator encounters.");
runOnSecrets = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludeSecretAndPrimeLevels", true, "Enable on secret/prime levels too.");
uiHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "ScreenHeightFraction", 0.52f, "Operator UI height relative to screen height (0.20 to 0.75).");
leftPosition = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "LeftScreenCenter", 0.2f, "Horizontal center position as fraction of screen width (0.12 to 0.36). Left side by default.");
swayAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "SwayAngleDegrees", 7.5f, "Rocking tilt in degrees while yellow; green/red use softer tilt (0 to 14).");
soundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 1f, "Volume of the Operator sound effects, 0 to 1.");
soundEffects = new OperatorSounds(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "sounds"), soundVolume.Value, ((BaseUnityPlugin)this).Logger);
texturesReady = LoadTextures();
SceneManager.activeSceneChanged += OnSceneChanged;
ResetForScene(SceneManager.GetActiveScene());
}
private void OnSceneChanged(Scene oldScene, Scene newScene)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
if (stoppedForSafety)
{
return;
}
try
{
ResetForScene(newScene);
}
catch (Exception ex)
{
StopSafely("mudanca de fase", ex);
}
}
private void ResetForScene(Scene scene)
{
DisposeEncounter();
currentSceneHandle = ((Scene)(ref scene)).handle;
spawnedThisLevel = false;
elapsed = 0f;
nextLookup = 0f;
player = null;
sceneLabel = (KnownScenes.TryGetValue(((Scene)(ref scene)).name ?? string.Empty, out var value) ? value : (((Scene)(ref scene)).name ?? string.Empty));
spawnDelay = DetermineDelay();
gameplayScene = IsGameplayScene();
nextSceneCheck = Time.unscaledTime + 1f;
((BaseUnityPlugin)this).Logger.LogInfo((object)("Scene: " + sceneLabel + " / Operator spawn scheduled in " + spawnDelay.ToString("0") + " seconds of active gameplay."));
}
private static float DetermineDelay()
{
return Random.Range(1.01f, 119.99f);
}
private bool IsGameplayScene()
{
string text = sceneLabel;
if (string.IsNullOrEmpty(text))
{
return false;
}
if (text.Equals("Intro", StringComparison.OrdinalIgnoreCase) || text.Equals("Main Menu", StringComparison.OrdinalIgnoreCase) || text.Equals("Bootstrap", StringComparison.OrdinalIgnoreCase) || text.Equals("Sandbox", StringComparison.OrdinalIgnoreCase) || text.Equals("Museum", StringComparison.OrdinalIgnoreCase) || text.Equals("uk_construct", StringComparison.OrdinalIgnoreCase) || text.Equals("Endless", StringComparison.OrdinalIgnoreCase) || text.Equals("Cybergrind", StringComparison.OrdinalIgnoreCase) || text.StartsWith("Intermission", StringComparison.OrdinalIgnoreCase) || text.IndexOf("credit", StringComparison.OrdinalIgnoreCase) >= 0)
{
return false;
}
if (text.StartsWith("Level ", StringComparison.OrdinalIgnoreCase))
{
if (!runOnSecrets.Value)
{
if (!text.Contains("-S"))
{
return !text.Contains("P-");
}
return false;
}
return true;
}
if (text.Length == 32)
{
return IsHex(text);
}
return false;
}
private static bool IsHex(string value)
{
for (int i = 0; i < value.Length; i++)
{
if (!Uri.IsHexDigit(value[i]))
{
return false;
}
}
return true;
}
private Component FindPlayer()
{
if (playerType == null)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
playerType = assembly.GetType("NewMovement", throwOnError: false);
if (playerType != null)
{
break;
}
}
}
if (playerType == null)
{
return null;
}
Object obj = Object.FindObjectOfType(playerType);
return (Component)(object)((obj is Component) ? obj : null);
}
private void Update()
{
if (stoppedForSafety)
{
return;
}
try
{
UpdateCore();
}
catch (Exception ex)
{
StopSafely("Update", ex);
}
}
private void StopSafely(string stage, Exception ex)
{
stoppedForSafety = true;
((BaseUnityPlugin)this).Logger.LogError((object)("NullscapeOperator interrompido para evitar novos erros em " + stage + ": " + ex));
try
{
DisposeEncounter();
}
catch (Exception ex2)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Falha na limpeza do evento: " + ex2.Message));
}
}
private void UpdateCore()
{
//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_0034: Unknown result type (might be due to invalid IL or missing references)
if (Time.unscaledTime >= nextSceneCheck)
{
nextSceneCheck = Time.unscaledTime + 1f;
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).handle != currentSceneHandle)
{
ResetForScene(activeScene);
}
}
if (!enabled.Value || !texturesReady || !gameplayScene)
{
DisposeEncounter();
return;
}
if ((Object)(object)player == (Object)null || !player.gameObject.activeInHierarchy)
{
if (Time.unscaledTime < nextLookup)
{
return;
}
nextLookup = Time.unscaledTime + 1f;
player = FindPlayer();
if ((Object)(object)player == (Object)null)
{
return;
}
CacheHealthFields(((object)player).GetType());
}
if (encounter != null)
{
encounter.Update(Mathf.Max(0f, Time.deltaTime));
if (encounter.Finished)
{
DisposeEncounter();
}
}
else if (!spawnedThisLevel && !(Time.timeScale <= 0.01f) && !IsDead(player))
{
elapsed += Mathf.Max(0f, Time.deltaTime);
if (!(elapsed < spawnDelay))
{
soundEffects.Volume = Mathf.Clamp01(soundVolume.Value);
encounter = new OperatorEncounter(player, textures, uiHeight.Value, leftPosition.Value, swayAngle.Value, ApplyFatalHit, soundEffects, ((BaseUnityPlugin)this).Logger);
spawnedThisLevel = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)("Operator apparition spawned on " + sceneLabel));
}
}
}
private void OnGUI()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Invalid comparison between Unknown and I4
if (stoppedForSafety || Event.current == null || (int)Event.current.type != 7 || enabled == null || !enabled.Value || encounter == null || encounter.Finished)
{
return;
}
try
{
encounter.Draw();
}
catch (Exception ex)
{
StopSafely("OnGUI", ex);
}
}
private void CacheHealthFields(Type type)
{
if (!(type == cachedFieldsForType))
{
cachedFieldsForType = type;
cachedHp = type.GetField("hp", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
cachedDead = type.GetField("dead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
}
private bool IsDead(Component target)
{
if ((Object)(object)target == (Object)null)
{
return true;
}
try
{
CacheHealthFields(((object)target).GetType());
if (cachedHp != null && Convert.ToDouble(cachedHp.GetValue(target)) <= 0.0)
{
return true;
}
if (cachedDead != null && cachedDead.FieldType == typeof(bool) && (bool)cachedDead.GetValue(target))
{
return true;
}
}
catch (Exception ex)
{
cachedHp = null;
cachedDead = null;
((BaseUnityPlugin)this).Logger.LogWarning((object)("Nao foi possivel ler vida do jogador: " + ex.Message));
}
return false;
}
private void ApplyFatalHit()
{
if ((Object)(object)player == (Object)null || IsDead(player))
{
return;
}
try
{
MethodInfo[] methods = ((object)player).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.Name != "GetHurt")
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
object[] parameters2;
if (parameters.Length == 7 && parameters[0].ParameterType == typeof(int) && parameters[1].ParameterType == typeof(bool) && parameters[2].ParameterType == typeof(float) && parameters[3].ParameterType == typeof(bool) && parameters[4].ParameterType == typeof(bool) && parameters[5].ParameterType == typeof(float) && parameters[6].ParameterType == typeof(bool))
{
parameters2 = new object[7] { 99999, false, 1f, true, true, 0.35f, false };
}
else
{
if (parameters.Length != 3 || !(parameters[0].ParameterType == typeof(int)) || !(parameters[1].ParameterType == typeof(bool)) || !(parameters[2].ParameterType == typeof(float)))
{
continue;
}
parameters2 = new object[3] { 99999, false, 1f };
}
methodInfo.Invoke(player, parameters2);
return;
}
((BaseUnityPlugin)this).Logger.LogError((object)"Could not find a supported NewMovement fatal damage method.");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Fatal hit call failed: " + ex));
}
}
private bool LoadTextures()
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "assets");
string[] array = new string[4] { "idle.png", "waiting.png", "danger.png", "killing.png" };
try
{
for (int i = 0; i < array.Length; i++)
{
string text = Path.Combine(path, array[i]);
byte[] array2 = File.ReadAllBytes(text);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (!ImageConversion.LoadImage(val, array2, true))
{
Object.Destroy((Object)(object)val);
throw new IOException("Imagem invalida: " + text);
}
((Texture)val).filterMode = (FilterMode)0;
((Texture)val).wrapMode = (TextureWrapMode)1;
textures[i] = val;
}
return true;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Could not load Operator textures: " + ex));
return false;
}
}
private void DisposeEncounter()
{
if (encounter != null)
{
encounter.Dispose();
encounter = null;
}
}
private void OnDestroy()
{
SceneManager.activeSceneChanged -= OnSceneChanged;
DisposeEncounter();
if (soundEffects != null)
{
soundEffects.Dispose();
}
Texture2D[] array = textures;
foreach (Texture2D val in array)
{
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
}
}
}
}