using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSLZ.Marrow.Zones;
using Il2CppSLZ.SFX;
using Il2CppSLZ.UI;
using Il2CppSystem;
using Il2CppTMPro;
using MelonLoader;
using Tymkass_Crate_Map_Extension;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(main), "Crate Map Extension", "1.0.0", "Tymkass", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: AssemblyTitle("Crate Map Extension")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Crate Map Extension")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2309b9ef-c486-4488-9156-78d08e2a2c4a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Tymkass_Crate_Map_Extension;
internal class CheckInitialized : MonoBehaviour
{
private ZoneEvents _zoneAEvents;
private bool _didInitialize;
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Scene sceneByName = SceneManager.GetSceneByName(main.mapName);
GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)((Scene)(ref sceneByName)).GetRootGameObjects());
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (((Object)val).name == "ZONES")
{
_zoneAEvents = ((Component)val.transform.Find("ZONE A")).GetComponent<ZoneEvents>();
}
}
}
public void Update()
{
if (_zoneAEvents._hasZoneEntered & !_didInitialize)
{
_didInitialize = true;
main.initialized = true;
main.loggerInstance.Msg("Initialized");
}
}
}
public class NarratorVoiceController : MonoBehaviour
{
[Serializable]
public struct Voiceline
{
public AudioClip voicelineClip;
public bool onlyPlayOnce;
public bool hasPlayedOnce;
public int priority;
public Voiceline(AudioClip voicelineClip, bool onlyPlayOnce)
{
this.voicelineClip = voicelineClip;
this.onlyPlayOnce = onlyPlayOnce;
hasPlayedOnce = false;
priority = 0;
}
public Voiceline(AudioClip voicelineClip, bool onlyPlayOnce, int priority)
{
this.voicelineClip = voicelineClip;
this.onlyPlayOnce = onlyPlayOnce;
hasPlayedOnce = false;
this.priority = priority;
}
}
private List<Voiceline> _voicelineClips = new List<Voiceline>();
public AudioSource narratorSRC;
private bool _runUpdate;
private Voiceline _currentVoiceline;
private Voiceline _inQueueVoiceline;
public bool isVoicelineInQueue;
public static NarratorVoiceController instance;
public bool isPlaying;
private void GetObjs()
{
for (int i = 0; i < ((Il2CppArrayBase<MusicCue>)(object)main.voicelines.tracks).Count; i++)
{
if (i < DestroyOperator._startDialoguesAt || i > EndOperator._startEndDialoguesAt)
{
_voicelineClips.Add(new Voiceline(((Il2CppArrayBase<MusicCue>)(object)main.voicelines.tracks)[i].clipMain, ((Il2CppArrayBase<MusicCue>)(object)main.voicelines.tracks)[i].onlyPlayOnce, 1));
}
else if (i == EndOperator._startEndDialoguesAt)
{
_voicelineClips.Add(new Voiceline(((Il2CppArrayBase<MusicCue>)(object)main.voicelines.tracks)[i].clipMain, ((Il2CppArrayBase<MusicCue>)(object)main.voicelines.tracks)[i].onlyPlayOnce, 2));
}
else
{
_voicelineClips.Add(new Voiceline(((Il2CppArrayBase<MusicCue>)(object)main.voicelines.tracks)[i].clipMain, ((Il2CppArrayBase<MusicCue>)(object)main.voicelines.tracks)[i].onlyPlayOnce, 0));
}
}
main.loggerInstance.Msg("Voiceline List lenght: " + _voicelineClips.Count);
}
public void ClearVoice()
{
narratorSRC.Stop();
isVoicelineInQueue = false;
}
private IEnumerator queueVoiceline()
{
while (narratorSRC.isPlaying)
{
yield return (object)new WaitForEndOfFrame();
}
PlaySRC(_inQueueVoiceline);
isVoicelineInQueue = false;
}
private void Awake()
{
instance = this;
}
private void Update()
{
if (main.initialized & !_runUpdate)
{
narratorSRC = ((Component)this).GetComponent<AudioSource>();
_runUpdate = true;
GetObjs();
PlayVoiceline(0);
}
}
private void PlaySRC(Voiceline voiceline)
{
narratorSRC.Stop();
int index = _voicelineClips.IndexOf(voiceline);
Voiceline voiceline2 = _voicelineClips[index];
voiceline2.hasPlayedOnce = true;
_voicelineClips[index] = voiceline2;
_currentVoiceline = voiceline2;
narratorSRC.PlayOneShot(voiceline.voicelineClip);
}
private void CalculateVoicelineValues(Voiceline voiceline)
{
if (_currentVoiceline.priority < voiceline.priority || _currentVoiceline.priority == voiceline.priority)
{
PlaySRC(voiceline);
}
else if (!isVoicelineInQueue)
{
isVoicelineInQueue = true;
_inQueueVoiceline = voiceline;
MelonCoroutines.Start(queueVoiceline());
}
else if (_inQueueVoiceline.priority < voiceline.priority || _inQueueVoiceline.priority == voiceline.priority)
{
_inQueueVoiceline = voiceline;
}
}
public void PlayVoiceline(int voicelineIndex)
{
if (!_voicelineClips[voicelineIndex].onlyPlayOnce || !_voicelineClips[voicelineIndex].hasPlayedOnce)
{
if (narratorSRC.isPlaying)
{
CalculateVoicelineValues(_voicelineClips[voicelineIndex]);
}
else
{
PlaySRC(_voicelineClips[voicelineIndex]);
}
}
}
}
internal class EndOperator : MonoBehaviour
{
private ZoneEvents _endEvent;
private bool _thisCouldBeDoneWithEvents;
private bool _entered;
private Animator _floorAnim;
private Collider _loadLevelCollider;
private GameObject _ford;
private GameObject _crateFord;
private ParticleSystem _smoke;
private bool _played;
private AudioSource _smokeSFX;
public static int _startEndDialoguesAt = 29;
private void GetObj()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Scene sceneByName = SceneManager.GetSceneByName(main.mapName);
GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)((Scene)(ref sceneByName)).GetRootGameObjects());
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
switch (((Object)val).name)
{
case "ZoneEvents":
_endEvent = ((Component)val.transform.Find("Zone Event END")).GetComponent<ZoneEvents>();
_loadLevelCollider = ((Component)val.transform.Find("Zone Event Load Menu Upper")).GetComponent<Collider>();
_loadLevelCollider.enabled = false;
break;
case "Zone2Floor":
_floorAnim = val.GetComponent<Animator>();
break;
case "CrateFord Variant":
_crateFord = val;
break;
case "Arthur Ford Textured":
_ford = val;
break;
case "Steam":
_smoke = val.GetComponent<ParticleSystem>();
break;
case "SmokeSFX":
_smokeSFX = val.GetComponent<AudioSource>();
break;
}
}
}
private IEnumerator final()
{
_smoke.Play();
_smokeSFX.Play();
yield return (object)new WaitForSeconds(1f);
_ford.SetActive(false);
_crateFord.SetActive(true);
NarratorVoiceController.instance.PlayVoiceline(_startEndDialoguesAt + 10);
while (NarratorVoiceController.instance.narratorSRC.isPlaying)
{
yield return (object)new WaitForEndOfFrame();
}
_loadLevelCollider.enabled = true;
}
private void Update()
{
if (main.initialized & !_thisCouldBeDoneWithEvents)
{
_thisCouldBeDoneWithEvents = true;
GetObj();
}
if (!((Object)(object)_endEvent != (Object)null))
{
return;
}
if (_endEvent._hasZoneEntered & !_entered)
{
_entered = true;
NarratorVoiceController.instance.ClearVoice();
NarratorVoiceController.instance.PlayVoiceline(_startEndDialoguesAt);
if (DestroyOperator.crateDestroyedCount == 0)
{
NarratorVoiceController.instance.PlayVoiceline(_startEndDialoguesAt + 1);
}
else if (DestroyOperator.crateDestroyedCount < 5)
{
NarratorVoiceController.instance.PlayVoiceline(_startEndDialoguesAt + 11);
}
else
{
NarratorVoiceController.instance.PlayVoiceline(DestroyOperator.crateDestroyedCount / 5 + 1 + _startEndDialoguesAt);
}
}
if (_entered && (!NarratorVoiceController.instance.narratorSRC.isPlaying & !NarratorVoiceController.instance.isVoicelineInQueue & !_played))
{
_played = true;
if (DestroyOperator.crateDestroyedCount < 15)
{
_floorAnim.SetBool("openPit", true);
}
else if (DestroyOperator.crateDestroyedCount >= 40)
{
MelonCoroutines.Start(final());
}
else
{
_loadLevelCollider.enabled = true;
}
}
}
}
internal class FightOperator : MonoBehaviour
{
private ZoneEvents _fightZoneEvent;
private bool _entered;
private Transform _enemySpawns;
private bool _isFight;
private int _waveAmount = 3;
private bool _thisCouldBeDoneWithEvents;
private Transform _spawnPlates;
private TMP_Text timeTxt;
private int _currentWave = 0;
private Animator _arenaDoorAnimator;
private Animator _finalDoorAnimator;
private int _currentEnemyCount;
private bool _didFailBefore;
private List<GameObject> _currentEnemies = new List<GameObject>();
public static FightOperator instance;
private object _currentCoroutine;
private void Awake()
{
instance = this;
}
private void GetObj()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Scene sceneByName = SceneManager.GetSceneByName(main.mapName);
GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)((Scene)(ref sceneByName)).GetRootGameObjects());
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (((Object)val).name == "ZoneEvents")
{
_fightZoneEvent = ((Component)val.transform.Find("Zone Event Fight")).GetComponent<ZoneEvents>();
}
else
{
if (!(((Object)val).name == "Enviroment"))
{
continue;
}
Transform child = val.transform.GetChild(3);
for (int j = 0; j < child.childCount; j++)
{
Transform child2 = child.GetChild(j);
if (((Object)((Component)child2).gameObject).name == "EnemySpawns")
{
_enemySpawns = child2;
}
else if (((Object)((Component)child2).gameObject).name == "DOOR Final")
{
_finalDoorAnimator = ((Component)child2).gameObject.GetComponent<Animator>();
}
}
Transform child3 = val.transform.GetChild(0);
for (int k = 0; k < child3.childCount; k++)
{
Transform child4 = child3.GetChild(k);
if (((Object)((Component)child4).gameObject).name == "DOOR Arena")
{
_arenaDoorAnimator = ((Component)child4).GetComponent<Animator>();
}
}
}
}
}
private void SpawnEnemies()
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
_currentWave++;
Transform val = _enemySpawns.Find($"Wave {_currentWave}");
_currentEnemyCount = val.childCount;
for (int i = 0; i < val.childCount; i++)
{
((Component)val.GetChild(i)).GetComponent<CrateSpawner>().SpawnSpawnable();
}
main.loggerInstance.Msg("Spawned all");
Scene sceneByName = SceneManager.GetSceneByName(main.mapName);
GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)((Scene)(ref sceneByName)).GetRootGameObjects());
GameObject[] array2 = array;
foreach (GameObject val2 in array2)
{
if (((Object)val2).name.StartsWith("NullBody") || ((Object)val2).name.StartsWith("omniProjector_hazmat"))
{
AIBrain component = val2.GetComponent<AIBrain>();
component.onDeathDelegate += Action<AIBrain>.op_Implicit((Action<AIBrain>)onEnemyDeath);
_currentEnemies.Add(val2);
}
}
}
public void onPlayerDeath()
{
main.loggerInstance.Msg("PlayerDead");
if (_currentWave != 0)
{
_didFailBefore = true;
ManagePlates(1);
_isFight = false;
_entered = false;
_currentWave = 0;
timeTxt.text = "1:00";
_currentEnemyCount = 0;
_fightZoneEvent._hasZoneEntered = false;
DestroyEnemies();
if (_currentCoroutine != null)
{
MelonCoroutines.Stop(_currentCoroutine);
}
}
}
public void onEnemyDeath(AIBrain aiBrain)
{
_currentEnemyCount--;
}
private void DestroyEnemies()
{
for (int i = 0; i < _currentEnemies.Count; i++)
{
if ((Object)(object)_currentEnemies[i] != (Object)null)
{
Object.Destroy((Object)(object)_currentEnemies[i]);
}
}
_currentEnemies = new List<GameObject>();
}
private void Update()
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
if (main.initialized & !_thisCouldBeDoneWithEvents)
{
_thisCouldBeDoneWithEvents = true;
GetObj();
}
if (!((Object)(object)_fightZoneEvent != (Object)null))
{
return;
}
if (_fightZoneEvent._hasZoneEntered & !_entered)
{
_entered = true;
Scene sceneByName = SceneManager.GetSceneByName("Zone2");
GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)((Scene)(ref sceneByName)).GetRootGameObjects());
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (!(((Object)val).name == "Enviroment"))
{
continue;
}
for (int j = 0; j < val.transform.childCount; j++)
{
Transform child = val.transform.GetChild(j);
if (((Object)((Component)child).gameObject).name == "WaitTime")
{
timeTxt = ((Component)child).GetComponent<TMP_Text>();
}
else if (((Object)((Component)child).gameObject).name == "SpawnPlates")
{
_spawnPlates = child;
}
}
}
if (_didFailBefore)
{
NarratorVoiceController.instance.PlayVoiceline(18);
_currentCoroutine = MelonCoroutines.Start(Countdown(30));
return;
}
NarratorVoiceController.instance.PlayVoiceline(14);
_currentCoroutine = MelonCoroutines.Start(Countdown(60));
}
if (_isFight && _currentEnemyCount == 0)
{
_isFight = false;
_currentEnemies = new List<GameObject>();
if (_currentWave == _waveAmount)
{
NarratorVoiceController.instance.PlayVoiceline(15);
_arenaDoorAnimator.SetBool("UP", true);
_finalDoorAnimator.SetBool("shouldOpen", true);
}
else
{
NarratorVoiceController.instance.PlayVoiceline(15 + _currentWave);
_currentCoroutine = MelonCoroutines.Start(Countdown(30));
}
}
}
private void ManagePlates(int activeplate)
{
if (_currentWave != 0)
{
((Component)_spawnPlates.Find($"Wave {_currentWave}")).gameObject.SetActive(false);
((Component)_spawnPlates.Find($"Wave {activeplate}")).gameObject.SetActive(true);
}
}
public IEnumerator Countdown(int time)
{
ManagePlates(_currentWave + 1);
main.loggerInstance.Msg("Countdown");
for (int i = 1; i < time + 1; i++)
{
if (time - i < 10)
{
timeTxt.text = $"0:0{time - i}";
}
else
{
timeTxt.text = $"0:{time - i}";
}
yield return (object)new WaitForSeconds(1f);
}
_isFight = true;
SpawnEnemies();
}
}
public class DestroyOperator : MonoBehaviour
{
public static int crateDestroyedCount;
public static int _startDialoguesAt = 20;
private int _currentDialogue;
private int _dialogueEveryXCrate = 5;
private int _nextDialogueInXCrates;
private bool _updateRan;
private int _cratesFound;
private void Awake()
{
_currentDialogue = _startDialoguesAt - 1;
crateDestroyedCount = 0;
}
public void Update()
{
if (main.initialized & !_updateRan)
{
_updateRan = true;
PoolInitialized();
}
}
public void PoolInitialized()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
Scene sceneByName = SceneManager.GetSceneByName(main.mapName);
GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit((Il2CppArrayBase<GameObject>)(object)((Scene)(ref sceneByName)).GetRootGameObjects());
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (((Object)val).name.StartsWith(main.crateTargetName) && !((Object)(object)val.GetComponent<ObjectDestructible>() == (Object)null))
{
_cratesFound++;
if (val.GetComponent<ObjectDestructible>().OnDestruct == null)
{
val.GetComponent<ObjectDestructible>().OnDestruct = new UnityEvent();
}
val.GetComponent<ObjectDestructible>().OnDestruct.AddListener(UnityAction.op_Implicit((Action)CrateDestroyed));
}
}
main.loggerInstance.Msg($"FOUND: {_cratesFound} crates");
}
public void checkPossibleDialogue()
{
if (_nextDialogueInXCrates <= 0)
{
if (crateDestroyedCount == 1)
{
_nextDialogueInXCrates = _dialogueEveryXCrate - 1;
}
else
{
_nextDialogueInXCrates = _dialogueEveryXCrate;
}
_currentDialogue++;
NarratorVoiceController.instance.PlayVoiceline(_currentDialogue);
}
}
public void CrateDestroyed()
{
crateDestroyedCount++;
_nextDialogueInXCrates--;
checkPossibleDialogue();
}
}
[HarmonyPatch(typeof(FlyingGun), "Awake")]
public static class PatchDevFlyingGun
{
private static void Postfix()
{
if (main.isCrateMap)
{
NarratorVoiceController.instance.PlayVoiceline(8);
}
}
}
[HarmonyPatch(typeof(SpawnablesPanelView), "Activate")]
public static class PatchSpawnablesPanelView
{
private static void Postfix()
{
if (main.isCrateMap)
{
NarratorVoiceController.instance.PlayVoiceline(13);
}
}
}
[HarmonyPatch(typeof(Player_Health), "Death")]
public static class PatchPlayer_Health
{
private static void Postfix()
{
if (main.isCrateMap)
{
FightOperator.instance.onPlayerDeath();
}
}
}
public class main : MelonMod
{
public static bool isCrateMap;
public static bool initialized;
public static Instance loggerInstance;
public static TriggeredMusic voicelines;
public static string crateTargetName = "dest_Crate_Lite_1m";
public static string mapName = "Crate Adventures";
private string[] _subscene_names = new string[4] { "Zone1", "Zone2", "SceneChunkUpper", "HallwayRooms" };
public override void OnInitializeMelon()
{
((MelonBase)this).LoggerInstance.Msg("Tymkass crate extension started up!");
loggerInstance = ((MelonBase)this).LoggerInstance;
ClassInjector.RegisterTypeInIl2Cpp<DestroyOperator>();
ClassInjector.RegisterTypeInIl2Cpp<NarratorVoiceController>();
ClassInjector.RegisterTypeInIl2Cpp<FightOperator>();
ClassInjector.RegisterTypeInIl2Cpp<CheckInitialized>();
ClassInjector.RegisterTypeInIl2Cpp<EndOperator>();
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Expected O, but got Unknown
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
if (_subscene_names.Contains(sceneName) && isCrateMap)
{
return;
}
initialized = false;
if (sceneName == mapName)
{
loggerInstance.Msg("Crate map loaded");
isCrateMap = true;
voicelines = Object.FindObjectOfType<TriggeredMusic>();
if (!((Object)(object)voicelines != (Object)null))
{
((MelonBase)this).LoggerInstance.Error("Did not find voicelines in Scene!");
return;
}
GameObject val = new GameObject("Initializer");
((Behaviour)val.AddComponent<CheckInitialized>()).enabled = true;
GameObject val2 = new GameObject("DestroyOperator");
((Behaviour)val2.AddComponent<DestroyOperator>()).enabled = true;
GameObject val3 = new GameObject("FightOperator");
((Behaviour)val3.AddComponent<FightOperator>()).enabled = true;
GameObject val4 = new GameObject("EndOperator");
((Behaviour)val4.AddComponent<EndOperator>()).enabled = true;
loggerInstance.Msg("Created gameobjects succesfully");
}
else
{
isCrateMap = false;
}
}
}