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 BepInEx;
using BepInEx.Configuration;
using GameConsole;
using HarmonyLib;
using UltraBlocks;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
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: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("UltraBlocks")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Adds Lucky Blocks")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("UltraBlocks")]
[assembly: AssemblyTitle("UltraBlocks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public class UltraBlock : MonoBehaviour
{
[Tooltip("max 100")]
public float luck;
public bool RandomizeLuck;
private void Start()
{
if (RandomizeLuck)
{
luck = Random.Range(0, 100);
}
}
public void OnBreak()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Plugin.SpawnBlockEvent(luck, ((Component)this).transform.position);
}
}
namespace UltraBlocks;
public class GenerateRandomLuckyBlock : ICommand
{
public string Name => "generateluckyblock";
public string Description => "Spawns a random Lucky Block";
public string Command => "GenerateLuckyBlock";
public void Execute(Console con, string[] args)
{
if (args.Length == 0)
{
Plugin.plugin.SpawnLuckyBlock();
}
if (float.TryParse(args[0], out var result))
{
for (int i = 1; i < (int)result; i++)
{
Plugin.plugin.SpawnLuckyBlock();
}
}
else
{
Plugin.plugin.SpawnLuckyBlock();
}
}
}
[BepInPlugin("ultrablocks.bananastudio", "UltraBlocks", "0.0.1")]
public class Plugin : BaseUnityPlugin
{
public static SpawnableObject LuckBlockSpawnable;
private static List<Vector3> takenPos = new List<Vector3>();
private static List<GameObject> GoodEvents = new List<GameObject>();
private static List<GameObject> NeutralEvents = new List<GameObject>();
private static List<GameObject> BadEvents = new List<GameObject>();
private static List<Transform> allTransforms = new List<Transform>();
public static Plugin plugin;
private ConfigEntry<int> amountOfLuckyBlocks;
private Harmony harmony;
private void Awake()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
plugin = this;
amountOfLuckyBlocks = ((BaseUnityPlugin)this).Config.Bind<int>("Configs", "Amount of lucky blocks", 50, "controls how many lucky blocks spawn in a level");
harmony = new Harmony("ultrablocks.bananastudio");
harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin ultrablocks.bananastudio is loaded!");
Assembly executingAssembly = Assembly.GetExecutingAssembly();
AssetBundle val = AssetBundle.LoadFromStream(executingAssembly.GetManifestResourceStream("UltraBlocks.luckyblockmod.bundle"));
object[] array = val.LoadAllAssets();
object[] array2 = array;
object[] array3 = array2;
foreach (object obj in array3)
{
GameObject val2 = (GameObject)((obj is GameObject) ? obj : null);
if (val2 != null)
{
if (((Object)val2).name.Contains("Good"))
{
GoodEvents.Add(val2);
}
if (((Object)val2).name.Contains("Bad"))
{
BadEvents.Add(val2);
}
if (((Object)val2).name.Contains("Neutral"))
{
NeutralEvents.Add(val2);
}
}
SpawnableObject val3 = (SpawnableObject)((obj is SpawnableObject) ? obj : null);
if (val3 != null)
{
Debug.Log((object)val3.objectName);
LuckBlockSpawnable = val3;
LuckBlockSpawnable = val3;
((MonoBehaviour)this).StartCoroutine(ShaderManager.ApplyShaderToGameObject(val3.gameObject));
}
}
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
}
private Transform FindNearestTransform(Vector3 position)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
if (allTransforms.Count == 0)
{
return null;
}
return allTransforms.OrderBy((Transform t) => Vector3.Distance(t.position, position)).FirstOrDefault();
}
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
{
takenPos.Clear();
if (ShaderManager.shaderDictionary.Count <= 0)
{
((MonoBehaviour)this).StartCoroutine(ShaderManager.LoadShadersAsync());
}
else
{
((MonoBehaviour)this).StartCoroutine(ShaderManager.ApplyShaderToGameObject(LuckBlockSpawnable.gameObject));
((MonoBehaviour)this).StartCoroutine(ShaderManager.ApplyShadersAsync(GoodEvents.ToArray()));
((MonoBehaviour)this).StartCoroutine(ShaderManager.ApplyShadersAsync(NeutralEvents.ToArray()));
((MonoBehaviour)this).StartCoroutine(ShaderManager.ApplyShadersAsync(BadEvents.ToArray()));
}
MonoSingleton<Console>.Instance.RegisterCommand((ICommand)(object)new GenerateRandomLuckyBlock());
MonoSingleton<Console>.Instance.RegisterCommand((ICommand)(object)new SpawnEvent());
allTransforms = Resources.FindObjectsOfTypeAll<Transform>().ToList();
allTransforms.RemoveAll((Transform x) => (Object)(object)((Component)x).gameObject.GetComponent<Renderer>() == (Object)null);
allTransforms.RemoveAll((Transform x) => (Object)(object)((Component)x).gameObject.GetComponent<EnemyIdentifier>() != (Object)null);
allTransforms.RemoveAll((Transform x) => hasEnemyParent(x));
allTransforms.RemoveAll((Transform x) => hasQuadParent(x));
allTransforms.RemoveAll((Transform x) => ((Object)((Component)x).gameObject).name == "Quad");
allTransforms.RemoveAll((Transform x) => ((Component)x).gameObject.scene != SceneManager.GetActiveScene());
Debug.Log((object)allTransforms.Count);
for (int i = 1; i < amountOfLuckyBlocks.Value; i++)
{
plugin.SpawnLuckyBlock();
}
}
private bool hasEnemyParent(Transform x)
{
if ((Object)(object)x.parent == (Object)null)
{
return false;
}
return (Object)(object)((Component)x.parent).gameObject.GetComponent<EnemyIdentifier>() != (Object)null;
}
private bool hasQuadParent(Transform x)
{
if ((Object)(object)x.parent == (Object)null)
{
return false;
}
return ((Object)((Component)x.parent).gameObject).name == "Quad";
}
public void SpawnLuckyBlock()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
GameObject gameObject = LuckBlockSpawnable.gameObject;
gameObject.AddComponent<Breakable>().weak = true;
if (GetRandomPointOnNavMesh(out var result))
{
GameObject val = Object.Instantiate<GameObject>(gameObject, result, Quaternion.identity);
Transform val2 = FindNearestTransform(result);
if ((Object)(object)val2 != (Object)null)
{
val.transform.SetParent(val2);
}
if (ShaderManager.shaderDictionary.Count > 0)
{
((MonoBehaviour)this).StartCoroutine(ShaderManager.ApplyShaderToGameObject(val));
}
}
}
public static void SpawnBlockEvent(float luck, Vector3 spawnPos)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
GameObject val = null;
val = ((luck >= 66f) ? GetRandomEvent(GoodEvents) : ((!(luck >= 33f)) ? GetRandomEvent(BadEvents) : GetRandomEvent(NeutralEvents)));
if ((Object)(object)val != (Object)null)
{
Object.Instantiate<GameObject>(val, spawnPos, Quaternion.identity);
Debug.Log((object)("Spawned event: " + ((Object)val).name));
}
else
{
Debug.LogWarning((object)"No event to spawn.");
}
}
private static GameObject GetRandomEvent(List<GameObject> events)
{
if (events == null || events.Count == 0)
{
return null;
}
int index = Random.Range(0, events.Count);
return events[index];
}
private static bool GetRandomPointOnNavMesh(out Vector3 result)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//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_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: 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_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: 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_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
NavMeshTriangulation val = NavMesh.CalculateTriangulation();
Vector3[] vertices = val.vertices;
if (vertices.Length == 0)
{
result = Vector3.zero;
return false;
}
Bounds val2 = default(Bounds);
((Bounds)(ref val2))..ctor(vertices[0], Vector3.zero);
for (int i = 1; i < vertices.Length; i++)
{
((Bounds)(ref val2)).Encapsulate(vertices[i]);
}
Vector3 val3 = default(Vector3);
NavMeshHit val4 = default(NavMeshHit);
for (int j = 0; j < 250; j++)
{
((Vector3)(ref val3))..ctor(Random.Range(((Bounds)(ref val2)).min.x, ((Bounds)(ref val2)).max.x), Random.Range(((Bounds)(ref val2)).min.y, ((Bounds)(ref val2)).max.y), Random.Range(((Bounds)(ref val2)).min.z, ((Bounds)(ref val2)).max.z));
if (NavMesh.SamplePosition(val3, ref val4, 200f, -1) && !takenPos.Contains(((NavMeshHit)(ref val4)).position))
{
takenPos.Add(((NavMeshHit)(ref val4)).position);
result = ((NavMeshHit)(ref val4)).position;
return true;
}
}
result = Vector3.zero;
return false;
}
}
[HarmonyPatch(typeof(SpawnMenu), "RebuildMenu")]
public class AddLuckyBlock
{
public static bool Prefix(ref SpawnableObjectsDatabase ___objects)
{
Debug.Log((object)"rebuild");
if ((Object)(object)Plugin.LuckBlockSpawnable == (Object)null)
{
return true;
}
Debug.Log((object)"Prefix");
List<SpawnableObject> list = ___objects.specialSandbox.ToList();
if (!list.Contains(Plugin.LuckBlockSpawnable))
{
Debug.Log((object)"adding spawnable");
list.Add(Plugin.LuckBlockSpawnable);
___objects.specialSandbox = list.ToArray();
}
return true;
}
}
public static class ShaderManager
{
public class ShaderInfo
{
public string Name { get; set; }
}
public static Dictionary<string, Shader> shaderDictionary = new Dictionary<string, Shader>();
private static HashSet<Material> modifiedMaterials = new HashSet<Material>();
public static IEnumerator LoadShadersAsync()
{
AsyncOperationHandle<IResourceLocator> handle = Addressables.InitializeAsync();
while (!handle.IsDone)
{
yield return null;
}
if ((int)handle.Status == 1)
{
IResourceLocator result = handle.Result;
foreach (object obj in ((ResourceLocationMap)result).Keys)
{
string text = (string)obj;
if (!text.EndsWith(".shader"))
{
continue;
}
AsyncOperationHandle<Shader> shaderHandle = Addressables.LoadAssetAsync<Shader>((object)text);
while (!shaderHandle.IsDone)
{
yield return null;
}
if ((int)shaderHandle.Status == 1)
{
Shader result2 = shaderHandle.Result;
if ((Object)(object)result2 != (Object)null && ((Object)result2).name != "ULTRAKILL/PostProcessV2" && !shaderDictionary.ContainsKey(((Object)result2).name))
{
shaderDictionary[((Object)result2).name] = result2;
}
}
else
{
string str = "Failed to load shader: ";
Debug.LogError((object)(str + shaderHandle.OperationException));
}
}
}
else
{
string str2 = "Addressables initialization failed: ";
Debug.LogError((object)(str2 + handle.OperationException));
}
}
public static string ModPath()
{
return Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(Path.DirectorySeparatorChar));
}
public static IEnumerator ApplyShadersAsync(GameObject[] allGameObjects)
{
if (allGameObjects == null)
{
yield break;
}
foreach (GameObject gameObject in allGameObjects)
{
if ((Object)(object)gameObject == (Object)null)
{
continue;
}
Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
foreach (Renderer renderer in componentsInChildren)
{
if ((Object)(object)renderer == (Object)null)
{
continue;
}
Material[] array2 = (Material[])(object)new Material[renderer.sharedMaterials.Length];
for (int i = 0; i < renderer.sharedMaterials.Length; i++)
{
Material material = (array2[i] = renderer.sharedMaterials[i]);
if (!((Object)(object)material == (Object)null) && !((Object)(object)material.shader == (Object)null) && !modifiedMaterials.Contains(material) && !(((Object)material.shader).name == "ULTRAKILL/PostProcessV2") && shaderDictionary.TryGetValue(((Object)material.shader).name, out var shader))
{
array2[i].shader = shader;
modifiedMaterials.Add(material);
}
shader = null;
}
renderer.materials = array2;
}
yield return null;
}
}
public static IEnumerator ApplyShaderToGameObject(GameObject gameObject)
{
if ((Object)(object)gameObject == (Object)null)
{
yield break;
}
Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
foreach (Renderer renderer in componentsInChildren)
{
if ((Object)(object)renderer == (Object)null)
{
continue;
}
Material[] array2 = (Material[])(object)new Material[renderer.sharedMaterials.Length];
for (int i = 0; i < renderer.sharedMaterials.Length; i++)
{
Material material = (array2[i] = renderer.sharedMaterials[i]);
if (!((Object)(object)material == (Object)null) && !((Object)(object)material.shader == (Object)null) && !modifiedMaterials.Contains(material) && !(((Object)material.shader).name == "ULTRAKILL/PostProcessV2") && shaderDictionary.TryGetValue(((Object)material.shader).name, out var shader))
{
array2[i].shader = shader;
modifiedMaterials.Add(material);
}
shader = null;
}
renderer.materials = array2;
}
yield return null;
}
}
public class SpawnEvent : ICommand
{
public string Name => "spawn event";
public string Description => "Spawns a random event (args: Neutral, Good, Bad)";
public string Command => "SpawnEvent";
public void Execute(Console con, string[] args)
{
//IL_0034: 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_006c: Unknown result type (might be due to invalid IL or missing references)
string text = args[0];
string text2 = text;
string text3 = text2;
if (!(text3 == "Neutral"))
{
if (text3 == "Bad")
{
Plugin.SpawnBlockEvent(0f, ((Component)MonoSingleton<NewMovement>.Instance).transform.position);
}
else
{
Plugin.SpawnBlockEvent(100f, ((Component)MonoSingleton<NewMovement>.Instance).transform.position);
}
}
else
{
Plugin.SpawnBlockEvent(50f, ((Component)MonoSingleton<NewMovement>.Instance).transform.position);
}
}
}