using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using CustomGameModes.Config;
using CustomGameModes.Controllers;
using CustomGameModes.Factories;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using WKLib;
using WKLib.Assets;
using WKLib.Core;
using WKLib.Gamemodes.Builders;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("monksilly.CustomGamemodes")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3+41b7fa25dcfbacbc290cd76e1b9e1fcb8e075867")]
[assembly: AssemblyProduct("Custom Gamemodes")]
[assembly: AssemblyTitle("monksilly.CustomGamemodes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 CustomGameModes
{
[RequireComponent(typeof(Image))]
public class DynamicSpriteSwitcher : MonoBehaviour
{
public enum DisplayMode
{
Random,
Slideshow
}
[CompilerGenerated]
private sealed class <FadeAlpha>d__15 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public float from;
public float to;
public DynamicSpriteSwitcher <>4__this;
private float <elapsed>5__1;
private Color <c>5__2;
private float <t>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <FadeAlpha>d__15(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<elapsed>5__1 = 0f;
<c>5__2 = ((Graphic)<>4__this._image).color;
break;
case 1:
<>1__state = -1;
break;
}
if (<elapsed>5__1 < <>4__this.fadeDuration)
{
<elapsed>5__1 += Time.deltaTime;
<t>5__3 = Mathf.Clamp01(<elapsed>5__1 / <>4__this.fadeDuration);
<c>5__2.r = Mathf.Lerp(from, to, <t>5__3);
<c>5__2.g = Mathf.Lerp(from, to, <t>5__3);
<c>5__2.b = Mathf.Lerp(from, to, <t>5__3);
((Graphic)<>4__this._image).color = <c>5__2;
<>2__current = null;
<>1__state = 1;
return true;
}
<c>5__2.r = to;
<c>5__2.g = to;
<c>5__2.b = to;
((Graphic)<>4__this._image).color = <c>5__2;
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <SlideshowLoop>d__14 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public DynamicSpriteSwitcher <>4__this;
private int <index>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SlideshowLoop>d__14(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if (!<>4__this._coroRunning)
{
<>4__this._coroRunning = true;
}
<index>5__1 = 0;
break;
case 1:
<>1__state = -1;
<>4__this._image.sprite = <>4__this.sprites[<index>5__1];
<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.FadeAlpha(0.2f, 1f));
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(<>4__this.displayDuration);
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
<index>5__1 = (<index>5__1 + 1) % <>4__this.sprites.Count;
break;
}
<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.FadeAlpha(1f, 0.2f));
<>1__state = 1;
return true;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public List<Sprite> sprites;
public DisplayMode mode = DisplayMode.Random;
public float displayDuration = 10f;
public float fadeDuration = 1.5f;
private Image _image;
private Coroutine _cycleCoroutine;
private string _key;
private bool _coroRunning;
public void Initialize()
{
_image = ((Component)this).GetComponent<Image>();
if (sprites == null || sprites.Count < 1)
{
LogManager.Debug("[DynamicSpriteSwitcher] No sprites assigned");
((Behaviour)this).enabled = false;
}
else
{
_key = ((Object)((Component)this).gameObject.transform.parent).name + ":" + ((Object)((Component)this).gameObject).name;
Enable();
}
}
private void Enable()
{
if (sprites.Count < 2)
{
_image.sprite = sprites[0];
return;
}
_image.sprite = sprites[1];
switch (mode)
{
case DisplayMode.Random:
ShowRandomSprite();
break;
case DisplayMode.Slideshow:
_cycleCoroutine = ((MonoBehaviour)this).StartCoroutine(SlideshowLoop());
break;
}
}
private void OnDisable()
{
if (_cycleCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_cycleCoroutine);
_cycleCoroutine = null;
}
}
private async void Update()
{
if (((Component)this).gameObject.activeSelf && _cycleCoroutine == null)
{
try
{
Initialize();
}
catch
{
}
await Task.Delay(5000);
}
}
private void ShowRandomSprite()
{
GameModeController instance = GameModeController.Instance;
if (instance == null)
{
LogManager.Error("[DynamicSpriteSwitcher] GameModeController.Instance is null");
return;
}
if (instance.LastChosenSpriteIndices.ContainsKey(_key))
{
instance.LastChosenSpriteIndices[_key] = -1;
}
int num = instance.LastChosenSpriteIndices[_key];
int num2 = Random.Range(0, sprites.Count);
if (sprites.Count > 1)
{
int num3 = 0;
while (num2 == num && num3 < 5)
{
num2 = Random.Range(0, sprites.Count);
num3++;
}
}
_image.sprite = sprites[num2];
instance.LastChosenSpriteIndices[_key] = num2;
}
[IteratorStateMachine(typeof(<SlideshowLoop>d__14))]
private IEnumerator SlideshowLoop()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SlideshowLoop>d__14(0)
{
<>4__this = this
};
}
[IteratorStateMachine(typeof(<FadeAlpha>d__15))]
private IEnumerator FadeAlpha(float from, float to)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <FadeAlpha>d__15(0)
{
<>4__this = this,
from = from,
to = to
};
}
}
public static class LogManager
{
private static ManualLogSource _logSource;
public static void Init(ManualLogSource logSource)
{
_logSource = logSource;
}
public static void Info(object msg)
{
_logSource.LogInfo(msg);
}
public static void Warn(object msg)
{
_logSource.LogWarning(msg);
}
public static void Error(object msg)
{
_logSource.LogError(msg);
}
public static void Debug(object msg)
{
_logSource.LogDebug(msg);
}
}
[BepInIncompatibility("com.validaq.loadintolevel")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("monksilly.CustomGamemodes", "Custom Gamemodes", "0.1.3")]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
public ModContext Context;
public GameObject stuffHolder;
private bool _isObjectInitialized;
private bool _isGameModeManagerInitialized;
private bool _isCustomItemsInitialized;
private void Awake()
{
Instance = this;
Context = ModRegistry.Register("monksilly.CustomGamemodes", "0.1.3");
LogManager.Init(((BaseUnityPlugin)this).Logger);
LogManager.Info("Plugin monksilly.CustomGamemodes v0.1.3 is loaded!");
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
SetupMainObject();
string name = ((Scene)(ref scene)).name;
string text = name;
if (!(text == "Game-Main"))
{
if (text == "Intro")
{
SetupGameModeController();
}
}
else
{
SetupCustomItemHolder();
}
}
private void SetupMainObject()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
if (!_isObjectInitialized)
{
_isObjectInitialized = true;
stuffHolder = new GameObject("CustomGamemodesManager");
Object.DontDestroyOnLoad((Object)(object)stuffHolder);
}
}
private void SetupCustomItemHolder()
{
if (!_isCustomItemsInitialized)
{
_isCustomItemsInitialized = true;
stuffHolder.AddComponent<SpawnController>();
}
}
private void SetupGameModeController()
{
if (!_isGameModeManagerInitialized)
{
_isGameModeManagerInitialized = true;
stuffHolder.AddComponent<GameModeController>();
}
}
}
public class SpawnController : MonoBehaviour
{
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "monksilly.CustomGamemodes";
public const string PLUGIN_NAME = "Custom Gamemodes";
public const string PLUGIN_VERSION = "0.1.3";
}
}
namespace CustomGameModes.Factories
{
public class CapsuleFactory
{
private class Builder
{
private class GiveMeMyUnlocksPls : MonoBehaviour
{
private UI_CapsuleButton capsuleButton;
public string author;
private void Awake()
{
capsuleButton = ((Component)this).GetComponent<UI_CapsuleButton>();
ForceUnlock();
}
private void Update()
{
ForceUnlock();
}
private void OnEnable()
{
ForceUnlock();
if (!string.IsNullOrEmpty(author))
{
Transform val = ((Component)this).transform.Find("Author Name Holder");
Transform val2 = ((val != null) ? val.Find("Author Name") : null);
if (val2 != null)
{
((TMP_Text)((Component)val2).gameObject.GetComponent<TextMeshProUGUI>()).text = author;
}
}
}
private void OnDisable()
{
ForceUnlock();
}
private void ForceUnlock()
{
if (capsuleButton != null && string.IsNullOrEmpty(capsuleButton.unlockAchievement))
{
capsuleButton.unlockAchievement = "ACH_TUTORIAL";
}
}
}
private readonly M_Gamemode _gameMode;
private string _category = "default";
private List<Sprite> _sprites;
private string _author;
private Transform _contentTransform;
private Transform _template;
private Transform _categoryHolder;
private Transform _newCapsule;
public Builder(M_Gamemode gameMode)
{
_gameMode = gameMode;
}
public Builder WithCategory(string category)
{
_category = category;
return this;
}
public Builder WithSprites(List<Sprite> sprites)
{
_sprites = sprites;
return this;
}
public Builder WithAuthor(string author)
{
_author = author;
return this;
}
public void Build()
{
if (ValidateInputs())
{
LocateContentAndTemplate();
PrepareCategoryHolder();
InstantiateCapsule();
ConfigureSprites();
UpdateTextAndName();
AttachUIComponents();
ConfigureRoachCounter();
ConfigureAuthor();
RebuildLayouts();
}
}
private bool ValidateInputs()
{
if (GameModeController.Instance.currentScene != "Main-Menu")
{
return false;
}
if (_gameMode != null)
{
return true;
}
LogManager.Error("[CapsuleFactory] gameMode is null; cannot create capsule.");
return false;
}
private void LocateContentAndTemplate()
{
GameObject obj = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane/Tab Objects/Play Pane - Scroll View Tab - Custom/Viewport/Content");
_contentTransform = ((obj != null) ? obj.transform : null);
if (_contentTransform == null)
{
LogManager.Error("[CapsuleFactory] Content transform not found.");
return;
}
GameObject obj2 = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane/Tab Objects/Play Pane - Scroll View Tab - Endless/Viewport/Content");
Transform val = ((obj2 != null) ? obj2.transform : null);
_template = ((val != null) ? val.Find("Mode Selection Button - Endless") : null);
if (_template == null)
{
LogManager.Error("[CapsuleFactory] Template not found.");
}
}
private void PrepareCategoryHolder()
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
Transform contentTransform = _contentTransform;
if (_category != "default")
{
_categoryHolder = contentTransform.Find(_category + " Holder");
if (_categoryHolder == null)
{
_categoryHolder = CreateCategoryHolder(_category).transform;
_categoryHolder.SetParent(contentTransform);
_categoryHolder.localScale = Vector3.one;
}
}
else
{
_categoryHolder = contentTransform;
}
}
private void InstantiateCapsule()
{
_newCapsule = Object.Instantiate<Transform>(_template, _categoryHolder);
Object.Destroy((Object)(object)((Component)_newCapsule).gameObject.GetComponent<UI_Gamemode_Button>());
Object.Destroy((Object)(object)((Component)_newCapsule).gameObject.GetComponent<UI_CapsuleButton>());
((Component)_newCapsule).gameObject.SetActive(true);
}
private void ConfigureSprites()
{
if (_sprites != null)
{
DynamicSpriteSwitcher dynamicSpriteSwitcher = ((Component)_newCapsule).gameObject.AddComponent<DynamicSpriteSwitcher>();
dynamicSpriteSwitcher.sprites = _sprites;
dynamicSpriteSwitcher.mode = DynamicSpriteSwitcher.DisplayMode.Slideshow;
dynamicSpriteSwitcher.Initialize();
}
}
private void UpdateTextAndName()
{
((Object)_newCapsule).name = "Mode Selection Button - " + _gameMode.gamemodeName;
Transform obj = _newCapsule.Find("Mode Name");
TMP_Text val = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
if (val != null)
{
val.text = _gameMode.gamemodeName;
}
}
private void AttachUIComponents()
{
UI_CapsuleButton val = ((Component)_newCapsule).gameObject.AddComponent<UI_CapsuleButton>();
val.unlockIcon = ((Component)_newCapsule.Find("Lock Image")).GetComponent<Image>();
val.showDelayAnimation = 10f;
val.unlockAchievement = "ACH_TUTORIAL";
((Component)_newCapsule).gameObject.AddComponent<GiveMeMyUnlocksPls>();
((Component)_newCapsule).gameObject.SetActive(false);
UI_Gamemode_Button val2 = ((Component)_newCapsule).gameObject.AddComponent<UI_Gamemode_Button>();
val2.gamemode = _gameMode;
val2.title = ((Component)_newCapsule.Find("Mode Name")).GetComponent<TMP_Text>();
val2.unlockText = (TMP_Text)(object)((Component)_newCapsule.Find("Lock Image/Unlock Requirement")).GetComponent<TextMeshProUGUI>();
GameObject obj = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane/Tab Objects/Play Pane - Scroll View Tab - Endless/Viewport/Content/Mode Selection Button - Endless");
Transform val3 = ((obj != null) ? obj.transform : null);
UI_Gamemode_Button val4 = ((val3 != null) ? ((Component)val3).GetComponent<UI_Gamemode_Button>() : null);
if (val3 != null && val4 != null)
{
val2.medalImage = val4.medalImage;
val2.medals = val4.medals;
val2.showMedals = false;
}
((Component)_newCapsule).gameObject.SetActive(true);
}
private void ConfigureRoachCounter()
{
Transform val = _newCapsule.Find("Roach Counter/Roaches");
if (val != null)
{
((Component)val.parent).gameObject.SetActive(true);
((Component)val).gameObject.SetActive(true);
UI_RoachBankAmount val2 = ((Component)val).gameObject.AddComponent<UI_RoachBankAmount>();
val2.roachBankID = "custom-" + _gameMode.gamemodeName;
}
}
private void ConfigureAuthor()
{
//IL_0080: 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)
if (string.IsNullOrEmpty(_author))
{
return;
}
Transform val = _newCapsule.Find("Roach Counter/Roaches");
Transform val2 = ((val != null) ? val.parent : null);
if (val2 != null)
{
Transform val3 = Object.Instantiate<Transform>(val2, _newCapsule);
((Object)val3).name = "Author Name Holder";
Object.Destroy((Object)(object)((Component)val3).gameObject.GetComponent<Image>());
RectTransform component = ((Component)val3).GetComponent<RectTransform>();
component.anchoredPosition = new Vector2(2.5f, -55f);
Transform child = val3.GetChild(0);
((Object)child).name = "Author Name";
Object.Destroy((Object)(object)((Component)child).gameObject.GetComponent<UI_RoachBankAmount>());
TextMeshProUGUI component2 = ((Component)child).GetComponent<TextMeshProUGUI>();
LogManager.Debug($"Text compotnent is: {component2 != null}");
if (component2 != null)
{
((Component)child).gameObject.SetActive(true);
((TMP_Text)component2).fontSizeMin = 10f;
((TMP_Text)component2).maxVisibleLines = 2;
((TMP_Text)component2).alignment = (TextAlignmentOptions)4097;
((Graphic)component2).color = new Color(1f, 1f, 1f, 1f);
((TMP_Text)component2).text = "By: " + _author;
}
}
}
private void RebuildLayouts()
{
LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)_categoryHolder).GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)_contentTransform).GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)_contentTransform.parent).gameObject.GetComponent<RectTransform>());
}
private static GameObject CreateCategoryHolder(string category)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Expected O, but got Unknown
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: 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)
string text = category + " Holder";
GameObject val = new GameObject(text);
try
{
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchorMin = Vector2.one;
val2.anchorMax = Vector2.one;
val2.anchoredPosition = Vector2.zero;
val2.pivot = Vector2.one * 0.5f;
HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)val3).spacing = 15f;
((LayoutGroup)val3).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = true;
((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = false;
((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = false;
((LayoutGroup)val3).padding = new RectOffset(15, 20, 0, 0);
ContentSizeFitter val4 = val.AddComponent<ContentSizeFitter>();
val4.horizontalFit = (FitMode)1;
val4.verticalFit = (FitMode)0;
val.transform.localScale = Vector3.one;
((Transform)val2).localScale = Vector3.one;
}
catch (Exception ex)
{
LogManager.Error("[CapsuleFactory] Error creating category holder: " + ex.Message);
}
GameObject obj = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane/Tab Objects/Play Pane - Scroll View Tab - Endless/Viewport/Content");
Transform val5 = ((obj != null) ? obj.transform : null);
if (val5 == null)
{
LogManager.Error("[CapsuleFactory] Cannot find Content for category.");
return val;
}
Transform val6 = val5.Find("Mode - Major Section Break - Endless");
if (val6 == null)
{
LogManager.Error("[CapsuleFactory] Section break template missing.");
return val;
}
Transform val7 = Object.Instantiate<Transform>(val6, val.transform);
((Object)val7).name = "Major Section Break.Custom-GameModes";
val7.localScale = Vector3.one;
((Component)val7).gameObject.SetActive(true);
Transform val8 = val7.Find("Section Title/Mode Name");
TextMeshProUGUI component = ((Component)val8).GetComponent<TextMeshProUGUI>();
if (component != null)
{
((TMP_Text)component).text = category;
((TMP_Text)component).faceColor = Color32.op_Implicit(new Color(20f / 51f, 20f / 51f, 20f / 51f, 1f));
((TMP_Text)component).fontSize = 28f;
}
Transform val9 = val7.Find("Section Title/Roach Counter - Regular");
Transform val10 = val7.Find("Section Title/Roach Counter - Hard");
Object.Destroy((Object)(object)((val9 != null) ? ((Component)val9).gameObject : null));
Object.Destroy((Object)(object)((val10 != null) ? ((Component)val10).gameObject : null));
return val;
}
}
public void CreateCapsuleForGameMode(M_Gamemode gameMode, string category = "default", List<Sprite> sprites = null, string author = null)
{
new Builder(gameMode).WithCategory(category).WithSprites(sprites).WithAuthor(author)
.Build();
}
}
}
namespace CustomGameModes.Controllers
{
public class GameModeController : MonoBehaviour
{
private enum ConfigKind
{
Standard,
Premade,
Unknown
}
public static GameModeController Instance;
public string currentScene;
private AssetService _assetService;
private SubRegionBuilder _subregionBuilder;
private RegionBuilder _regionBuilder;
private GamemodeBuilder _gameModeBuilder;
private CapsuleFactory _capsuleFactory;
private const string ConfigFileName = "config.json";
private readonly Dictionary<ConfigKind, Func<string, JObject, Task>> _configHandlers;
private const string GameModesRoot = "Gamemodes";
private const string PlayPane = "Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane";
private readonly Dictionary<string, float> _progressPhases = new Dictionary<string, float>();
private int _expectedPhaseCount;
private Transform _customLoadingGamemodes;
private string _customRoot;
private readonly Dictionary<string, GameObject> _customCategories = new Dictionary<string, GameObject>();
public Dictionary<string, int> LastChosenSpriteIndices { get; } = new Dictionary<string, int>();
public GameModeController()
{
_configHandlers = new Dictionary<ConfigKind, Func<string, JObject, Task>>
{
{
ConfigKind.Premade,
HandlePremadeConfigAsync
},
{
ConfigKind.Standard,
HandleStandardConfigAsync
}
};
}
private void Awake()
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
if (Instance == null || (Object)(object)Instance != (Object)(object)this)
{
Instance = this;
}
else
{
Object.Destroy((Object)(object)this);
}
LogManager.Info("[GameModeController] Awake()");
_assetService = new AssetService(Plugin.Instance.Context);
_subregionBuilder = new SubRegionBuilder();
_regionBuilder = new RegionBuilder();
_gameModeBuilder = new GamemodeBuilder();
_capsuleFactory = new CapsuleFactory();
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string text = Path.Combine(directoryName, "Gamemodes");
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
_customRoot = text;
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
currentScene = ((Scene)(ref scene)).name;
if (!(((Scene)(ref scene)).name != "Main-Menu"))
{
SetupStuff();
((Component)this).gameObject.SetActive(true);
_expectedPhaseCount = 0;
}
}
private async void SetupStuff()
{
LogManager.Info("[GameModeController] Setting up menu!");
PrepareLoadingText();
PreparePlaySection();
PrepareMenuTab();
string baseFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Gamemodes");
string[] folders = Directory.GetDirectories(baseFolder);
string[] array = folders;
for (int i = 0; i < array.Length; i++)
{
await ProcessGamemodeFolderAsync(Path.Combine(path2: array[i], path1: Assembly.GetExecutingAssembly().Location));
}
string[] foldersPlugins = Directory.GetDirectories(Paths.PluginPath);
string[] array2 = foldersPlugins;
for (int j = 0; j < array2.Length; j++)
{
await ProcessGamemodeFolderAsync(Path.Combine(path2: array2[j], path1: Paths.PluginPath));
}
}
private void PrepareLoadingText()
{
//IL_0050: 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)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
Transform transform = GameObject.Find("Canvas - Main Menu").transform;
Transform val = transform.Find("Loading");
Transform val2 = Object.Instantiate<Transform>(val, transform);
((Object)val2).name = "Loading Gamemodes";
RectTransform component = ((Component)val2).GetComponent<RectTransform>();
if (Object.op_Implicit((Object)(object)component))
{
component.offsetMin = new Vector2(-250f, -360f);
component.offsetMax = new Vector2(250f, -255f);
((Component)component).transform.localPosition = new Vector3(0f, -306f, 0f);
}
bool flag = _progressPhases.All((KeyValuePair<string, float> x) => x.Value >= 1f) && _progressPhases.Count == _expectedPhaseCount;
((Component)val2).gameObject.SetActive(!flag);
_customLoadingGamemodes = val2;
}
private void UpdateLoadingText(Dictionary<string, float> progressPhases)
{
if (_customLoadingGamemodes == null || currentScene != "Main-Menu")
{
return;
}
TextMeshProUGUI component = ((Component)_customLoadingGamemodes.Find("Settings Title.01")).GetComponent<TextMeshProUGUI>();
StringBuilder stringBuilder = new StringBuilder();
List<string> list = progressPhases.Keys.ToList();
for (int i = 0; i < list.Count; i++)
{
string text = list[i];
float num = progressPhases[text];
if (!(num >= 1f))
{
stringBuilder.AppendLine($"({i + 1}/{_expectedPhaseCount}) {text}: {num * 100f:0}%");
}
}
((TMP_Text)component).fontSize = 25f;
((TMP_Text)component).text = stringBuilder.ToString();
bool flag = progressPhases.All((KeyValuePair<string, float> x) => x.Value >= 1f) && progressPhases.Count == _expectedPhaseCount;
((Component)_customLoadingGamemodes).gameObject.SetActive(!flag);
}
private async Task CheckIfAllLoaded()
{
if (_progressPhases.All((KeyValuePair<string, float> x) => x.Value >= 1f) && _progressPhases.Count == _expectedPhaseCount)
{
((Component)_customLoadingGamemodes).gameObject.SetActive(false);
return;
}
await Task.Delay(1000);
await Task.Run((Func<Task?>)CheckIfAllLoaded);
}
private async Task ProcessGamemodeFolderAsync(string folderPath)
{
string configPath = Path.Combine(folderPath, "config.json");
if (File.Exists(configPath))
{
string jsonText;
try
{
jsonText = await File.ReadAllTextAsync(configPath);
}
catch (Exception ex)
{
Exception e2 = ex;
LogManager.Error("[GameModeLoader] Failed reading " + configPath + ": " + e2.Message);
return;
}
JObject root;
try
{
root = JObject.Parse(jsonText);
}
catch (Exception e)
{
LogManager.Error("[GameModeLoader] Invalid JSON in " + configPath + ": " + e.Message);
return;
}
ConfigKind kind = DetectConfigKind(root);
if (!_configHandlers.TryGetValue(kind, out var handler))
{
LogManager.Error($"[GameModeLoader] No handler for config kind {kind}");
}
else
{
await handler(folderPath, root);
}
}
}
private async Task HandleStandardConfigAsync(string folderPath, JObject root)
{
_expectedPhaseCount += 2;
try
{
GamemodeConfig cfg;
try
{
cfg = ((JToken)root).ToObject<GamemodeConfig>();
}
catch (Exception ex)
{
Exception e = ex;
LogManager.Error($"[GameModeLoader] Invalid Standard Config Structure: {e}");
return;
}
if (cfg.regions == null)
{
LogManager.Error("[GameModeLoader] Standard Config is missing regions");
return;
}
string assetsFolder = Path.Combine(folderPath, "Assets");
if (cfg.assetBundleFileName != null && !File.Exists(Path.Combine(assetsFolder, cfg.assetBundleFileName)))
{
LogManager.Error("[GameModeLoader] Standard Config is missing asset bundle file");
return;
}
string gmName = cfg.gamemodeName;
string levelPhaseKey = "Loading Levels for \"" + gmName + "\"";
_progressPhases[levelPhaseKey] = 0f;
IProgress<float> levelProgress = new Progress<float>(delegate(float p)
{
_progressPhases[levelPhaseKey] = p;
UpdateLoadingText(_progressPhases);
});
Sprite capsuleSprite = _assetService.LoadPngAsSprite(Path.Combine(assetsFolder, cfg.capsuleIcon));
Sprite screenSprite = _assetService.LoadPngAsSprite(Path.Combine(assetsFolder, cfg.screenIcon));
Dictionary<string, M_Level> allLevels = new Dictionary<string, M_Level>();
foreach (GameObject inGameLevel in WkLib.Instance.WKdb.levelPrefabs)
{
allLevels.TryAdd(((Object)inGameLevel).name, inGameLevel.GetComponent<M_Level>());
}
if (!string.IsNullOrEmpty(cfg.assetBundleFileName))
{
AssetBundle bundle = await _assetService.LoadBundleRelativeAsync(Path.Combine(assetsFolder, cfg.assetBundleFileName), levelProgress);
Dictionary<string, M_Level> levelsToAdd = (await _assetService.LoadAllLevelsFromBundle(bundle, levelProgress)).Where((KeyValuePair<string, M_Level> x) => !allLevels.Contains(x)).ToDictionary((KeyValuePair<string, M_Level> x) => x.Key, (KeyValuePair<string, M_Level> x) => x.Value);
Extensions.AddRange<string, M_Level>(allLevels, levelsToAdd);
}
List<M_Region> regions = cfg.regions.Select((RegionConfig rc) => BuildRegion(rc, allLevels)).ToList();
string gmPhaseKey = "Loading Gamemode for \"" + gmName + "\"";
_progressPhases[gmPhaseKey] = 0f;
IProgress<float> gmProgress = new Progress<float>(delegate(float p)
{
_progressPhases[gmPhaseKey] = p;
UpdateLoadingText(_progressPhases);
});
M_Gamemode gm = _gameModeBuilder.WithRegions(regions).WithName(cfg.gamemodeName).WithIntroText(cfg.introText)
.IsEndless(cfg.isEndless)
.HasPerks(cfg.hasPerks)
.HasRevives(cfg.hasRevives)
.WithCapsuleSprite(capsuleSprite)
.WithScreenArt(screenSprite)
.WithGameType(cfg.gameType ?? "single")
.Build();
levelProgress.Report(1f);
gmProgress.Report(1f);
_capsuleFactory.CreateCapsuleForGameMode(gm, cfg.category ?? "default", null, cfg.author);
}
catch
{
LogManager.Error("Couldn't process " + folderPath);
}
}
private async Task HandlePremadeConfigAsync(string folderPath, JObject root)
{
_expectedPhaseCount += 3;
try
{
PremadeGamemodeConfig cfg;
try
{
cfg = ((JToken)root).ToObject<PremadeGamemodeConfig>();
}
catch (Exception ex)
{
Exception e = ex;
LogManager.Error($"[GameModeLoader] Invalid Premade Config Structure: {e}");
return;
}
if (string.IsNullOrEmpty(cfg.assetBundle) || string.IsNullOrEmpty(cfg.gamemodeName))
{
LogManager.Error("[GamemodeLoader] Premade config is missing required fields");
return;
}
string assetsFolder = Path.Combine(folderPath, "Assets");
if (!Directory.Exists(assetsFolder))
{
LogManager.Error("[GamemodeLoader] Premade Assets folder is missing");
return;
}
string gmName = cfg.gamemodeName;
string assetPhaseProgress = "Loading Assets for \"" + gmName + "\"";
_progressPhases[assetPhaseProgress] = 0f;
IProgress<float> assetProgress = new Progress<float>(delegate(float p)
{
_progressPhases[assetPhaseProgress] = p;
UpdateLoadingText(_progressPhases);
});
AssetBundle bundle = await _assetService.LoadBundleRelativeAsync(Path.Combine(assetsFolder, cfg.assetBundle), assetProgress);
string levelPhaseKey = "Loading Levels for \"" + gmName + "\"";
_progressPhases[levelPhaseKey] = 0f;
IProgress<float> levelProgress = new Progress<float>(delegate(float p)
{
_progressPhases[levelPhaseKey] = p;
UpdateLoadingText(_progressPhases);
});
await _assetService.LoadAllLevelsFromBundle(bundle, levelProgress);
string gmPhaseKey = "Loading Gamemode \"" + gmName + "\"";
_progressPhases[gmPhaseKey] = 0f;
IProgress<float> gmProgress = new Progress<float>(delegate(float p)
{
_progressPhases[gmPhaseKey] = p;
UpdateLoadingText(_progressPhases);
});
M_Gamemode gm = await _assetService.LoadGameModeFromBundle(bundle, cfg.gamemodeName, gmProgress);
List<Sprite> capsuleArtsFinal = null;
if (cfg.capsuleArts != null)
{
if (cfg.capsuleArts.Count == 1)
{
Sprite loadedArt = _assetService.LoadPngAsSprite(cfg.capsuleArts[0]);
if (loadedArt == null)
{
LogManager.Error("Failed to load " + cfg.capsuleArts[0] + " for the capsule art! (gamemode: " + cfg.gamemodeName + ")");
}
else
{
gm.capsuleArt = _assetService.LoadPngAsSprite(cfg.capsuleArts[0]);
}
}
else
{
List<Sprite> capsuleArts = new List<Sprite>();
capsuleArts.AddRange(from capsuleArt in cfg.capsuleArts
select _assetService.LoadPngAsSprite(Path.Combine(assetsFolder, capsuleArt)) into x
where x != null
select x);
capsuleArtsFinal = capsuleArts;
}
}
ApplyRandomArt(cfg.screenArts, assetsFolder, gm, delegate(string a)
{
gm.screenArt = _assetService.LoadPngAsSprite(a);
});
levelProgress.Report(1f);
gmProgress.Report(1f);
_capsuleFactory.CreateCapsuleForGameMode(gm, cfg.category ?? "default", capsuleArtsFinal, cfg.author);
}
catch
{
LogManager.Error("Couldn't process " + folderPath);
}
}
private static ConfigKind DetectConfigKind(JObject j)
{
if (j["assetBundle"] != null && j["gamemodeName"] != null)
{
return ConfigKind.Premade;
}
if (j["regions"] != null)
{
return ConfigKind.Standard;
}
return ConfigKind.Unknown;
}
private static void ApplyRandomArt(List<string> paths, string baseFolder, M_Gamemode gm, Action<string> apply)
{
if (paths != null && paths.Count != 0)
{
string path = ((paths.Count == 1) ? paths[0] : paths[Random.Range(0, paths.Count - 1)]);
string obj = Path.Combine(baseFolder, path);
apply(obj);
}
}
private M_Region BuildRegion(RegionConfig rc, Dictionary<string, M_Level> levels)
{
List<M_Subregion> list = (rc.subregions ?? new List<SubregionConfig>()).Select(delegate(SubregionConfig src)
{
List<M_Level> list2 = FindMatchingLevels(src, levels);
return _subregionBuilder.WithName(src.subregionName).WithLevels(list2).Build();
}).ToList();
return _regionBuilder.WithName(rc.regionName).WithSubregions(list).Build();
}
private List<M_Level> FindMatchingLevels(SubregionConfig src, Dictionary<string, M_Level> levels)
{
if (levels != null && src.levelNameContains != null)
{
return (from kv in levels
where kv.Key.IndexOf(src.levelNameContains, StringComparison.OrdinalIgnoreCase) >= 0
select kv.Value).ToList();
}
if (src.levels != null)
{
return src.levels.SelectMany((string lvl) => _assetService.FindLevelsByName(lvl)).ToList();
}
LogManager.Error("[GamemodeLoader] No matching rule for subregion " + src.subregionName);
return new List<M_Level>();
}
private void PrepareMenuTab()
{
GameObject val = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane/Tabs/Tab Buttons");
if (val != null)
{
Transform obj = val.transform.Find("ModeButton_Custom");
GameObject val2 = ((obj != null) ? ((Component)obj).gameObject : null);
if (val2 != null)
{
val2.gameObject.SetActive(true);
}
}
}
private void PreparePlaySection()
{
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Expected O, but got Unknown
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Expected O, but got Unknown
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane/Tab Objects/Play Pane - Scroll View Tab - Custom/Viewport/Content");
Transform val = ((obj != null) ? obj.transform : null);
if (val == null)
{
LogManager.Error("[GameModeController] Cannot find Play Menu content.");
return;
}
for (int i = 0; i < val.childCount; i++)
{
((Component)val.GetChild(i)).gameObject.SetActive(false);
}
GameObject obj2 = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Play/Play Menu/Play Pane/Tab Objects/Play Pane - Scroll View Tab - Endless/Viewport/Content");
Transform val2 = ((obj2 != null) ? obj2.transform : null);
if (val2 == null)
{
LogManager.Error("[GameModeController] Cannot find content To Copy From.");
return;
}
Transform val3 = val2.Find("Mode - Major Section Break - Endless");
if (val3 == null)
{
LogManager.Error("[GameModeController] Cannot find section‐break template.");
return;
}
Transform val4 = Object.Instantiate<Transform>(val3, val);
((Object)val4).name = "Major Section Break.Custom-GameModes";
val4.localScale = Vector3.one;
((Component)val4).gameObject.SetActive(false);
Transform obj3 = val4.Find("Break.02");
if (obj3 != null)
{
((Component)obj3).gameObject.SetActive(true);
}
GameObject val5 = new GameObject("Custom Gamemodes Holder");
RectTransform val6 = val5.AddComponent<RectTransform>();
val6.anchorMin = Vector2.one;
val6.anchorMax = Vector2.one;
val6.anchoredPosition = Vector2.zero;
val6.pivot = Vector2.one * 0.5f;
HorizontalLayoutGroup val7 = val5.AddComponent<HorizontalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)val7).spacing = 7.5f;
((LayoutGroup)val7).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)val7).childForceExpandHeight = true;
((HorizontalOrVerticalLayoutGroup)val7).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)val7).childControlWidth = false;
((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = false;
((LayoutGroup)val7).padding = new RectOffset(5, 10, 0, 0);
val5.transform.SetParent(((Component)val).transform);
ContentSizeFitter val8 = val5.AddComponent<ContentSizeFitter>();
val8.verticalFit = (FitMode)0;
val8.horizontalFit = (FitMode)1;
val5.transform.localScale = Vector3.one;
((Transform)val6).localScale = Vector3.one;
Transform val9 = val4.Find("Section Title/Mode Name");
TextMeshProUGUI val10 = ((val9 != null) ? ((Component)val9).GetComponent<TextMeshProUGUI>() : null);
if (val10 != null)
{
((TMP_Text)val10).text = "Custom GameModes".ToUpper();
}
Transform val11 = val4.Find("Section Title/Roach Counter - Regular");
Transform val12 = val4.Find("Section Title/Roach Counter - Hard");
object obj4;
if (val11 == null)
{
obj4 = null;
}
else
{
GameObject gameObject = ((Component)val11).gameObject;
obj4 = ((gameObject != null) ? gameObject.GetComponent<UT_HardModeEnable>() : null);
}
Object.Destroy((Object)obj4);
Object.Destroy((Object)(object)((val11 != null) ? ((Component)val11.GetChild(0)).GetComponent<UI_RoachBankAmount>() : null));
Object.Destroy((Object)(object)((val11 != null) ? ((Component)val11).gameObject : null));
Object.Destroy((Object)(object)((val12 != null) ? ((Component)val12).gameObject : null));
}
}
}
namespace CustomGameModes.Config
{
[Serializable]
public class GamemodeConfig
{
public string gamemodeName;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public string author;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public string category;
public string introText;
public bool isEndless;
public bool hasPerks;
public bool hasRevives;
public string capsuleIcon;
public string screenIcon;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public string assetBundleFileName;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public string gameType;
public List<RegionConfig> regions;
}
[Serializable]
public class PremadeGamemodeConfig
{
public string assetBundle;
public string gamemodeName;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public string author;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public string category;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public List<string> capsuleArts;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public List<string> screenArts;
}
[Serializable]
public class RegionConfig
{
public string regionName;
public List<SubregionConfig> subregions;
}
[Serializable]
public class SubregionConfig
{
public string subregionName;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public string levelNameContains;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public List<string> levels;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public List<string> blacklist;
}
}