Decompiled source of Jolly Coop v1.1.0

JollyCoop.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using Dungeonator;
using HarmonyLib;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("JollyCoop")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JollyCoop")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("825bc8e2-2faf-496c-803c-3f3e31eba1a0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace JollyCoop;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("kleirof.etg.jollycoop", "Jolly Coop", "1.1.0")]
public class JollyCoopModule : BaseUnityPlugin
{
	public class JollyCoopPatches
	{
		[HarmonyILManipulator]
		[HarmonyPatch(typeof(Chest), "Open")]
		public static void OpenPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(ctx);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<PlayerController>(x, "TriggerItemAcquisition")
			}))
			{
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Action<Chest>>((Action<Chest>)delegate(Chest self)
			{
				if (!self.IsRainbowChest)
				{
					AddItem(self);
				}
			});
		}

		[HarmonyILManipulator]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void HandleSynergyGambleChestPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(ctx);
			FieldInfo fieldInfo = AccessTools.Field(Type.GetType("Chest+<HandleSynergyGambleChest>c__Iterator4, Assembly-CSharp"), "$this");
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "Chest+<HandleSynergyGambleChest>c__Iterator4", "player"),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<PlayerController>(x, "TriggerItemAcquisition")
			}))
			{
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldfld, fieldInfo);
				val.EmitDelegate<Action<Chest>>((Action<Chest>)delegate(Chest self)
				{
					AddItem(self);
				});
			}
		}

		[HarmonyILManipulator]
		[HarmonyPatch(typeof(Chest), "OnBroken")]
		public static void OnBrokenPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(ctx);
			for (int i = 0; i < 6; i++)
			{
				if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[6]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
					(Instruction x) => ILPatternMatchingExt.MatchCall<Chest>(x, "PresentItem"),
					(Instruction x) => ILPatternMatchingExt.MatchCall<MonoBehaviour>(x, "StartCoroutine"),
					(Instruction x) => ILPatternMatchingExt.MatchPop(x),
					(Instruction x) => ILPatternMatchingExt.Match(x, OpCodes.Br)
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.EmitDelegate<Action<Chest>>((Action<Chest>)delegate(Chest self)
					{
						AddItem(self);
					});
				}
				val.Index += 6;
			}
		}

		[HarmonyILManipulator]
		[HarmonyPatch(typeof(RoomHandler), "HandleRoomClearReward")]
		public static void HandleRoomClearRewardPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(ctx);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 4),
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 5),
				(Instruction x) => ILPatternMatchingExt.Match(x, OpCodes.Ble_Un)
			}))
			{
				val.Index += 2;
				val.EmitDelegate<Func<float, float>>((Func<float, float>)((float orig) => (m_RoomItemDropInc && (int)GameManager.Instance.CurrentGameType == 1) ? (orig * 1.5f) : orig));
			}
		}

		[HarmonyILManipulator]
		[HarmonyPatch(typeof(RoomHandler), "HandleBossClearReward")]
		public static void HandleBossClearRewardPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(ctx);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdsfld<IntVector2>(x, "Left"),
				(Instruction x) => ILPatternMatchingExt.MatchCall<IntVector2>(x, "op_Addition"),
				(Instruction x) => ILPatternMatchingExt.MatchStloc(x, 2)
			}))
			{
				val.Emit(OpCodes.Ldloc_2);
				val.Emit(OpCodes.Ldloc, 12);
				val.EmitDelegate<Func<IntVector2, bool, IntVector2>>((Func<IntVector2, bool, IntVector2>)((IntVector2 orig, bool flag2) => (m_MasterDoubled && flag2 && (int)GameManager.Instance.CurrentGameType == 1) ? (orig + IntVector2.Left) : orig));
				val.Emit(OpCodes.Stloc_2);
			}
			val.Index = 0;
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 18),
				(Instruction x) => ILPatternMatchingExt.MatchLdnull(x),
				(Instruction x) => ILPatternMatchingExt.MatchStfld<RewardPedestal>(x, "MimicGuid")
			}))
			{
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc_2);
			val.Emit(OpCodes.Ldloc, 10);
			val.EmitDelegate<Action<RoomHandler, IntVector2, RewardPedestal>>((Action<RoomHandler, IntVector2, RewardPedestal>)delegate(RoomHandler self, IntVector2 intVector, RewardPedestal component)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: 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_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				if (m_MasterDoubled && (int)GameManager.Instance.CurrentGameType == 1)
				{
					Dungeon dungeon = GameManager.Instance.Dungeon;
					intVector += new IntVector2(2, 0);
					RewardPedestal val2 = RewardPedestal.Spawn(component, intVector, self);
					dungeon.data[intVector].isOccupied = true;
					dungeon.data[intVector + IntVector2.Right].isOccupied = true;
					dungeon.data[intVector + IntVector2.Up].isOccupied = true;
					dungeon.data[intVector + IntVector2.One].isOccupied = true;
					dungeon.HasGivenMasteryToken = true;
					val2.SpawnsTertiarySet = false;
					val2.contents = PickupObjectDatabase.GetById(dungeon.BossMasteryTokenItemId);
					val2.MimicGuid = null;
				}
			});
		}

		[HarmonyILManipulator]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void SpawnBehavior_CRPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(ctx);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCall<BraveBehaviour>(x, "get_sprite"),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<tk2dBaseSprite>(x, "get_WorldCenter"),
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 2f)
			}))
			{
				val.EmitDelegate<Func<float, float>>((Func<float, float>)((float orig) => (m_RoomItemDropInc && (int)GameManager.Instance.CurrentGameType == 1 && GameManager.Instance.Dungeon.HasGivenMasteryToken) ? (orig + 2f) : orig));
			}
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCall<BraveBehaviour>(x, "get_sprite"),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<tk2dBaseSprite>(x, "get_WorldCenter"),
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0f),
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, -3f)
			}))
			{
				val.EmitDelegate<Func<float, float>>((Func<float, float>)((float orig) => (m_RoomItemDropInc && (int)GameManager.Instance.CurrentGameType == 1 && GameManager.Instance.Dungeon.HasGivenMasteryToken) ? (orig - 2f) : orig));
			}
		}

		[HarmonyILManipulator]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void RegeneratePatch(ILContext ctx)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(ctx);
			MethodInfo mi = AccessTools.Method(typeof(Vector3?), "get_Value", (Type[])null, (Type[])null);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<GameManager>(x, "get_RewardManager"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<RewardManager>(x, "A_Chest"),
				(Instruction x) => ILPatternMatchingExt.MatchLdloca(x, 10),
				(Instruction x) => ILPatternMatchingExt.MatchCall(x, (MethodBase)mi)
			}))
			{
				val.EmitDelegate<Func<Vector3, Vector3>>((Func<Vector3, Vector3>)((Vector3 orig) => (m_RainbowDoubled && (int)GameManager.Instance.CurrentGameType == 1) ? (orig - new Vector3(4f, 0f, 0f)) : orig));
			}
			FieldInfo fieldInfo = AccessTools.Field(Type.GetType("Dungeonator.Dungeon+<Regenerate>c__Iterator1, Assembly-CSharp"), "$this");
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 15),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<Chest>(x, "BecomeRainbowChest")
			}))
			{
				return;
			}
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldfld, fieldInfo);
			val.Emit(OpCodes.Ldloc, 10);
			val.EmitDelegate<Action<Dungeon, Vector3?>>((Action<Dungeon, Vector3?>)delegate(Dungeon self, Vector3? vector)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				if (m_RainbowDoubled && (int)GameManager.Instance.CurrentGameType == 1)
				{
					Vector3? val2 = vector;
					Vector3 val3 = default(Vector3);
					((Vector3)(ref val3))..ctor(4f, 0f, 0f);
					((MonoBehaviour)self).StartCoroutine(SpawnChest((val2.HasValue ? new Vector3?(val2.GetValueOrDefault() + val3) : null).Value, self.data.Entrance));
				}
			});
		}

		[HarmonyILManipulator]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void get_BaseLevelHealthModifierPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(ctx);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCall<GameManager>(x, "get_Instance"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<GameManager>(x, "COOP_ENEMY_HEALTH_MULTIPLIER")
			}))
			{
				val.EmitDelegate<Func<float, float>>((Func<float, float>)((float orig) => EnemyHealth));
			}
		}

		[HarmonyILManipulator]
		[HarmonyPatch(typeof(HealthHaver), "Start")]
		public static void StartPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(ctx);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCall<GameManager>(x, "get_Instance"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<GameManager>(x, "COOP_ENEMY_HEALTH_MULTIPLIER")
			}))
			{
				val.EmitDelegate<Func<float, float>>((Func<float, float>)((float orig) => EnemyHealth));
			}
		}

		[HarmonyILManipulator]
		[HarmonyPatch(typeof(Projectile), "UpdateEnemyBulletSpeedMultiplier")]
		public static void UpdateEnemyBulletSpeedMultiplierPatch(ILContext ctx)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(ctx);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCall<GameManager>(x, "get_Instance"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<GameManager>(x, "COOP_ENEMY_PROJECTILE_SPEED_MULTIPLIER")
			}))
			{
				val.EmitDelegate<Func<float, float>>((Func<float, float>)((float orig) => EnemyProjectileSpeed));
			}
		}
	}

	public const string GUID = "kleirof.etg.jollycoop";

	public const string NAME = "Jolly Coop";

	public const string VERSION = "1.1.0";

	public const string TEXT_COLOR = "#00CED1";

	private static bool m_JollyCoopIsOn = true;

	private static bool m_ChestItemDoubled = true;

	private static bool m_RoomItemDropInc = true;

	private static bool m_MasterDoubled = true;

	private static bool m_RainbowDoubled = true;

	private const string m_onStr = "<color=#7FFFD4>on</color>";

	private const string m_offStr = "<color=#DAA520>off</color>";

	private const string m_nameStr = "<color=#00CED1>Jolly Coop</color>";

	private string[] m_EnemyAttrStr = new string[4] { "<color=#8B4513>normal</color>", "<color=#6495ED>medium</color>", "<color=#3CB371>hard</color>", "<color=#FF0000>brutal</color>" };

	private static int EnemyAttr = 1;

	private static float EnemyHealth => EnemyAttr switch
	{
		0 => 1.4f, 
		1 => 1.6f, 
		2 => 1.8f, 
		3 => 2f, 
		_ => 1.4f, 
	};

	private static float EnemyProjectileSpeed => EnemyAttr switch
	{
		0 => 0.95f, 
		1 => 0.975f, 
		2 => 1f, 
		3 => 1f, 
		_ => 0.95f, 
	};

	private void ListStatus()
	{
		ETGModConsole.Log((object)("   ChestItemDoubled " + (m_ChestItemDoubled ? "<color=#7FFFD4>on</color>" : "<color=#DAA520>off</color>")), false);
		ETGModConsole.Log((object)("   RoomItemDropInc " + (m_RoomItemDropInc ? "<color=#7FFFD4>on</color>" : "<color=#DAA520>off</color>")), false);
		ETGModConsole.Log((object)("   MasterDoubled " + (m_MasterDoubled ? "<color=#7FFFD4>on</color>" : "<color=#DAA520>off</color>")), false);
		ETGModConsole.Log((object)("   RainbowDoubled " + (m_RainbowDoubled ? "<color=#7FFFD4>on</color>" : "<color=#DAA520>off</color>")), false);
		ETGModConsole.Log((object)("   EnhancedEnemyAttr " + m_EnemyAttrStr[EnemyAttr]), false);
		ETGModConsole.Log((object)("enemy health multiplies " + EnemyHealth + ((EnemyAttr == 0) ? " (originally)" : " (1.4 originally)")), false);
		ETGModConsole.Log((object)("enemy projectile speed multiplies " + EnemyProjectileSpeed + ((EnemyAttr == 0) ? " (originally)" : " (0.95 originally)")), false);
	}

	public void Start()
	{
		ETGModMainBehaviour.WaitForGameManagerStart((Action<GameManager>)GMStart);
	}

	private void ShowMessage(string opt, string cmd, string stat)
	{
		ETGModConsole.Log((object)("<color=#00CED1>Jolly Coop</color>" + ((opt != null) ? (": " + opt) : "") + " is " + stat + ". Type 'jollycoop" + ((cmd != null) ? (" " + cmd) : "") + "' to switch."), false);
	}

	private void RequestRejected()
	{
		ETGModConsole.Log((object)"Request rejected. <color=#00CED1>Jolly Coop</color> is now <color=#DAA520>off</color>. Type 'jollycoop' to switch.", false);
	}

	private void SwitchJollyCoop(string[] args)
	{
		if (m_JollyCoopIsOn)
		{
			m_ChestItemDoubled = false;
			m_RoomItemDropInc = false;
			m_MasterDoubled = false;
			m_RainbowDoubled = false;
			EnemyAttr = 0;
			ShowMessage(null, null, "<color=#DAA520>off</color>");
		}
		else
		{
			m_ChestItemDoubled = true;
			m_RoomItemDropInc = true;
			m_MasterDoubled = true;
			m_RainbowDoubled = true;
			EnemyAttr = 1;
			ShowMessage(null, null, "<color=#7FFFD4>on</color>");
		}
		m_JollyCoopIsOn = !m_JollyCoopIsOn;
		ListStatus();
	}

	private void SwitchChestItemDoubled(string[] args)
	{
		if (!m_JollyCoopIsOn)
		{
			RequestRejected();
			return;
		}
		ShowMessage("ChestItemDoubled", "chestitemdoubled", m_ChestItemDoubled ? "<color=#DAA520>off</color>" : "<color=#7FFFD4>on</color>");
		m_ChestItemDoubled = !m_ChestItemDoubled;
		ListStatus();
	}

	private void SwitchRoomItemDropInc(string[] args)
	{
		if (!m_JollyCoopIsOn)
		{
			RequestRejected();
			return;
		}
		ShowMessage("RoomItemDropInc", "roomitemdropinc", m_RoomItemDropInc ? "<color=#DAA520>off</color>" : "<color=#7FFFD4>on</color>");
		m_RoomItemDropInc = !m_RoomItemDropInc;
		ListStatus();
	}

	private void SwitchMasterDoubled(string[] args)
	{
		if (!m_JollyCoopIsOn)
		{
			RequestRejected();
			return;
		}
		ShowMessage("MasterDoubled", "masterdoubled", m_MasterDoubled ? "<color=#DAA520>off</color>" : "<color=#7FFFD4>on</color>");
		m_MasterDoubled = !m_MasterDoubled;
		ListStatus();
	}

	private void SwitchRainbowDoubled(string[] args)
	{
		if (!m_JollyCoopIsOn)
		{
			RequestRejected();
			return;
		}
		ShowMessage("RainbowDoubled", "rainbowdoubled", m_RainbowDoubled ? "<color=#DAA520>off</color>" : "<color=#7FFFD4>on</color>");
		m_RainbowDoubled = !m_RainbowDoubled;
		ListStatus();
	}

	private void SwitchEnhancedEnemyAttr(string[] args)
	{
		if (!m_JollyCoopIsOn)
		{
			RequestRejected();
			return;
		}
		EnemyAttr = (EnemyAttr + 1) % 4;
		ETGModConsole.Log((object)("EnhancedEnemyAttr switched to " + m_EnemyAttrStr[EnemyAttr]), false);
		ListStatus();
	}

	public static void Log(string text, string color = "FFFFFF")
	{
		ETGModConsole.Log((object)("<color=" + color + ">" + text + "</color>"), false);
	}

	public void GMStart(GameManager g)
	{
		Log("Jolly Coop v1.1.0 started successfully.", "#00CED1");
		Harmony.CreateAndPatchAll(typeof(JollyCoopPatches), (string)null);
		ShowMessage(null, null, "<color=#7FFFD4>on</color>");
		ETGModConsole.Log((object)"<color=#FFFACD>Enter 'jollycoop help' for more options.</color>", false);
		ListStatus();
		ETGModConsole.Commands.AddGroup("jollycoop", (Action<string[]>)SwitchJollyCoop);
		ETGModConsole.Commands.GetGroup("jollycoop").AddUnit("help", (Action<string[]>)delegate
		{
			ETGModConsole.Log((object)"<color=#FFDEAD>jollycoop</color> - switch Jolly Coop mode", false);
			ETGModConsole.Log((object)"<color=#FFDEAD>jollycoop status</color> - show the status of jollycoop", false);
			ETGModConsole.Log((object)"<color=#FFDEAD>jollycoop chestitemdoubled</color> - switch the mode that chests drop double items", false);
			ETGModConsole.Log((object)"<color=#FFDEAD>jollycoop roomitemdropinc</color> - switch the mode that room clear items drop increase by 50%", false);
			ETGModConsole.Log((object)"<color=#FFDEAD>jollycoop masterdoubled</color> - switch the mode that boss's master bullet doubled", false);
			ETGModConsole.Log((object)"<color=#FFDEAD>jollycoop rainbowdoubled</color> - switch the mode that rainbow chest doubled in the rainbow run", false);
			ETGModConsole.Log((object)"<color=#FFDEAD>jollycoop enhancedenemyattr</color> - switch the mode that multiplies enemy health and enemy projectile speed", false);
			ETGModConsole.Log((object)("                              " + m_EnemyAttrStr[0] + ": enemy health x1.4, enemy projectile speed x0.95(originally in game)"), false);
			ETGModConsole.Log((object)("                              " + m_EnemyAttrStr[1] + ": enemy health x1.6, enemy projectile speed x0.975"), false);
			ETGModConsole.Log((object)("                              " + m_EnemyAttrStr[2] + "\t: enemy health x1.8, enemy projectile speed x1.0"), false);
			ETGModConsole.Log((object)("                              " + m_EnemyAttrStr[3] + ": enemy health x2.0, enemy projectile speed x1.0"), false);
		});
		ETGModConsole.Commands.GetGroup("jollycoop").AddUnit("chestitemdoubled", (Action<string[]>)SwitchChestItemDoubled);
		ETGModConsole.Commands.GetGroup("jollycoop").AddUnit("roomitemdropinc", (Action<string[]>)SwitchRoomItemDropInc);
		ETGModConsole.Commands.GetGroup("jollycoop").AddUnit("masterdoubled", (Action<string[]>)SwitchMasterDoubled);
		ETGModConsole.Commands.GetGroup("jollycoop").AddUnit("rainbowdoubled", (Action<string[]>)SwitchRainbowDoubled);
		ETGModConsole.Commands.GetGroup("jollycoop").AddUnit("enhancedenemyattr", (Action<string[]>)SwitchEnhancedEnemyAttr);
		ETGModConsole.Commands.GetGroup("jollycoop").AddUnit("status", (Action<string[]>)delegate
		{
			ListStatus();
		});
	}

	public static PlayerItem GetRandomActiveOfQualities(Random usedRandom, List<int> excludedIDs, params ItemQuality[] qualities)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Invalid comparison between Unknown and I4
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Invalid comparison between Unknown and I4
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		List<PlayerItem> list = new List<PlayerItem>();
		for (int i = 0; i < ((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects.Count; i++)
		{
			if ((Object)(object)((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i] != (Object)null && ((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i] is PlayerItem && (int)((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i].quality != -100 && (int)((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i].quality != -50 && !(((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i] is ContentTeaserItem) && Array.IndexOf(qualities, ((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i].quality) != -1 && !excludedIDs.Contains(((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i].PickupObjectId))
			{
				EncounterTrackable component = ((Component)((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i]).GetComponent<EncounterTrackable>();
				if (Object.op_Implicit((Object)(object)component) && component.PrerequisitesMet())
				{
					PickupObject obj = ((ObjectDatabase<PickupObject>)(object)PickupObjectDatabase.Instance).Objects[i];
					list.Add((PlayerItem)(object)((obj is PlayerItem) ? obj : null));
				}
			}
		}
		int num = usedRandom.Next(list.Count);
		if (num < 0 || num >= list.Count)
		{
			return null;
		}
		return list[num];
	}

	public static void AddItem(Chest c)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Invalid comparison between Unknown and I4
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Invalid comparison between Unknown and I4
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Invalid comparison between Unknown and I4
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Invalid comparison between Unknown and I4
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Invalid comparison between Unknown and I4
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Expected I4, but got Unknown
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Expected I4, but got Unknown
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Expected I4, but got Unknown
		if (!m_ChestItemDoubled || (int)GameManager.Instance.CurrentGameType != 1)
		{
			return;
		}
		int count = c.contents.Count;
		for (int i = 0; i < count; i++)
		{
			if ((int)c.contents[i].quality == 4 || (int)c.contents[i].quality == 3 || (int)c.contents[i].quality == 2 || (int)c.contents[i].quality == 1 || (int)c.contents[i].quality == 5)
			{
				if (c.contents[i] is Gun)
				{
					c.contents.Add((PickupObject)(object)PickupObjectDatabase.GetRandomGunOfQualities(new Random(), new List<int>(), (ItemQuality[])(object)new ItemQuality[1] { (ItemQuality)(int)c.contents[i].quality }));
				}
				else if (c.contents[i] is PassiveItem)
				{
					c.contents.Add((PickupObject)(object)PickupObjectDatabase.GetRandomPassiveOfQualities(new Random(), new List<int>(), (ItemQuality[])(object)new ItemQuality[1] { (ItemQuality)(int)c.contents[i].quality }));
				}
				else if (c.contents[i] is PlayerItem)
				{
					c.contents.Add((PickupObject)(object)GetRandomActiveOfQualities(new Random(), new List<int>(), (ItemQuality)(int)c.contents[i].quality));
				}
			}
			else
			{
				c.contents.Add(c.contents[i]);
			}
		}
	}

	private static IEnumerator SpawnChest(Vector3 v, RoomHandler room)
	{
		//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)
		yield return (object)new WaitForSeconds(0.45f);
		Chest c = Chest.Spawn(GameManager.Instance.RewardManager.A_Chest, v, room, true);
		c.IsRainbowChest = true;
		c.BecomeRainbowChest();
	}
}