Decompiled source of RiskOfRoutes v1.1.0

RiskOfRoutes.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CleanestHud;
using CleanestHud.HudChanges;
using EntityStates.FalseSonBoss;
using HG;
using HG.Reflection;
using IL.RoR2;
using LeTai.Asset.TranslucentImage;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.EntityStates.FalseSonBoss;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RiskOfRoutes;
using RiskOfRoutes.Helpers;
using RiskOfRoutes.Items;
using RiskOfRoutes.ModSupport;
using RiskOfRoutes.StageModifiers;
using RiskOfRoutes.StageModifiers.CombatModifiers;
using RiskOfRoutes.StageModifiers.OtherModifiers;
using RiskOfRoutes.StageModifiers.SceneModifiers;
using RiskOfRoutes.UI;
using RoR2;
using RoR2.Artifacts;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.ExpansionManagement;
using RoR2.Navigation;
using RoR2.UI;
using SamplePlugin;
using SamplePlugin.StageModifiers;
using SamplePlugin.StageModifiers.BossRewardModifiers;
using SamplePlugin.StageModifiers.CombatModifiers;
using SamplePlugin.StageModifiers.OtherModifiers;
using SamplePlugin.StageModifiers.SceneModifiers;
using TMPro;
using Unity;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityHotReloadNS;

[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyInformationalVersion("1.0.0+185ee28e17662a4dc1d154a632ce73e7013649b2")]
[assembly: AssemblyProduct("RiskOfRoutes")]
[assembly: AssemblyTitle("RiskOfRoutes")]
[assembly: AssemblyCompany("RiskOfRoutes")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class RouteMap
{
	public class RouteNode
	{
		public RoutePortalType portalType;

		public int x;

		public int y;

		public bool visited;

		public bool shopVisited;

		public bool goldshoresVisited;

		public bool voidFieldsVisited;

		public RouteNode left;

		public RouteNode front;

		public RouteNode right;

		public RouteNode portalNode;

		public RouteNode(int x, int y)
		{
			portalType = RoutePortalType.None;
			this.x = x;
			this.y = y;
		}

		public List<RouteNode> GetPaths(bool usePortalNode = false)
		{
			List<RouteNode> list = new List<RouteNode>();
			if (left != null)
			{
				list.Add(left);
			}
			if (front != null)
			{
				list.Add(front);
			}
			if (right != null)
			{
				list.Add(right);
			}
			if (portalNode != null && usePortalNode)
			{
				list.Add(portalNode);
			}
			return list;
		}

		public override string ToString()
		{
			return $"Node:{x}.{y} with {GetPaths().Count} paths";
		}
	}

	public int width;

	public int height;

	public int startingRoutes = 3;

	public bool isMoonVisited = false;

	public RouteNode[,] mapGrid;

	public RouteNode root;

	public bool isDirty = false;

	public RouteMap(Xoroshiro128Plus rng)
	{
		width = global::RiskOfRoutes.RiskOfRoutes.routeMapWidth.Value;
		height = 5;
		mapGrid = new RouteNode[width + 1, height];
		mapGrid[0, 0] = new RouteNode(0, 0);
		root = mapGrid[0, 0];
		root.visited = true;
		root.portalType = RoutePortalType.Starting;
		int num = 100;
		bool flag = false;
		List<RouteNode> list = new List<RouteNode>();
		while (num > 0 && !flag)
		{
			num--;
			for (int i = 0; i < width; i++)
			{
				for (int j = 1; j < height; j++)
				{
					mapGrid[i, j] = new RouteNode(i, j);
				}
			}
			int num2 = 0;
			list = SetupPaths(rng);
			for (int k = 0; k < width; k++)
			{
				for (int l = 1; l < height; l++)
				{
					RouteNode routeNode = mapGrid[k, l];
					if (routeNode == null)
					{
						Log.Error("this should happern");
					}
					int count = routeNode.GetPaths().Count;
					if (count > 1)
					{
						num2++;
					}
				}
			}
			Log.Info($"Good oens count:{num2}");
			flag = num2 > 2;
			if (!flag)
			{
				Log.Info("Trying to create map with more choices");
			}
		}
		list.Sort((RouteNode a, RouteNode b) => a.x.CompareTo(b.x));
		if (list.Count >= 1)
		{
			root.left = list[0];
		}
		if (list.Count >= 2)
		{
			root.front = list[1];
		}
		if (list.Count >= 3)
		{
			root.right = list[2];
		}
		SetupRewards(rng);
		isDirty = true;
	}

	public void SetupRewards(Xoroshiro128Plus rng)
	{
		WeightedSelection<RoutePortalType> val = new WeightedSelection<RoutePortalType>(8);
		val.AddChoice(RoutePortalType.Heal, 1f);
		val.AddChoice(RoutePortalType.Combat, 1f);
		val.AddChoice(RoutePortalType.Utility, 1f);
		val.AddChoice(RoutePortalType.DroneType, 1f);
		WeightedSelection<RoutePortalType> val2 = new WeightedSelection<RoutePortalType>(8);
		val2.AddChoice(RoutePortalType.Heal, 1f);
		val2.AddChoice(RoutePortalType.Combat, 1f);
		val2.AddChoice(RoutePortalType.Utility, 1f);
		val2.AddChoice(RoutePortalType.DroneType, 1f);
		val2.AddChoice(RoutePortalType.ChefType, 0.8f);
		val2.AddChoice(RoutePortalType.Rare, 0.8f);
		for (int i = 0; i < width; i++)
		{
			if (mapGrid[i, 1].portalType != RoutePortalType.None)
			{
				mapGrid[i, 1].portalType = val.Evaluate(rng.nextNormalizedFloat);
			}
			if (mapGrid[i, 3].portalType != RoutePortalType.None)
			{
				mapGrid[i, 3].portalType = val2.Evaluate(rng.nextNormalizedFloat);
			}
			if (mapGrid[i, 2].portalType != RoutePortalType.None)
			{
				mapGrid[i, 2].portalType = val2.Evaluate(rng.nextNormalizedFloat);
			}
			if (mapGrid[i, 4].portalType != RoutePortalType.None)
			{
				mapGrid[i, 4].portalType = RoutePortalType.ChefType;
			}
		}
		HashSet<Vector2> memory = new HashSet<Vector2>();
		List<RouteNode> paths = root.GetPaths();
		CheckNodeCorrect(root, rng, memory);
		foreach (RouteNode item in paths)
		{
			CheckNodeCorrect(item, rng, memory);
		}
	}

	public RouteNode GetRandomNodeOnFloor(int floor, Xoroshiro128Plus rng)
	{
		List<RouteNode> list = new List<RouteNode>();
		for (int i = 0; i < width; i++)
		{
			RouteNode routeNode = mapGrid[i, floor];
			if (routeNode != null && routeNode.portalType != RoutePortalType.None)
			{
				list.Add(routeNode);
			}
		}
		return rng.NextElementUniform<RouteNode>(list);
	}

	private void CheckNodeCorrect(RouteNode node, Xoroshiro128Plus rng, HashSet<Vector2> memory)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		Vector2 item = default(Vector2);
		((Vector2)(ref item))..ctor((float)node.x, (float)node.y);
		if (memory.Contains(item))
		{
			return;
		}
		memory.Add(item);
		RoutePortalType routePortalType = RoutePortalType.None;
		List<RouteNode> paths = node.GetPaths();
		if (paths.Count == 0)
		{
			return;
		}
		routePortalType = node.portalType;
		foreach (RouteNode item2 in paths)
		{
			if (item2.portalType == node.portalType)
			{
				item2.portalType = RollPortalType(rng, node.portalType);
			}
		}
		if (paths.Count > 1)
		{
			if (paths.Count == 2)
			{
				if (paths[0].portalType == paths[1].portalType)
				{
					paths[1].portalType = RollPortalType(rng, paths[0].portalType, routePortalType);
				}
			}
			else if (paths.Count == 3)
			{
				if (paths[0].portalType == paths[1].portalType)
				{
					paths[1].portalType = RollPortalType(rng, paths[0].portalType, routePortalType);
				}
				if (paths[2].portalType == paths[0].portalType || paths[2].portalType == paths[1].portalType)
				{
					paths[2].portalType = RollPortalType(rng, paths[0].portalType, paths[1].portalType, routePortalType);
				}
			}
		}
		foreach (RouteNode item3 in paths)
		{
			CheckNodeCorrect(item3, rng, memory);
		}
	}

	private RoutePortalType RollPortalType(Xoroshiro128Plus rng, params RoutePortalType[] skipTypes)
	{
		WeightedSelection<RoutePortalType> val = new WeightedSelection<RoutePortalType>(8);
		RoutePortalType[] array = new RoutePortalType[6]
		{
			RoutePortalType.Combat,
			RoutePortalType.Heal,
			RoutePortalType.Utility,
			RoutePortalType.DroneType,
			RoutePortalType.Rare,
			RoutePortalType.ChefType
		};
		RoutePortalType[] array2 = array;
		foreach (RoutePortalType routePortalType in array2)
		{
			if (!skipTypes.Contains(routePortalType))
			{
				if (routePortalType == RoutePortalType.Rare || routePortalType == RoutePortalType.ChefType)
				{
					val.AddChoice(routePortalType, 0.8f);
				}
				else
				{
					val.AddChoice(routePortalType, 1f);
				}
			}
		}
		return val.Evaluate(rng.nextNormalizedFloat);
	}

	public List<RouteNode> SetupPaths(Xoroshiro128Plus rng)
	{
		List<RouteNode> list = new List<RouteNode>();
		List<int> list2 = new List<int>();
		for (int i = 0; i < width; i++)
		{
			list2.Add(i);
		}
		for (int j = 0; j < startingRoutes; j++)
		{
			if (list2.Count == 0)
			{
				break;
			}
			int num = rng.NextElementUniform<int>(list2);
			list2.Remove(num);
			RouteNode routeNode = mapGrid[num, 1];
			if (routeNode != null)
			{
				routeNode.portalType = RoutePortalType.Rare;
				CreateRoute(routeNode, routeNode.x, routeNode.y, rng);
				list.Add(routeNode);
			}
		}
		return list;
	}

	public void CreateRoute(RouteNode curr, int x, int y, Xoroshiro128Plus rng)
	{
		if (y >= height - 1)
		{
			return;
		}
		List<RouteNode> list = new List<RouteNode>();
		for (int i = 0; i < 3; i++)
		{
			int num = x - 1 + i;
			int num2 = y + 1;
			if (num >= 0 && num <= width - 1 && (i != 0 || mapGrid[num, y].right == null) && (i != 2 || mapGrid[num, y].left == null))
			{
				list.Add(mapGrid[x - 1 + i, y + 1]);
			}
		}
		if (list.Count != 0)
		{
			RouteNode routeNode = rng.NextElementUniform<RouteNode>(list);
			if (list.Count > 1 && rng.nextNormalizedFloat < 0.2f)
			{
				list.Remove(routeNode);
				RouteNode routeNode2 = rng.NextElementUniform<RouteNode>(list);
				routeNode2.portalType = RoutePortalType.Rare;
				Connect(curr, routeNode2);
				CreateRoute(routeNode2, routeNode2.x, routeNode2.y, rng);
			}
			routeNode.portalType = RoutePortalType.Rare;
			Connect(curr, routeNode);
			CreateRoute(routeNode, routeNode.x, routeNode.y, rng);
		}
	}

	public RouteNode CreateColossusNode(RouteNode current, bool currentLayer = false)
	{
		if (current.y == height - 1 || current.y > 3)
		{
			return null;
		}
		int num = (currentLayer ? current.y : (current.y + 1));
		Log.Info("Creating colossus node");
		isDirty = true;
		RouteNode routeNode = null;
		for (int i = 0; i < width + 1; i++)
		{
			if (mapGrid[i, num] != null && (mapGrid[i, num].portalType == RoutePortalType.Colossus || mapGrid[i, num].portalType == RoutePortalType.FalseSon))
			{
				routeNode = mapGrid[i, num];
				Log.Info("Floor already has colossus node");
				return routeNode;
			}
		}
		Log.Info("Has no colossus nodes");
		for (int j = 0; j < width; j++)
		{
			int[] array = new int[2]
			{
				current.x + j,
				current.x - j
			};
			int[] array2 = array;
			foreach (int num2 in array2)
			{
				if (num2 >= 0 && num2 < width && mapGrid[num2, num].portalType == RoutePortalType.None)
				{
					routeNode = mapGrid[num2, num];
					break;
				}
			}
			if (routeNode != null)
			{
				break;
			}
		}
		if (routeNode == null)
		{
			Log.Warning("No place for colossus node, placing on extra");
			mapGrid[width, num] = new RouteNode(width, num);
			routeNode = mapGrid[width, num];
		}
		if (routeNode != null)
		{
			routeNode.portalType = ((num != 3) ? RoutePortalType.Colossus : RoutePortalType.FalseSon);
			current.portalNode = routeNode;
			if (routeNode.portalType == RoutePortalType.FalseSon)
			{
				ConnectToRandomNode(routeNode, thisLayer: true);
			}
			else
			{
				ConnectToRandomNode(routeNode);
			}
			return routeNode;
		}
		Log.Error("Still null");
		return null;
	}

	public RouteNode CreateHardwareNode(RouteNode current)
	{
		int num = current.y + 1;
		Log.Info("Creating hardware node");
		isDirty = true;
		RouteNode routeNode = null;
		for (int i = 0; i < width + 1; i++)
		{
			if (mapGrid[i, num] != null && (mapGrid[i, num].portalType == RoutePortalType.Hardware || mapGrid[i, num].portalType == RoutePortalType.SolusWing))
			{
				routeNode = mapGrid[i, num];
				Log.Info("Floor already has hardware node");
				return routeNode;
			}
		}
		Log.Info("Has no hardware nodes");
		for (int j = 0; j < width; j++)
		{
			int[] array = new int[2]
			{
				current.x + j,
				current.x - j
			};
			int[] array2 = array;
			foreach (int num2 in array2)
			{
				if (num2 >= 0 && num2 < width && mapGrid[num2, num].portalType == RoutePortalType.None)
				{
					routeNode = mapGrid[num2, num];
					break;
				}
			}
			if (routeNode != null)
			{
				break;
			}
		}
		if (routeNode == null)
		{
			Log.Warning("No place for hardware node, placing on extra");
			mapGrid[width, num] = new RouteNode(width, num);
			routeNode = mapGrid[width, num];
		}
		if (routeNode != null)
		{
			routeNode.portalType = ((num != 4) ? RoutePortalType.Hardware : RoutePortalType.SolusWing);
			current.portalNode = routeNode;
			return routeNode;
		}
		Log.Error("Still null");
		return null;
	}

	private void ConnectToRandomNode(RouteNode node, bool thisLayer = false)
	{
		int y = node.y;
		int num = (thisLayer ? y : (y + 1));
		List<RouteNode> list = new List<RouteNode>();
		for (int i = 0; i < width; i++)
		{
			RouteNode routeNode = mapGrid[i, num];
			if (routeNode != null && routeNode.portalType != RoutePortalType.None && routeNode != node)
			{
				list.Add(routeNode);
			}
		}
		if (list.Count > 0)
		{
			node.front = Run.instance.stageRng.NextElementUniform<RouteNode>(list);
		}
		else
		{
			Log.Warning("ConnectToRandomNode: No valid target nodes to connect");
		}
	}

	private void Connect(RouteNode curr, RouteNode next)
	{
		if (curr.x - next.x == -1)
		{
			curr.right = next;
		}
		else if (curr.x - next.x == 0)
		{
			curr.front = next;
		}
		else
		{
			curr.left = next;
		}
	}

	public RouteNode GetStartingNode()
	{
		return mapGrid[0, 0];
	}
}
public enum RoutePortalType
{
	None,
	Rare,
	ItemType,
	DroneType,
	ChefType,
	Colossus,
	Hardware,
	SolusWing,
	Goldshores,
	Shop,
	Arena,
	FalseSon,
	Starting,
	Combat,
	Heal,
	Utility,
	MoonTeleporter
}
public enum ModifierTier
{
	None,
	Tier1,
	Tier2,
	Tier3
}
public enum ModifierRarity
{
	Common,
	Rare
}
namespace SamplePlugin
{
	[Serializable]
	public struct ModifierSync : IEquatable<ModifierSync>
	{
		public string name;

		public int stack;

		public bool isArtifact;

		public ModifierSync(ModifierDef mod)
		{
			name = mod.name;
			stack = 1;
			isArtifact = mod.isArtifact;
		}

		public ModifierSync(ModifierDef mod, int stack)
		{
			name = mod.name;
			this.stack = stack;
			isArtifact = mod.isArtifact;
		}

		public bool Equals(ModifierSync other)
		{
			return name == other.name;
		}
	}
	[Serializable]
	public struct RouteNodeSync : IEquatable<RouteNodeSync>
	{
		public RoutePortalType portalType;

		public int x;

		public int y;

		public int frontX;

		public int frontY;

		public int leftX;

		public int leftY;

		public int rightX;

		public int rightY;

		public int bonusX;

		public int bonusY;

		public bool visited;

		public bool shopVisited;

		public bool goldshoresVisited;

		public bool voidFieldsVisited;

		public RouteNodeSync(RouteMap.RouteNode node)
		{
			x = -1;
			y = -1;
			frontX = -1;
			frontY = -1;
			leftX = -1;
			leftY = -1;
			rightX = -1;
			rightY = -1;
			bonusX = -1;
			bonusY = -1;
			x = node.x;
			y = node.y;
			visited = node.visited;
			portalType = node.portalType;
			RouteMap.RouteNode front = node.front;
			if (front != null)
			{
				frontX = front.x;
				frontY = front.y;
			}
			RouteMap.RouteNode left = node.left;
			if (left != null)
			{
				leftX = left.x;
				leftY = left.y;
			}
			RouteMap.RouteNode right = node.right;
			if (node.right != null)
			{
				rightX = right.x;
				rightY = right.y;
			}
			if (node.portalNode != null)
			{
				bonusX = node.portalNode.x;
				bonusY = node.portalNode.y;
			}
			shopVisited = node.shopVisited;
			goldshoresVisited = node.goldshoresVisited;
			voidFieldsVisited = node.voidFieldsVisited;
		}

		public bool Equals(RouteNodeSync other)
		{
			return x == other.x && y == other.y && visited == other.visited && portalType == other.portalType && frontX == other.frontX && frontY == other.frontY && leftX == other.leftX && leftY == other.leftY && rightX == other.rightX && rightY == other.rightY && bonusX == other.bonusX && bonusY == other.bonusY;
		}
	}
	public class SyncListModifier : SyncListStruct<ModifierSync>
	{
		public override void SerializeItem(NetworkWriter writer, ModifierSync item)
		{
			writer.Write(item.name);
			writer.WritePackedUInt32((uint)item.stack);
			writer.Write(item.isArtifact);
		}

		public override ModifierSync DeserializeItem(NetworkReader reader)
		{
			return new ModifierSync
			{
				name = reader.ReadString(),
				stack = (int)reader.ReadPackedUInt32(),
				isArtifact = reader.ReadBoolean()
			};
		}
	}
	public class SyncListRouteNode : SyncListStruct<RouteNodeSync>
	{
		public override void SerializeItem(NetworkWriter writer, RouteNodeSync item)
		{
			writer.Write((int)item.portalType);
			writer.WritePackedUInt32((uint)item.x);
			writer.WritePackedUInt32((uint)item.y);
			writer.WritePackedUInt32((uint)item.frontX);
			writer.WritePackedUInt32((uint)item.frontY);
			writer.WritePackedUInt32((uint)item.leftX);
			writer.WritePackedUInt32((uint)item.leftY);
			writer.WritePackedUInt32((uint)item.rightX);
			writer.WritePackedUInt32((uint)item.rightY);
			writer.WritePackedUInt32((uint)item.bonusX);
			writer.WritePackedUInt32((uint)item.bonusY);
			writer.Write(item.visited);
			writer.Write(item.shopVisited);
			writer.Write(item.goldshoresVisited);
			writer.Write(item.voidFieldsVisited);
		}

		public override RouteNodeSync DeserializeItem(NetworkReader reader)
		{
			return new RouteNodeSync
			{
				portalType = (RoutePortalType)reader.ReadInt32(),
				x = (int)reader.ReadPackedUInt32(),
				y = (int)reader.ReadPackedUInt32(),
				frontX = (int)reader.ReadPackedUInt32(),
				frontY = (int)reader.ReadPackedUInt32(),
				leftX = (int)reader.ReadPackedUInt32(),
				leftY = (int)reader.ReadPackedUInt32(),
				rightX = (int)reader.ReadPackedUInt32(),
				rightY = (int)reader.ReadPackedUInt32(),
				bonusX = (int)reader.ReadPackedUInt32(),
				bonusY = (int)reader.ReadPackedUInt32(),
				visited = reader.ReadBoolean(),
				shopVisited = reader.ReadBoolean(),
				goldshoresVisited = reader.ReadBoolean(),
				voidFieldsVisited = reader.ReadBoolean()
			};
		}
	}
	public class ModifierSlotConfiguration
	{
		public Dictionary<ModifierTier, int> positive = new Dictionary<ModifierTier, int>();

		public Dictionary<ModifierTier, int> negative = new Dictionary<ModifierTier, int>();
	}
	public class StageModifierDirector : NetworkBehaviour
	{
		public static StageModifierDirector instance;

		public static List<GameObject> activePortalInstances;

		public List<string> runArtifactsApplied;

		public SyncListModifier modifiersSynced = new SyncListModifier();

		public List<RouteNodeSync> routeNodesSynced = new List<RouteNodeSync>();

		public int mapState = 0;

		public float stageEnterTime = 0f;

		[SyncVar]
		public int mapWidth;

		[SyncVar]
		public int mapHeight;

		[SyncVar]
		public bool isMoonVisited;

		[SyncVar]
		public Vector2 currentNodeSync = new Vector2(-1f, -1f);

		public Inventory monsterTeamInventory;

		public RouteMap routeMap;

		public RouteMap.RouteNode currentNode;

		[SyncVar(hook = "OnBaseCurseSyncedUpdate")]
		public float syncedBaseCurse = 0f;

		[SyncVar]
		public int cursePerStack = 0;

		public int punishCommandStack = 0;

		[SyncVar]
		public float punishmentTime = -1f;

		[SyncVar]
		public bool purifyLunarItemModifier;

		[SyncVar]
		public int doppelStackTime = 30;

		[SyncVar]
		public bool modifiersCanBeBanned = true;

		[SyncVar]
		public int commonDefaultStack = 5;

		[SyncVar]
		public int uncommonDefaultStack = 3;

		[SyncVar]
		public int legendaryDefaultStack = 1;

		[SyncVar]
		public int bossDefaultStack = 1;

		[SyncVar]
		public int commonExtraRange = 3;

		[SyncVar]
		public int uncommonExtraRange = 2;

		[SyncVar]
		public int legendaryExtraRange = 1;

		[SyncVar]
		public int bossExtraRange = 1;

		[SyncVar]
		public int chanceForExtra = 0;

		private static int kListmodifiersSynced;

		private static int kRpcRpcReceiveFullMap;

		public List<StageModifier> activeModifiers { get; set; }

		public List<ModifierSync> reservedModifiers { get; set; }

		public HashSet<string> bannedModifiersRun { get; set; }

		public HashSet<string> bannedModifiersStage { get; set; }

		public int NetworkmapWidth
		{
			get
			{
				return mapWidth;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref mapWidth, 2u);
			}
		}

		public int NetworkmapHeight
		{
			get
			{
				return mapHeight;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref mapHeight, 4u);
			}
		}

		public bool NetworkisMoonVisited
		{
			get
			{
				return isMoonVisited;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<bool>(value, ref isMoonVisited, 8u);
			}
		}

		public Vector2 NetworkcurrentNodeSync
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return currentNodeSync;
			}
			[param: In]
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				((NetworkBehaviour)this).SetSyncVar<Vector2>(value, ref currentNodeSync, 16u);
			}
		}

		public float NetworksyncedBaseCurse
		{
			get
			{
				return syncedBaseCurse;
			}
			[param: In]
			set
			{
				ref float reference = ref syncedBaseCurse;
				if (NetworkServer.localClientActive && !((NetworkBehaviour)this).syncVarHookGuard)
				{
					((NetworkBehaviour)this).syncVarHookGuard = true;
					OnBaseCurseSyncedUpdate(value);
					((NetworkBehaviour)this).syncVarHookGuard = false;
				}
				((NetworkBehaviour)this).SetSyncVar<float>(value, ref reference, 32u);
			}
		}

		public int NetworkcursePerStack
		{
			get
			{
				return cursePerStack;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref cursePerStack, 64u);
			}
		}

		public float NetworkpunishmentTime
		{
			get
			{
				return punishmentTime;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<float>(value, ref punishmentTime, 128u);
			}
		}

		public bool NetworkpurifyLunarItemModifier
		{
			get
			{
				return purifyLunarItemModifier;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<bool>(value, ref purifyLunarItemModifier, 256u);
			}
		}

		public int NetworkdoppelStackTime
		{
			get
			{
				return doppelStackTime;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref doppelStackTime, 512u);
			}
		}

		public bool NetworkmodifiersCanBeBanned
		{
			get
			{
				return modifiersCanBeBanned;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<bool>(value, ref modifiersCanBeBanned, 1024u);
			}
		}

		public int NetworkcommonDefaultStack
		{
			get
			{
				return commonDefaultStack;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref commonDefaultStack, 2048u);
			}
		}

		public int NetworkuncommonDefaultStack
		{
			get
			{
				return uncommonDefaultStack;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref uncommonDefaultStack, 4096u);
			}
		}

		public int NetworklegendaryDefaultStack
		{
			get
			{
				return legendaryDefaultStack;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref legendaryDefaultStack, 8192u);
			}
		}

		public int NetworkbossDefaultStack
		{
			get
			{
				return bossDefaultStack;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref bossDefaultStack, 16384u);
			}
		}

		public int NetworkcommonExtraRange
		{
			get
			{
				return commonExtraRange;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref commonExtraRange, 32768u);
			}
		}

		public int NetworkuncommonExtraRange
		{
			get
			{
				return uncommonExtraRange;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref uncommonExtraRange, 65536u);
			}
		}

		public int NetworklegendaryExtraRange
		{
			get
			{
				return legendaryExtraRange;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref legendaryExtraRange, 131072u);
			}
		}

		public int NetworkbossExtraRange
		{
			get
			{
				return bossExtraRange;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref bossExtraRange, 262144u);
			}
		}

		public int NetworkchanceForExtra
		{
			get
			{
				return chanceForExtra;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref chanceForExtra, 524288u);
			}
		}

		public void Awake()
		{
			instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			activeModifiers = new List<StageModifier>();
			reservedModifiers = new List<ModifierSync>();
			bannedModifiersRun = new HashSet<string>();
			bannedModifiersStage = new HashSet<string>();
			activePortalInstances = new List<GameObject>();
			Log.Info("Awake: StageModifierDirector created");
			if (NetworkServer.active)
			{
				Run.onRunStartGlobal += Run_onRunStartGlobal;
				Run.onRunDestroyGlobal += Run_onRunDestroyGlobal;
				SceneDirector.onPrePopulateSceneServer += SceneDirector_onPrePopulateSceneServer;
				Stage.onServerStageComplete += Stage_onServerStageComplete;
			}
			((SyncList<ModifierSync>)(object)modifiersSynced).InitializeBehaviour((NetworkBehaviour)(object)this, kListmodifiersSynced);
		}

		public void OnDestroy()
		{
			Run.onRunDestroyGlobal -= Run_onRunDestroyGlobal;
			Run.onRunStartGlobal -= Run_onRunStartGlobal;
			SceneDirector.onPrePopulateSceneServer -= SceneDirector_onPrePopulateSceneServer;
			Stage.onServerStageComplete -= Stage_onServerStageComplete;
		}

		public void OnConfigUpdated()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Invalid comparison between Unknown and I4
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Invalid comparison between Unknown and I4
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Invalid comparison between Unknown and I4
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Invalid comparison between Unknown and I4
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Invalid comparison between Unknown and I4
			bannedModifiersRun.Clear();
			HashSet<string> bannedPrinterItems = global::RiskOfRoutes.RiskOfRoutes.bannedPrinterItems;
			HashSet<string> bannedEnemyItems = global::RiskOfRoutes.RiskOfRoutes.bannedEnemyItems;
			foreach (string item in bannedEnemyItems)
			{
				bannedModifiersRun.Add(item + "_EnemyItem");
			}
			foreach (string item2 in bannedPrinterItems)
			{
				bannedModifiersRun.Add(item2 + "_Printer");
			}
			Enumerator<ItemDef> enumerator3 = ItemCatalog.allItemDefs.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					ItemDef current3 = enumerator3.Current;
					if (current3.hidden)
					{
						bannedModifiersRun.Add(((Object)current3).name + "_EnemyItem");
						bannedModifiersRun.Add(((Object)current3).name + "_Printer");
					}
					if (current3.ContainsTag((ItemTag)4) && !global::RiskOfRoutes.RiskOfRoutes.canAppearWithAIBlacklisted.Value)
					{
						bannedModifiersRun.Add(((Object)current3).name + "_EnemyItem");
					}
					if ((int)current3.tier == 4)
					{
						if (!global::RiskOfRoutes.RiskOfRoutes.enemyItemsAllowBoss.Value)
						{
							bannedModifiersRun.Add(((Object)current3).name + "_EnemyItem");
						}
					}
					else if (((int)current3.tier == 6 || (int)current3.tier == 7 || (int)current3.tier == 8) && !global::RiskOfRoutes.RiskOfRoutes.enemyItemsAllowVoid.Value)
					{
						bannedModifiersRun.Add(((Object)current3).name + "_EnemyItem");
					}
					if (((int)current3.tier != 0 && (int)current3.tier != 1) || current3.ContainsTag((ItemTag)15))
					{
						bannedModifiersRun.Add(((Object)current3).name + "_Printer");
					}
				}
			}
			finally
			{
				((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private void Run_onRunStartGlobal(Run run)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				GameObject val = Object.Instantiate<GameObject>(global::RiskOfRoutes.RiskOfRoutes.networkedInventoryPrefab);
				Object.DontDestroyOnLoad((Object)(object)val);
				monsterTeamInventory = val.GetComponent<Inventory>();
				val.GetComponent<TeamFilter>().teamIndex = (TeamIndex)2;
				NetworkServer.Spawn(val);
				CreateRunConfiguration();
				Log.Info(string.Format("{0}: Got punishmentTimeMinutes value - {1}", "Run_onRunStartGlobal", punishmentTime));
				Log.Info("Creating route map");
				routeMap = new RouteMap(run.runRNG);
				currentNode = routeMap.GetStartingNode();
				currentNode.visited = true;
				NetworkcurrentNodeSync = new Vector2((float)currentNode.x, (float)currentNode.y);
				Log.Info($"Current:{currentNode.x},{currentNode.y} that has {currentNode.GetPaths().Count} paths");
				routeMap.isDirty = true;
			}
		}

		private void Run_onRunDestroyGlobal(Run obj)
		{
			if (!NetworkServer.active)
			{
				return;
			}
			Log.Info(string.Format("{0}: Run ended, clearing {1} modifiers", "Run_onRunDestroyGlobal", activeModifiers.Count));
			foreach (StageModifier activeModifier in activeModifiers)
			{
				if (activeModifier == null)
				{
					Log.Error("Run_onRunDestroyGlobal: Some active modifier was null");
				}
				else
				{
					activeModifier.OnEnd();
				}
			}
			reservedModifiers.Clear();
			runArtifactsApplied.Clear();
			((SyncList<ModifierSync>)(object)modifiersSynced).Clear();
			routeNodesSynced.Clear();
			if (Object.op_Implicit((Object)(object)((Component)this).gameObject))
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				Log.Info("Run_onRunDestroyGlobal: StageModifierDirector destroyed");
			}
			if (Object.op_Implicit((Object)(object)monsterTeamInventory))
			{
				NetworkServer.Destroy(((Component)monsterTeamInventory).gameObject);
			}
			monsterTeamInventory = null;
		}

		private void SceneDirector_onPrePopulateSceneServer(SceneDirector obj)
		{
			Log.Info(string.Format("{0}: Stage started, applying {1} modifiers", "SceneDirector_onPrePopulateSceneServer", reservedModifiers.Count));
			if (reservedModifiers.Count == 0)
			{
				return;
			}
			activeModifiers.Clear();
			bannedModifiersStage.Clear();
			foreach (ModifierSync reservedModifier in reservedModifiers)
			{
				StageModifier stageModifier = StageModifierCatalog.StageModifierFromDef(reservedModifier.name, reservedModifier.stack);
				if (stageModifier == null)
				{
					Log.Error("SceneDirector_onPrePopulateSceneServer: Modifier with def " + reservedModifier.name + " is null");
					continue;
				}
				activeModifiers.Add(stageModifier);
				if (modifiersCanBeBanned)
				{
					bannedModifiersStage.Add(reservedModifier.name);
				}
			}
			foreach (ModifierSync reservedModifier2 in reservedModifiers)
			{
				((SyncList<ModifierSync>)(object)modifiersSynced).Add(reservedModifier2);
				if (reservedModifier2.name == "SoulCost")
				{
					NetworkcursePerStack = reservedModifier2.stack;
				}
			}
			activePortalInstances.Clear();
			reservedModifiers.Clear();
			foreach (StageModifier activeModifier in activeModifiers)
			{
				activeModifier?.OnStart();
			}
			SceneDef sceneDefForCurrentScene = SceneCatalog.GetSceneDefForCurrentScene();
			stageEnterTime = Run.instance.GetRunStopwatch();
		}

		private void Stage_onServerStageComplete(Stage obj)
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Invalid comparison between Unknown and I4
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			Log.Info($"Stage completed, clearing {activeModifiers.Count} modifiers");
			foreach (StageModifier activeModifier in activeModifiers)
			{
				if (activeModifier == null)
				{
					Log.Error("Some of the modifiers is null");
				}
				else
				{
					activeModifier.OnEnd();
				}
			}
			activeModifiers.Clear();
			((SyncList<ModifierSync>)(object)modifiersSynced).Clear();
			Log.Info($"Scene order:{Stage.instance.sceneDef.stageOrder}");
			if (Stage.instance.sceneDef.stageOrder == 5 || (currentNode.x == 0 && currentNode.y == 0 && Stage.instance.sceneDef.baseSceneName != "bazaar" && (int)Stage.instance.sceneDef.sceneType == 1))
			{
				Log.Info("Trying to create new map");
				if (Object.op_Implicit((Object)(object)TeleporterInteraction.instance) && TeleporterInteraction.instance.sceneExitController.destinationScene.baseSceneName == "moon2" && TeleporterInteraction.instance.isCharged)
				{
					routeMap.isMoonVisited = true;
				}
				else
				{
					routeMap = new RouteMap(Run.instance.runRNG);
					Log.Info("Created new map");
					currentNode = routeMap.GetStartingNode();
					NetworkcurrentNodeSync = new Vector2((float)currentNode.x, (float)currentNode.y);
					Log.Info($"Current:{currentNode.x},{currentNode.y} that has {currentNode.GetPaths().Count} paths");
					Log.Info($"Teleporter:{TeleporterInteraction.instance.sceneExitController.useRunNextStageScene}");
				}
			}
			else
			{
				Log.Info("Not creating new map yet");
				Log.Info($"\t{currentNode.x}:{currentNode.y}");
				Log.Info($"\t{Stage.instance.sceneDef.stageOrder}");
			}
			currentNode.visited = true;
			routeMap.isDirty = true;
		}

		private void CreateRunConfiguration()
		{
			NetworkcommonDefaultStack = global::RiskOfRoutes.RiskOfRoutes.commonDefaultStack.Value;
			NetworkuncommonDefaultStack = global::RiskOfRoutes.RiskOfRoutes.uncommonDefaultStack.Value;
			NetworklegendaryDefaultStack = global::RiskOfRoutes.RiskOfRoutes.legendaryDefaultStack.Value;
			NetworkbossDefaultStack = global::RiskOfRoutes.RiskOfRoutes.bossDefaultStack.Value;
			NetworkcommonExtraRange = global::RiskOfRoutes.RiskOfRoutes.commonExtraRange.Value;
			NetworkuncommonExtraRange = global::RiskOfRoutes.RiskOfRoutes.uncommonExtraRange.Value;
			NetworklegendaryExtraRange = global::RiskOfRoutes.RiskOfRoutes.legendaryExtraRange.Value;
			NetworkbossExtraRange = global::RiskOfRoutes.RiskOfRoutes.bossExtraRange.Value;
			NetworkchanceForExtra = global::RiskOfRoutes.RiskOfRoutes.chanceForExtra.Value;
			runArtifactsApplied = GetArtifactsAppliedThisRun();
			if (global::RiskOfRoutes.RiskOfRoutes.negativeStackPunishment.Value)
			{
				NetworkpunishmentTime = global::RiskOfRoutes.RiskOfRoutes.punishmentTimeMinutes.Value;
			}
			else
			{
				NetworkpunishmentTime = -1f;
			}
			NetworkpurifyLunarItemModifier = global::RiskOfRoutes.RiskOfRoutes.lunarTurnToPearl.Value;
			NetworkdoppelStackTime = global::RiskOfRoutes.RiskOfRoutes.doppelStackTime.Value;
			NetworkmodifiersCanBeBanned = global::RiskOfRoutes.RiskOfRoutes.modifiersCanBeBanned.Value;
			bannedModifiersRun.Clear();
			HashSet<string> bannedPrinterItems = global::RiskOfRoutes.RiskOfRoutes.bannedPrinterItems;
			HashSet<string> bannedEnemyItems = global::RiskOfRoutes.RiskOfRoutes.bannedEnemyItems;
			HashSet<string> bannedLunarDefs = global::RiskOfRoutes.RiskOfRoutes.bannedLunarDefs;
			HashSet<string> bannedArtifactDefs = global::RiskOfRoutes.RiskOfRoutes.bannedArtifactDefs;
			HashSet<string> bannedModifierDefs = global::RiskOfRoutes.RiskOfRoutes.bannedModifierDefs;
			foreach (string item in bannedEnemyItems)
			{
				bannedModifiersRun.Add(item + "_EnemyItem");
			}
			foreach (string item2 in bannedPrinterItems)
			{
				bannedModifiersRun.Add(item2 + "_Printer");
			}
			foreach (string item3 in bannedLunarDefs)
			{
				bannedModifiersRun.Add(item3 + "_LunarItem");
			}
			foreach (string item4 in bannedArtifactDefs)
			{
				bannedModifiersRun.Add(item4);
			}
			foreach (string bannedModifierDef in global::RiskOfRoutes.RiskOfRoutes.bannedModifierDefs)
			{
				bannedModifiersRun.Add(bannedModifierDef);
			}
			HashSet<DefInfo> moddedArtifactsInfo = global::RiskOfRoutes.RiskOfRoutes.moddedArtifactsInfo;
			HashSet<DefInfo> moddedLunarsInfo = global::RiskOfRoutes.RiskOfRoutes.moddedLunarsInfo;
			ArtifactDef[] artifactDefs = ArtifactCatalog.artifactDefs;
			foreach (ArtifactDef art in artifactDefs)
			{
				if (!StageModifierCatalog.artifactTiers.ContainsKey(art.cachedName) && !moddedArtifactsInfo.Any((DefInfo defInfo) => defInfo.name == art.cachedName))
				{
					bannedModifiersRun.Add(art.cachedName);
				}
			}
			foreach (ItemDef lunar in StageModifierCatalog.lunarRegisteredDefs)
			{
				if (!StageModifierCatalog.lunarItemTiers.ContainsKey(((Object)lunar).name) && !moddedLunarsInfo.Any((DefInfo defInfo) => defInfo.name == ((Object)lunar).name))
				{
					bannedModifiersRun.Add(((Object)lunar).name + "_LunarItem");
				}
			}
			StageModifierCatalog.CreateRunPools();
		}

		private void OnEnable()
		{
			Stage.onStageStartGlobal += OnStageStartClient;
		}

		private void OnDisable()
		{
			Stage.onStageStartGlobal -= OnStageStartClient;
		}

		private void OnStageStartClient(Stage obj)
		{
			if (!NetworkServer.active)
			{
				Log.Info("OnStageStartClient: on client");
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null);
				if (!((Object)(object)val == (Object)null))
				{
					Console.instance.SubmitCmd(val, "request_map", false);
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCRequestMap(ConCommandArgs args)
		{
			if ((Object)(object)instance != (Object)null && instance.routeMap != null)
			{
				Log.Info("CCRequestMap: requested the map");
				instance.routeMap.isDirty = true;
			}
		}

		protected virtual void FixedUpdate()
		{
			if (NetworkServer.active && routeMap != null && routeMap.isDirty)
			{
				UpdateRouteMap();
				routeMap.isDirty = false;
			}
		}

		private void UpdateRouteMap()
		{
			Log.Info("UpdateRouteMap: Updating route map");
			int width = routeMap.width;
			int height = routeMap.height;
			RouteNodeSync[] array = new RouteNodeSync[(width + 1) * height];
			for (int i = 0; i < width + 1; i++)
			{
				for (int j = 0; j < height; j++)
				{
					int num = i * height + j;
					if (routeMap.mapGrid[i, j] != null)
					{
						array[num] = new RouteNodeSync(routeMap.mapGrid[i, j]);
					}
					else
					{
						array[num] = new RouteNodeSync(new RouteMap.RouteNode(-1, -1));
					}
				}
			}
			NetworkmapWidth = width;
			NetworkmapHeight = height;
			NetworkisMoonVisited = routeMap.isMoonVisited;
			routeNodesSynced = new List<RouteNodeSync>(array);
			CallRpcReceiveFullMap(array, width, height, routeMap.isMoonVisited, stageEnterTime);
		}

		[ClientRpc]
		private void RpcReceiveFullMap(RouteNodeSync[] map, int width, int height, bool moon, float hostStageEnterTime)
		{
			NetworkmapWidth = width;
			NetworkmapHeight = height;
			NetworkisMoonVisited = moon;
			routeNodesSynced = new List<RouteNodeSync>(map);
			mapState++;
			stageEnterTime = hostStageEnterTime;
			Debug.Log((object)"RpcReceiveFullMap: Got map on client");
		}

		private void OnBaseCurseSyncedUpdate(float newValue)
		{
			NetworksyncedBaseCurse = newValue;
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				if (!((Object)(object)readOnlyInstances.playerCharacterMasterController == (Object)null) && Object.op_Implicit((Object)(object)readOnlyInstances) && Object.op_Implicit((Object)(object)readOnlyInstances.GetBody()))
				{
					readOnlyInstances.GetBody().RecalculateStats();
				}
			}
		}

		public unsafe List<string> GetArtifactsAppliedThisRun()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			RunEnabledArtifacts enumerator = RunArtifactManager.enabledArtifactsEnumerable.GetEnumerator();
			try
			{
				while (((RunEnabledArtifacts)(ref enumerator)).MoveNext())
				{
					ArtifactDef current = ((RunEnabledArtifacts)(ref enumerator)).Current;
					list.Add(current.cachedName);
					Log.Info("GetArtifactsAppliedThisRun: Added " + current.cachedName);
				}
			}
			finally
			{
				((IDisposable)(*(RunEnabledArtifacts*)(&enumerator))/*cast due to .constrained prefix*/).Dispose();
			}
			return list;
		}

		public void GetNextStageModifiers(GameObject portal)
		{
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Invalid comparison between I4 and Unknown
			RoutePortalManager component = portal.GetComponent<RoutePortalManager>();
			if ((Object)(object)component == (Object)null || component.routeNode == null)
			{
				Log.Error("GetNextStageModifiers: Portal doesn't have routePortalManager or RouteNode, couldn't get modifiers.");
				return;
			}
			if (component.isObjectiveNode)
			{
				List<string> pool = StageModifierCatalog.GetPool(RoutePortalType.MoonTeleporter);
				Log.Info("Boss modifiers pool: ");
				foreach (string item in pool)
				{
					Log.Info("\t" + item);
				}
			}
			HashSet<string> hashSet = new HashSet<string>(bannedModifiersRun);
			hashSet.UnionWith(bannedModifiersStage);
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			ModifierSlotConfiguration modifierSlots = GetModifierSlots(Run.instance.stageRng, component.routeNode.portalType, hashSet);
			if (SceneHelper.IsSceneColossus((SceneIndex)component.destinationSceneIndex, includeFalseSonScene: false) || CheckPlayersHaveFalseSonHeart() > 0)
			{
				if (!bannedModifiersRun.Contains("Aurelionite"))
				{
					dictionary.Add("Aurelionite", 1);
					Log.Info("GetNextStageModifiers: Added aurelionite modifier to colossus portal");
				}
				else
				{
					Log.Warning("Not adding aurelionite reward to collosus portal because modifier is banned");
				}
			}
			if (component.destinationSceneIndex == (int)SceneCatalog.FindSceneIndex("conduitcanyon"))
			{
				List<string> list = new List<string> { "UpgradeDrones", "DroneBossRed" };
				dictionary.Add(Run.instance.stageRng.NextElementUniform<string>(list), 1);
				Log.Info("GetNextStageModifiers: Added rare drone modifier to hardware portal");
			}
			if (component.routeNode.portalType == RoutePortalType.ChefType)
			{
				if (!bannedModifiersRun.Contains("WanderingChef"))
				{
					dictionary.Add("WanderingChef", 1);
					Log.Info("GetNextStageModifiers: Added chef modifier to route portal");
				}
				else
				{
					Log.Warning("Not adding wandering chef to chef portal because modifier is banned");
				}
			}
			if (CheckMountainShrine() && Run.instance.stageRng.nextNormalizedFloat > 0.5f && !bannedModifiersRun.Contains("Mountain"))
			{
				dictionary.Add("Mountain", TeleporterInteraction.instance.shrineBonusStacks);
			}
			if (CheckRepairAvailable() && Run.instance.stageRng.nextNormalizedFloat > 0.8f && !bannedModifiersRun.Contains("Repair"))
			{
				dictionary.Add("Repair", 1);
			}
			Dictionary<ModifierTier, int> positive = modifierSlots.positive;
			foreach (KeyValuePair<ModifierTier, int> item2 in positive)
			{
				for (int i = 0; i < item2.Value; i++)
				{
					List<string> pool2 = StageModifierCatalog.GetPool(component.routeNode.portalType);
					ModifierDef modifierDef = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, item2.Key, pool2);
					if (modifierDef == null)
					{
						continue;
					}
					int num = CalculateStack(modifierDef, item2.Key);
					if (modifierDef.name == "DamagePrinterModifier" || modifierDef.name == "HealingPrinterModifier" || modifierDef.name == "UtilityPrinterModifier" || modifierDef.name == "FoodRelatedPrinterModifier")
					{
						Log.Info("GetNextStageModifiers: got printer modifier");
						List<string> typePool = StageModifierCatalog.damageItems;
						if (modifierDef.name == "DamagePrinterModifier")
						{
							typePool = StageModifierCatalog.damageItems;
						}
						else if (modifierDef.name == "HealingPrinterModifier")
						{
							typePool = StageModifierCatalog.healingItems;
						}
						else if (modifierDef.name == "UtilityPrinterModifier")
						{
							typePool = StageModifierCatalog.utilityItems;
						}
						else if (modifierDef.name == "FoodRelatedPrinterModifier")
						{
							typePool = StageModifierCatalog.foodRelatedItems;
						}
						for (int j = 0; j < num; j++)
						{
							ModifierDef modifierDef2 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, ModifierTier.Tier1, typePool);
							if (modifierDef2 == null)
							{
								Log.Error("GetNextStageModifiers: got null printer modifier from item pool");
								break;
							}
							hashSet.Add(modifierDef2.name);
							if (modifierDef2.conflictList != null)
							{
								foreach (string conflict in modifierDef2.conflictList)
								{
									hashSet.Add(conflict);
								}
							}
							if (!dictionary.ContainsKey(modifierDef2.name))
							{
								dictionary.Add(modifierDef2.name, 1);
							}
						}
						continue;
					}
					hashSet.Add(modifierDef.name);
					if (modifierDef.conflictList != null)
					{
						foreach (string conflict2 in modifierDef.conflictList)
						{
							hashSet.Add(conflict2);
						}
					}
					if (dictionary.ContainsKey(modifierDef.name))
					{
						dictionary[modifierDef.name] += num;
					}
					else
					{
						dictionary.Add(modifierDef.name, num);
					}
				}
			}
			Dictionary<ModifierTier, int> negative = modifierSlots.negative;
			List<ModifierDef> list2 = new List<ModifierDef>();
			foreach (KeyValuePair<ModifierTier, int> item3 in negative)
			{
				for (int k = 0; k < item3.Value; k++)
				{
					List<string> pool3 = StageModifierCatalog.GetPool(component.routeNode.portalType, isNegative: true);
					ModifierDef modifierDef3 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, item3.Key, pool3);
					if (modifierDef3 == null)
					{
						continue;
					}
					int num2 = CalculateStack(modifierDef3, item3.Key);
					if (modifierDef3.name == "EnemyItemModifier")
					{
						Log.Info($"Enemy item stack: {num2}");
						List<string> pool4 = StageModifierCatalog.GetPool(component.routeNode.portalType, isNegative: true, isItemPool: true);
						modifierDef3 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, item3.Key, pool4);
						if (modifierDef3 == null)
						{
							Log.Error("GetNextStageModifiers: Item is null");
							continue;
						}
						Log.Info("Selected " + modifierDef3.name + " as enemy item modifier");
					}
					hashSet.Add(modifierDef3.name);
					if (modifierDef3.conflictList != null)
					{
						foreach (string conflict3 in modifierDef3.conflictList)
						{
							hashSet.Add(conflict3);
						}
					}
					if (dictionary.ContainsKey(modifierDef3.name))
					{
						dictionary[modifierDef3.name] += num2;
						continue;
					}
					dictionary.Add(modifierDef3.name, num2);
					list2.Add(modifierDef3);
				}
			}
			int num3 = (int)((Run.instance.GetRunStopwatch() - stageEnterTime) / (punishmentTime * 60f));
			num3 += punishCommandStack;
			if (num3 > 0)
			{
				Log.Info(string.Format("{0}: Adding {1} punishment stacks", "GetNextStageModifiers", num3));
			}
			IEnumerable<ModifierDef> source = list2.Where((ModifierDef s) => s.isStackable);
			if (num3 > 0)
			{
				if (source.Count() == 0)
				{
					Log.Warning("GetNextStageModifiers: There are no stackable negative modifiers to apply punish, adding new");
					List<string> pool5 = StageModifierCatalog.GetPool(component.routeNode.portalType, isNegative: true);
					while (num3 > 0)
					{
						int num4 = Mathf.Min(num3, 3);
						int num5 = Run.instance.stageRng.RangeInt(1, num4 + 1);
						ModifierTier tier = (ModifierTier)num5;
						ModifierDef modifierDef4 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, tier, pool5);
						while (modifierDef4 == null && num5 > 1)
						{
							num5--;
							tier = (ModifierTier)num5;
							modifierDef4 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, tier, pool5);
						}
						if (modifierDef4 == null)
						{
							Log.Warning("GetNextStageModifiers: Couldnt add new negative modifiers");
							break;
						}
						hashSet.Add(modifierDef4.name);
						if (modifierDef4.conflictList != null)
						{
							foreach (string conflict4 in modifierDef4.conflictList)
							{
								hashSet.Add(conflict4);
							}
						}
						num3 -= num5;
						int num6 = 0;
						if (num3 > 0 && modifierDef4.isStackable)
						{
							num6 = Run.instance.stageRng.RangeInt(0, num3 + 1);
							num3 -= num6;
						}
						dictionary.Add(modifierDef4.name, 1 + num6);
						Log.Info(string.Format("{0}: Punish added new modifier {1} with stack {2}", "GetNextStageModifiers", modifierDef4.name, 1 + num6));
					}
				}
				else
				{
					for (int num7 = 0; num7 < num3; num7++)
					{
						ModifierDef modifierDef5 = Run.instance.stageRng.NextElementUniform<ModifierDef>(source.ToArray());
						if (dictionary.ContainsKey(modifierDef5.name))
						{
							dictionary[modifierDef5.name]++;
							Log.Info("GetNextStageModifiers: Added 1 additional stack to " + modifierDef5.name);
						}
					}
				}
			}
			List<ModifierSync> list3 = new List<ModifierSync>();
			foreach (KeyValuePair<string, int> item4 in dictionary)
			{
				ModifierDef modifierDef6 = StageModifierCatalog.FindModifier(item4.Key);
				if (modifierDef6 == null)
				{
					return;
				}
				list3.Add(new ModifierSync(modifierDef6, item4.Value));
			}
			((SyncList<string>)(object)component.stageModifiers).Clear();
			foreach (ModifierSync item5 in list3)
			{
				((SyncList<string>)(object)component.stageModifiers).Add($"{item5.name}={item5.stack}={item5.isArtifact}");
			}
		}

		private int CalculateStack(ModifierDef def, ModifierTier targetTier)
		{
			ModifierTier tier = def.tier;
			if (tier == targetTier)
			{
				return 1;
			}
			if ((tier == ModifierTier.Tier1 && targetTier == ModifierTier.Tier2) || (tier == ModifierTier.Tier2 && targetTier == ModifierTier.Tier3))
			{
				return 2;
			}
			if (tier == ModifierTier.Tier1 && targetTier == ModifierTier.Tier3)
			{
				return 3;
			}
			return 1;
		}

		public ModifierSlotConfiguration GetModifierSlots(Xoroshiro128Plus rng, RoutePortalType type, HashSet<string> banned)
		{
			WeightedSelection<ModifierSlotConfiguration> val = new WeightedSelection<ModifierSlotConfiguration>(8);
			if (type != RoutePortalType.Rare)
			{
				val.AddChoice(new ModifierSlotConfiguration
				{
					positive = { 
					{
						ModifierTier.Tier1,
						2
					} },
					negative = { 
					{
						ModifierTier.Tier1,
						1
					} }
				}, 1f);
				val.AddChoice(new ModifierSlotConfiguration
				{
					positive = { 
					{
						ModifierTier.Tier1,
						2
					} },
					negative = { 
					{
						ModifierTier.Tier2,
						1
					} }
				}, 1f);
				val.AddChoice(new ModifierSlotConfiguration
				{
					positive = { 
					{
						ModifierTier.Tier2,
						1
					} },
					negative = { 
					{
						ModifierTier.Tier1,
						2
					} }
				}, 1f);
			}
			val.AddChoice(new ModifierSlotConfiguration
			{
				positive = { 
				{
					ModifierTier.Tier3,
					1
				} },
				negative = { 
				{
					ModifierTier.Tier3,
					1
				} }
			}, 0.5f);
			val.AddChoice(new ModifierSlotConfiguration
			{
				positive = { 
				{
					ModifierTier.Tier3,
					1
				} },
				negative = 
				{
					{
						ModifierTier.Tier2,
						1
					},
					{
						ModifierTier.Tier1,
						1
					}
				}
			}, 0.5f);
			ModifierSlotConfiguration modifierSlotConfiguration = val.Evaluate(rng.nextNormalizedFloat);
			if (modifierSlotConfiguration.positive.ContainsKey(ModifierTier.Tier3))
			{
				List<string> pool = StageModifierCatalog.GetPool(type);
				if (StageModifierCatalog.SelectModifier(banned, type, ModifierTier.Tier3, pool) == null)
				{
					Log.Warning(string.Format("{0}: Couldnt get Tier3 modifier for node type {1}, using Tier2", "GetModifierSlots", type));
					modifierSlotConfiguration.positive.Remove(ModifierTier.Tier3);
					if (modifierSlotConfiguration.positive.ContainsKey(ModifierTier.Tier2))
					{
						modifierSlotConfiguration.positive[ModifierTier.Tier2] = modifierSlotConfiguration.positive[ModifierTier.Tier2] + 1;
					}
					else
					{
						modifierSlotConfiguration.positive.Add(ModifierTier.Tier2, 2);
					}
				}
			}
			return modifierSlotConfiguration;
		}

		public bool IsModifierActive(string name)
		{
			foreach (ModifierSync item in (SyncList<ModifierSync>)(object)modifiersSynced)
			{
				if (item.name == name)
				{
					return true;
				}
			}
			return false;
		}

		public void AddRoutePortalInstance(GameObject portal)
		{
			if ((Object)(object)portal == (Object)null)
			{
				Log.Error("AddRoutePortalInstance: Route portal is null, cant add instance");
				return;
			}
			RoutePortalManager component = portal.GetComponent<RoutePortalManager>();
			if ((Object)(object)component == (Object)null)
			{
				Log.Error("AddRoutePortalInstance: Route portal manager is null, cant add instance");
			}
			else
			{
				activePortalInstances.Add(portal);
			}
		}

		public void GetModifiersFromRandomPortal()
		{
			if (activePortalInstances == null || activePortalInstances.Count == 0)
			{
				Log.Warning("GetModifiersFromRandomPortal: There are no portal instances to get modifiers from");
				return;
			}
			GameObject val = Run.instance.stageRng.NextElementUniform<GameObject>(activePortalInstances);
			RoutePortalManager component = val.GetComponent<RoutePortalManager>();
			if ((Object)(object)component == (Object)null)
			{
				Log.Warning("GetModifiersFromRandomPortal: Route portal manager is null, cant get modifiers");
				return;
			}
			reservedModifiers.Clear();
			foreach (string item in (SyncList<string>)(object)component.stageModifiers)
			{
				string[] array = item.Split('=');
				instance.reservedModifiers.Add(new ModifierSync
				{
					name = array[0],
					stack = int.Parse(array[1])
				});
			}
			foreach (GameObject activePortalInstance in activePortalInstances)
			{
				GenericInteraction component2 = activePortalInstance.GetComponent<GenericInteraction>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = false;
				}
			}
		}

		public void GetRouteNodeFromRandomPortal()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (activePortalInstances == null || activePortalInstances.Count == 0)
			{
				Log.Warning("GetRouteNodeFromRandomPortal: There are no portal active instances to get routeNode from");
				return;
			}
			Log.Info(string.Format("{0}: Trying to get routeNode from {1} portal instances", "GetRouteNodeFromRandomPortal", activePortalInstances.Count));
			GameObject val = Run.instance.stageRng.NextElementUniform<GameObject>(activePortalInstances);
			RoutePortalManager component = val.GetComponent<RoutePortalManager>();
			if ((Object)(object)component == (Object)null)
			{
				Log.Warning("GetRouteNodeFromRandomPortal: Selected portal instance missing RoutePortalManager");
				return;
			}
			currentNode = component.routeNode;
			NetworkcurrentNodeSync = new Vector2((float)currentNode.x, (float)currentNode.y);
			foreach (GameObject activePortalInstance in activePortalInstances)
			{
				GenericInteraction component2 = activePortalInstance.GetComponent<GenericInteraction>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = false;
				}
			}
		}

		[Server]
		public bool CheckPlayersRedItem()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Boolean SamplePlugin.StageModifierDirector::CheckPlayersRedItem()' called on client");
				return false;
			}
			int num = 0;
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				if ((Object)(object)readOnlyInstances.playerCharacterMasterController == (Object)null)
				{
					continue;
				}
				foreach (ItemIndex item in readOnlyInstances.inventory.itemAcquisitionOrder)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if ((Object)(object)itemDef != (Object)null && (int)itemDef.tier == 2)
					{
						num += readOnlyInstances.inventory.GetItemCount(item);
						Log.Info(string.Format("{0}: Found red item:{1}", "CheckPlayersRedItem", itemDef));
					}
				}
			}
			Log.Info(string.Format("{0}: Players have {1} red items right now", "CheckPlayersRedItem", num));
			return num > 0;
		}

		[Server]
		public bool CheckPlayersYellowItem()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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)
			//IL_009f: Invalid comparison between Unknown and I4
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Boolean SamplePlugin.StageModifierDirector::CheckPlayersYellowItem()' called on client");
				return false;
			}
			int num = 0;
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				if ((Object)(object)readOnlyInstances.playerCharacterMasterController == (Object)null || !Object.op_Implicit((Object)(object)readOnlyInstances.inventory))
				{
					continue;
				}
				foreach (ItemIndex item in readOnlyInstances.inventory.itemAcquisitionOrder)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if ((Object)(object)itemDef != (Object)null && (int)itemDef.tier == 4)
					{
						num += readOnlyInstances.inventory.GetItemCount(item);
						Log.Info(string.Format("{0}: Found yellow item:{1}", "CheckPlayersYellowItem", itemDef));
					}
				}
			}
			Log.Info(string.Format("{0}: Players have {1} yellow items right now", "CheckPlayersYellowItem", num));
			return num > 0;
		}

		[Server]
		public bool CheckRepairAvailable()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Boolean SamplePlugin.StageModifierDirector::CheckRepairAvailable()' called on client");
				return false;
			}
			int num = 0;
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				if ((Object)(object)readOnlyInstances.playerCharacterMasterController == (Object)null || !Object.op_Implicit((Object)(object)readOnlyInstances.inventory))
				{
					continue;
				}
				foreach (ItemIndex item in readOnlyInstances.inventory.itemAcquisitionOrder)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if ((Object)(object)itemDef != (Object)null && itemDef.isConsumed && (Object)(object)itemDef != (Object)(object)Items.RegeneratingScrapConsumed && (Object)(object)itemDef != (Object)(object)Items.LowerPricedChestsConsumed && (Object)(object)itemDef != (Object)(object)Items.TeleportOnLowHealthConsumed)
					{
						num++;
					}
				}
			}
			Log.Info($"Players have {num} consumed items right now");
			return num > 0;
		}

		[Server]
		public bool CheckMountainShrine()
		{
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Boolean SamplePlugin.StageModifierDirector::CheckMountainShrine()' called on client");
				return false;
			}
			if (Object.op_Implicit((Object)(object)TeleporterInteraction.instance))
			{
				return TeleporterInteraction.instance.shrineBonusStacks > 0;
			}
			return false;
		}

		[Server]
		public bool CheckArtifactOfDeathAvailable()
		{
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Boolean SamplePlugin.StageModifierDirector::CheckArtifactOfDeathAvailable()' called on client");
				return false;
			}
			return Run.instance.participatingPlayerCount > 1 && !runArtifactsApplied.Contains("TeamDeath");
		}

		[Server]
		public bool CheckArtifactAvailable(string name)
		{
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Boolean SamplePlugin.StageModifierDirector::CheckArtifactAvailable(System.String)' called on client");
				return false;
			}
			return !runArtifactsApplied.Contains(name);
		}

		[Server]
		public int CheckPlayersHaveFoodItems()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Debug.LogWarning((object)"[Server] function 'System.Int32 SamplePlugin.StageModifierDirector::CheckPlayersHaveFoodItems()' called on client");
				return 0;
			}
			List<ItemDef> list = new List<ItemDef>
			{
				Items.FlatHealth,
				Items.Mushroom,
				Items.Infusion,
				Items.HealWhileSafe,
				Items.MushroomVoid
			};
			int num = 0;
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				if ((Object)(object)readOnlyInstances.playerCharacterMasterController == (Object)null || !Object.op_Implicit((Object)(object)readOnlyInstances.inventory))
				{
					continue;
				}
				foreach (ItemIndex item in readOnlyInstances.inventory.itemAcquisitionOrder)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if ((Object)(object)itemDef != (Object)null && list.Contains(itemDef))
					{
						num += readOnlyInstances.inventory.GetItemCount(itemDef);
					}
				}
			}
			Log.Info($"Players have {num} food related items right now");
			return num;
		}

		public int CheckPlayersHaveFalseSonHeart()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				if ((Object)(object)readOnlyInstances.playerCharacterMasterController == (Object)null || !Object.op_Implicit((Object)(object)readOnlyInstances.inventory))
				{
					continue;
				}
				foreach (ItemIndex item in readOnlyInstances.inventory.itemAcquisitionOrder)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if ((Object)(object)itemDef != (Object)null && itemDef.itemIndex == ModItemsManager.falseSonBless.itemIndex)
					{
						num += readOnlyInstances.inventory.GetItemCount(itemDef);
					}
				}
			}
			Log.Info($"Players have {num} false son bless right now");
			return num;
		}

		public List<RouteMap.RouteNode> GetAvailableNodes()
		{
			if (currentNode != null)
			{
				return currentNode.GetPaths();
			}
			Log.Error("GetAvailableNodes: Current node is null");
			return null;
		}

		private void UNetVersion()
		{
		}

		protected static void InvokeSyncListmodifiersSynced(NetworkBehaviour obj, NetworkReader reader)
		{
			if (!NetworkClient.active)
			{
				Debug.LogError((object)"SyncList modifiersSynced called on server.");
			}
			else
			{
				((SyncList<ModifierSync>)(object)((StageModifierDirector)(object)obj).modifiersSynced).HandleMsg(reader);
			}
		}

		protected static void InvokeRpcRpcReceiveFullMap(NetworkBehaviour obj, NetworkReader reader)
		{
			if (!NetworkClient.active)
			{
				Debug.LogError((object)"RPC RpcReceiveFullMap called on server.");
			}
			else
			{
				((StageModifierDirector)(object)obj).RpcReceiveFullMap(GeneratedNetworkCode._ReadArrayRouteNodeSync_None(reader), (int)reader.ReadPackedUInt32(), (int)reader.ReadPackedUInt32(), reader.ReadBoolean(), reader.ReadSingle());
			}
		}

		public void CallRpcReceiveFullMap(RouteNodeSync[] map, int width, int height, bool moon, float hostStageEnterTime)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Debug.LogError((object)"RPC Function RpcReceiveFullMap called on client.");
				return;
			}
			NetworkWriter val = new NetworkWriter();
			val.Write((short)0);
			val.Write((short)2);
			val.WritePackedUInt32((uint)kRpcRpcReceiveFullMap);
			val.Write(((Component)this).GetComponent<NetworkIdentity>().netId);
			GeneratedNetworkCode._WriteArrayRouteNodeSync_None(val, map);
			val.WritePackedUInt32((uint)width);
			val.WritePackedUInt32((uint)height);
			val.Write(moon);
			val.Write(hostStageEnterTime);
			((NetworkBehaviour)this).SendRPCInternal(val, 0, "RpcReceiveFullMap");
		}

		static StageModifierDirector()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			kRpcRpcReceiveFullMap = -1012231583;
			NetworkBehaviour.RegisterRpcDelegate(typeof(StageModifierDirector), kRpcRpcReceiveFullMap, new CmdDelegate(InvokeRpcRpcReceiveFullMap));
			kListmodifiersSynced = -163976013;
			NetworkBehaviour.RegisterSyncListDelegate(typeof(StageModifierDirector), kListmodifiersSynced, new CmdDelegate(InvokeSyncListmodifiersSynced));
			NetworkCRC.RegisterBehaviour("StageModifierDirector", 0);
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			if (forceAll)
			{
				GeneratedNetworkCode._WriteStructSyncListModifier_None(writer, modifiersSynced);
				writer.WritePackedUInt32((uint)mapWidth);
				writer.WritePackedUInt32((uint)mapHeight);
				writer.Write(isMoonVisited);
				writer.Write(currentNodeSync);
				writer.Write(syncedBaseCurse);
				writer.WritePackedUInt32((uint)cursePerStack);
				writer.Write(punishmentTime);
				writer.Write(purifyLunarItemModifier);
				writer.WritePackedUInt32((uint)doppelStackTime);
				writer.Write(modifiersCanBeBanned);
				writer.WritePackedUInt32((uint)commonDefaultStack);
				writer.WritePackedUInt32((uint)uncommonDefaultStack);
				writer.WritePackedUInt32((uint)legendaryDefaultStack);
				writer.WritePackedUInt32((uint)bossDefaultStack);
				writer.WritePackedUInt32((uint)commonExtraRange);
				writer.WritePackedUInt32((uint)uncommonExtraRange);
				writer.WritePackedUInt32((uint)legendaryExtraRange);
				writer.WritePackedUInt32((uint)bossExtraRange);
				writer.WritePackedUInt32((uint)chanceForExtra);
				return true;
			}
			bool flag = false;
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 1) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				GeneratedNetworkCode._WriteStructSyncListModifier_None(writer, modifiersSynced);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 2) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)mapWidth);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 4) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)mapHeight);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 8) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(isMoonVisited);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x10) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(currentNodeSync);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x20) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(syncedBaseCurse);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x40) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)cursePerStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x80) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(punishmentTime);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x100) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(purifyLunarItemModifier);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x200) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)doppelStackTime);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x400) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(modifiersCanBeBanned);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x800) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)commonDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x1000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)uncommonDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x2000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)legendaryDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x4000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)bossDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x8000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)commonExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x10000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)uncommonExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x20000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)legendaryExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x40000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)bossExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x80000) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)chanceForExtra);
			}
			if (!flag)
			{
				writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
			}
			return flag;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			if (initialState)
			{
				GeneratedNetworkCode._ReadStructSyncListModifier_None(reader, modifiersSynced);
				mapWidth = (int)reader.ReadPackedUInt32();
				mapHeight = (int)reader.ReadPackedUInt32();
				isMoonVisited = reader.ReadBoolean();
				currentNodeSync = reader.ReadVector2();
				syncedBaseCurse = reader.ReadSingle();
				cursePerStack = (int)reader.ReadPackedUInt32();
				punishmentTime = reader.ReadSingle();
				purifyLunarItemModifier = reader.ReadBoolean();
				doppelStackTime = (int)reader.ReadPackedUInt32();
				modifiersCanBeBanned = reader.ReadBoolean();
				commonDefaultStack = (int)reader.ReadPackedUInt32();
				uncommonDefaultStack = (int)reader.ReadPackedUInt32();
				legendaryDefaultStack = (int)reader.ReadPackedUInt32();
				bossDefaultStack = (int)reader.ReadPackedUInt32();
				commonExtraRange = (int)reader.ReadPackedUInt32();
				uncommonExtraRange = (int)reader.ReadPackedUInt32();
				legendaryExtraRange = (int)reader.ReadPackedUInt32();
				bossExtraRange = (int)reader.ReadPackedUInt32();
				chanceForExtra = (int)reader.ReadPackedUInt32();
				return;
			}
			int num = (int)reader.ReadPackedUInt32();
			if ((num & 1) != 0)
			{
				GeneratedNetworkCode._ReadStructSyncListModifier_None(reader, modifiersSynced);
			}
			if ((num & 2) != 0)
			{
				mapWidth = (int)reader.ReadPackedUInt32();
			}
			if ((num & 4) != 0)
			{
				mapHeight = (int)reader.ReadPackedUInt32();
			}
			if ((num & 8) != 0)
			{
				isMoonVisited = reader.ReadBoolean();
			}
			if ((num & 0x10) != 0)
			{
				currentNodeSync = reader.ReadVector2();
			}
			if ((num & 0x20) != 0)
			{
				OnBaseCurseSyncedUpdate(reader.ReadSingle());
			}
			if ((num & 0x40) != 0)
			{
				cursePerStack = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x80) != 0)
			{
				punishmentTime = reader.ReadSingle();
			}
			if ((num & 0x100) != 0)
			{
				purifyLunarItemModifier = reader.ReadBoolean();
			}
			if ((num & 0x200) != 0)
			{
				doppelStackTime = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x400) != 0)
			{
				modifiersCanBeBanned = reader.ReadBoolean();
			}
			if ((num & 0x800) != 0)
			{
				commonDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x1000) != 0)
			{
				uncommonDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x2000) != 0)
			{
				legendaryDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x4000) != 0)
			{
				bossDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x8000) != 0)
			{
				commonExtraRange = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x10000) != 0)
			{
				uncommonExtraRange = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x20000) != 0)
			{
				legendaryExtraRange = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x40000) != 0)
			{
				bossExtraRange = (int)reader.ReadPackedUInt32();
			}
			if ((num & 0x80000) != 0)
			{
				chanceForExtra = (int)reader.ReadPackedUInt32();
			}
		}
	}
}
namespace SamplePlugin.StageModifiers
{
	public abstract class StageModifier
	{
		public int stack = 1;

		public abstract void OnStart();

		public abstract void OnEnd();

		protected GameObject TryPlaceObjectOnScene(SpawnCard spawnCard, string name = "object")
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_007f: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				return null;
			}
			if ((Object)(object)spawnCard == (Object)null)
			{
				Log.Error("Something went wrong with " + name + " spawncard");
				return null;
			}
			if (!Object.op_Implicit((Object)(object)Run.instance))
			{
				return null;
			}
			Log.Info("Trying to place " + name);
			GameObject val = null;
			for (int i = 0; i < 15; i++)
			{
				DirectorPlacementRule val2 = new DirectorPlacementRule
				{
					placementMode = (PlacementMode)4
				};
				val = DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest(spawnCard, val2, Run.instance.stageRng));
				if (Object.op_Implicit((Object)(object)val))
				{
					Log.Info($"Succesfully placed {name} on {val.transform.position}");
					break;
				}
				Log.Error("Failed to place " + name + ", retrying");
			}
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("It was impossible to place " + name);
			}
			return val;
		}
	}
}
namespace SamplePlugin.StageModifiers.SceneModifiers
{
	public class MoreDronesModifier : StageModifier
	{
		public MoreDronesModifier(int stack)
		{
			base.stack = stack;
		}

		public override void OnEnd()
		{
			Log.Info("MoreDronesModifier end");
		}

		public override void OnStart()
		{
			Log.Info("MoreDronesModifier start");
			PopulateDrones();
		}

		public void PopulateDrones()
		{
			//IL_008d: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Invalid comparison between Unknown and I4
			int num = 0;
			int sceneDirectorInteractibleCredits = ClassicStageInfo.instance.sceneDirectorInteractibleCredits;
			float num2 = (float)global::RiskOfRoutes.RiskOfRoutes.droneStackPercent.Value / 100f;
			int num3 = (int)((float)(sceneDirectorInteractibleCredits * stack) * num2);
			Log.Info(string.Format("{0}: Drone stack percent is {1}", "PopulateDrones", num2));
			Log.Info("PopulateDrones: Spawning more drones");
			ClassicStageInfo instance = ClassicStageInfo.instance;
			WeightedSelection<DirectorCard> val = new WeightedSelection<DirectorCard>(8);
			Category val2 = ((IEnumerable<Category>)instance.interactableCategories.categories).FirstOrDefault((Func<Category, bool>)((Category c) => c.name == "Drones"));
			if (val2.cards.Length == 0)
			{
				Log.Error("PopulateDrones: No drones available on stage");
				return;
			}
			DirectorCard[] cards = val2.cards;
			foreach (DirectorCard val3 in cards)
			{
				if (val3.IsAvailable())
				{
					val.AddChoice(val3, (float)val3.selectionWeight);
				}
			}
			int num5 = 100;
			while (num3 > 0 && num5 > 0)
			{
				DirectorCard val4 = SelectCard(val, num3);
				if (val4 == null)
				{
					break;
				}
				if (!val4.IsAvailable())
				{
					continue;
				}
				GameObject val5 = TryPlaceObjectOnScene(val4.spawnCard, ((Object)val4.spawnCard).name);
				if ((Object)(object)val5 != (Object)null)
				{
					PurchaseInteraction component = val5.GetComponent<PurchaseInteraction>();
					if (Object.op_Implicit((Object)(object)component) && (int)component.costType == 1)
					{
						component.Networkcost = Run.instance.GetDifficultyScaledCost(component.cost);
					}
					num3 -= val4.cost;
					num++;
				}
				num5--;
			}
			Log.Info(string.Format("{0}: Spawned {1} more drones", "PopulateDrones", num));
		}

		private static DirectorCard SelectCard(WeightedSelection<DirectorCard> deck, int maxCost)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			WeightedSelection<DirectorCard> val = new WeightedSelection<DirectorCard>(maxCost);
			int i = 0;
			for (int count = deck.Count; i < count; i++)
			{
				ChoiceInfo<DirectorCard> choice = deck.GetChoice(i);
				if (choice.value.cost <= maxCost)
				{
					val.AddChoice(choice);
				}
			}
			if (val.Count == 0)
			{
				return null;
			}
			return val.Evaluate(Run.instance.stageRng.nextNormalizedFloat);
		}
	}
	public class PrinterItemModifier : StageModifier
	{
		public ItemDef selectedItem;

		public static InteractableSpawnCard printerSpawnCard;

		public PrinterItemModifier(string internalName)
		{
			selectedItem = stringToItemDef(internalName);
			if (!((Object)(object)selectedItem == (Object)null))
			{
				CreatePrinterSpawnCard();
			}
		}

		public static ItemDef stringToItemDef(string selectedItemName)
		{
			//IL_0002: 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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ItemIndex val = ItemCatalog.FindItemIndex(selectedItemName);
			if ((int)val != -1)
			{
				return ItemCatalog.GetItemDef(val);
			}
			Log.Error("Error finding item");
			return null;
		}

		public override void OnEnd()
		{
			Log.Info("PrinterItemModifier end");
		}

		public override void OnStart()
		{
			Log.Info("PrinterItemModifier start");
			SpawnPrinter();
		}

		private void SpawnPrinter()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_0096: 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)
			GameObject val = TryPlaceObjectOnScene((SpawnCard)(object)printerSpawnCard, "Printer with " + ((Object)selectedItem).name);
			if (Object.op_Implicit((Object)(object)val))
			{
				Log.Info($"printer appeared at {val.transform.position} on stage");
				ShopTerminalBehavior component = val.GetComponent<ShopTerminalBehavior>();
				component.dropTable = null;
				component.selfGeneratePickup = false;
				component.itemTier = selectedItem.tier;
				PickupIndex pickupIndex = PickupCatalog.FindPickupIndex(selectedItem.itemIndex);
				UniquePickup val2 = new UniquePickup
				{
					pickupIndex = pickupIndex
				};
				component.SetPickup(val2, false);
			}
		}

		private void CreatePrinterSpawnCard()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			ItemTier tier = selectedItem.tier;
			if (1 == 0)
			{
			}
			InteractableSpawnCard val = (InteractableSpawnCard)((int)tier switch
			{
				0 => AssetManager.tier1Printer, 
				1 => AssetManager.tier2Printer, 
				2 => AssetManager.tier3Printer, 
				4 => AssetManager.bossPrinter, 
				_ => AssetManager.tier1Printer, 
			});
			if (1 == 0)
			{
			}
			InteractableSpawnCard val2 = val;
			if ((Object)(object)val2 != (Object)null)
			{
				printerSpawnCard = val2;
			}
			else
			{
				Log.Error("Asset path is invalid");
			}
		}
	}
	public class RedPrinterModifier : StageModifier
	{
		public static InteractableSpawnCard redPrinterSpawnCard;

		public ItemTag tag;

		public RedPrinterModifier(int stack, ItemTag tag = (ItemTag)0)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			CreateRedPrinterSpawnCard();
			base.stack = stack;
			this.tag = tag;
		}

		public override void OnEnd()
		{
			Log.Info("RedPrinter on end");
		}

		public override void OnStart()
		{
			Log.Info("RedPrinter on start");
			SpawnRedPrinter();
		}

		private void SpawnRedPrinter()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0039: Invalid comparison between Unknown and I4
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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)
			List<PickupIndex> availableTier3DropList = Run.instance.availableTier3DropList;
			List<PickupIndex> list = new List<PickupIndex>();
			foreach (PickupIndex item in availableTier3DropList)
			{
				PickupDef pickupDef = PickupCatalog.GetPickupDef(item);
				if (pickupDef != null && (int)pickupDef.itemIndex != -1)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
					if ((Object)(object)itemDef != (Object)null && itemDef.tags.Contains(tag))
					{
						list.Add(item);
					}
				}
			}
			if (list.Count == 0)
			{
				Log.Error($"No red items available for tag {tag}");
				list = availableTier3DropList;
			}
			for (int i = 0; i < stack; i++)
			{
				GameObject val = TryPlaceObjectOnScene((SpawnCard)(object)redPrinterSpawnCard, "Red item printer");
				if (Object.op_Implicit((Object)(object)val))
				{
					ShopTerminalBehavior component = val.GetComponent<ShopTerminalBehavior>();
					component.dropTable = null;
					component.selfGeneratePickup = false;
					PickupIndex pickupIndex = Run.instance.stageRng.NextElementUniform<PickupIndex>(list);
					UniquePickup val2 = new UniquePickup
					{
						pickupIndex = pickupIndex
					};
					component.SetPickup(val2, false);
				}
			}
		}

		private void CreateRedPrinterSpawnCard()
		{
			InteractableSpawnCard tier3Printer = AssetManager.tier3Printer;
			if ((Object)(object)tier3Printer != (Object)null)
			{
				redPrinterSpawnCard = tier3Printer;
			}
		}
	}
	public class WanderingChefModifier : StageModifier
	{
		public static bool spawnCardCreated;

		public static InteractableSpawnCard chefSpawnCard;

		public override void OnEnd()
		{
			Log.Info("WanderingChef on end");
		}

		public override void OnStart()
		{
			Log.Info("WanderingChef on start");
			SpawnWanderingChef();
		}

		private void SpawnWanderingChef()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			InteractableSpawnCard wanderingChefSpawnCard = AssetManager.wanderingChefSpawnCard;
			GameObject val = TryPlaceObjectOnScene((SpawnCard)(object)wanderingChefSpawnCard, "Wandering Chef");
			if (Object.op_Implicit((Object)(object)val))
			{
				Transform transform = val.transform;
				transform.position += val.transform.up * 1f;
			}
		}
	}
	public class YellowPrinterModifier : StageModifier
	{
		public static InteractableSpawnCard yellowPrinterSpawnCard;

		public ItemTag tag;

		public YellowPrinterModifier(int stack, ItemTag tag = (ItemTag)0)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			CreateYellowPrinterSpawnCard();
			base.stack = stack;
			this.tag = tag;
		}

		public override void OnEnd()
		{
			Log.Info("YellowPrinterModifier on end");
		}

		public override void OnStart()
		{
			Log.Info("YellowPrinterModifier on start");
			SpawnYellowPrinter();
		}

		private void SpawnYellowPrinter()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0039: Invalid comparison between Unknown and I4
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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)
			List<PickupIndex> availableBossDropList = Run.instance.availableBossDropList;
			List<PickupIndex> list = new List<PickupIndex>();
			foreach (PickupIndex item in availableBossDropList)
			{
				PickupDef pickupDef = PickupCatalog.GetPickupDef(item);
				if (pickupDef != null && (int)pickupDef.itemIndex != -1)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
					if ((Object)(object)itemDef != (Object)null && itemDef.tags.Contains(tag))
					{
						list.Add(item);
					}
				}
			}
			if (list.Count == 0)
			{
				Log.Error($"No yellow items available for tag {tag}");
				list = availableBossDropList;
			}
			for (int i = 0; i < stack; i++)
			{
				GameObject val = TryPlaceObjectOnScene((SpawnCard)(object)yellowPrinterSpawnCard, "Yellow item printer");
				if (Object.op_Implicit((Object)(object)val))
				{
					ShopTerminalBehavior component = val.GetComponent<ShopTerminalBehavior>();
					component.dropTable = null;
					component.selfGeneratePickup = false;
					PickupIndex pickupIndex = Run.instance.stageRng.NextElementUniform<PickupIndex>(list);
					UniquePickup val2 = new UniquePickup
					{
						pickupIndex = pickupIndex
					};
					component.SetPickup(val2, false);
				}
			}
		}

		private void CreateYellowPrinterSpawnCard()
		{
			InteractableSpawnCard bossPrinter = AssetManager.bossPrinter;
			if ((Object)(object)bossPrinter != (Object)null)
			{
				yellowPrinterSpawnCard = bossPrinter;
			}
			else
			{
				Log.Error("Asset path is invalid");
			}
		}
	}
}
namespace SamplePlugin.StageModifiers.OtherModifiers
{
	public class ArtifactModifier : StageModifier
	{
		private ArtifactDef currentArtifact;

		public ArtifactModifier(ArtifactDef artifact)
		{
			currentArtifact = artifact;
		}

		public ArtifactModifier(string name, bool isPositive)
		{
			currentArtifact = ArtifactCatalog.FindArtifactDef(name);
			if ((Object)(object)currentArtifact == (Object)null)
			{
				Log.Error("Could not find artifact by the name " + name);
			}
			else
			{
				name = currentArtifact.cachedName;
			}
		}

		public ArtifactModifier()
		{
			currentArtifact = Artifacts.MixEnemy;
			if ((Object)(object)currentArtifact == (Object)null)
			{
				Log.Error("CurrentArtifact is null");
			}
		}

		public override void OnEnd()
		{
			Log.Info("ArtifactModifier on end");
			if (Object.op_Implicit((Object)(object)currentArtifact))
			{
				if (Object.op_Implicit((Object)(object)Run.instance))
				{
					RunArtifactManager.instance.SetArtifactEnabled(currentArtifact, false);
					Log.Info("Succesfully disabled artifact: " + currentArtifact.cachedName);
				}
				else
				{
					Log.Info("Run already ended");
				}
			}
			else
			{
				Log.Info("No current artifact for some reason");
			}
		}

		public override void OnStart()
		{
			Log.Info("ArtifactModifier on start start");
			if (Object.op_Implicit((Object)(object)currentArtifact))
			{
				RunArtifactManager.instance.SetArtifactEnabled(currentArtifact, true);
			}
			else
			{
				Log.Info("No such artifact");
			}
		}
	}
	public class RepairConsumedItemsModifier : StageModifier
	{
		public override void OnEnd()
		{
			Log.Info("Repair on end");
		}

		public override void OnStart()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Invalid comparison between Unknown and I4
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			Log.Info("Repair on start");
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				if (!Object.op_Implicit((Object)(object)readOnlyInstances.inventory))
				{
					continue;
				}
				List<ItemIndex> list = new List<ItemIndex>(readOnlyInstances.inventory.itemAcquisitionOrder);
				foreach (ItemIndex item in list)
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(item);
					if (!((Object)(object)itemDef != (Object)null) || !itemDef.isConsumed || !((Object)(object)itemDef != (Object)(object)Items.RegeneratingScrapConsumed) || !((Object)(object)itemDef != (Object)(object)Items.LowerPricedChestsConsumed) || !((Object)(object)itemDef != (Object)(object)Items.TeleportOnLowHealthConsumed))
					{
						continue;
					}
					int itemCount = readOnlyInstances.inventory.GetItemCount(itemDef);
					readOnlyInstances.inventory.RemoveItem(itemDef, itemCount);
					ItemDef val = null;
					if ((Object)(object)itemDef == (Object)(object)Items.FragileDamageBonusConsumed)
					{
						val = Items.FragileDamageBonus;
					}
					else if ((Object)(object)itemDef == (Object)(object)Items.HealingPotionConsumed)
					{
						val = Items.HealingPotion;
					}
					else if ((Object)(object)itemDef == (Object)(object)Items.ExtraLifeVoidConsumed)
					{
						val = Items.ExtraLifeVoid;
					}
					else if ((Object)(object)itemDef == (Object)(object)Items.ExtraLifeConsumed)
					{
						val = Items.ExtraLife;
					}
					else
					{
						ItemIndex val2 = ItemCatalog.FindItemIndex(((Object)itemDef).name.Replace("Consumed", ""));
						if ((int)val2 != -1)
						{
							ItemDef itemDef2 = ItemCatalog.GetItemDef(val2);
							if ((Object)(object)itemDef2 != (Object)null)
							{
								val = itemDef2;
							}
						}
					}
					Log.Debug($"For consumed item{itemDef} in count {itemCount} found repaired {val}");
					readOnlyInstances.inventory.GiveItem(val, itemCount);
					Log.Info("Succesfully repaired " + ((Object)itemDef).name);
				}
			}
		}
	}
}
namespace SamplePlugin.StageModifiers.CombatModifiers
{
	public class EnemyItemsModifier : StageModifier
	{
		private ItemDef selectedItem;

		public EnemyItemsModifier(string internalName, int stack)
		{
			selectedItem = PrinterItemModifier.stringToItemDef(internalName);
			if (!((Object)(object)selectedItem == (Object)null))
			{
				base.stack = stack;
			}
		}

		public override void OnEnd()
		{
			Log.Info("EnemyItems on end");
			SpawnCard.onSpawnedServerGlobal -= SpawnCard_onSpawnedServerGlobal;
			StageModifierDirector.instance.monsterTeamInventory.CleanInventory();
		}

		public override void OnStart()
		{
			Log.Info("EnemyItems on start");
			int itemStack = GetItemStack(selectedItem, stack);
			StageModifierDirector.instance.monsterTeamInventory.GiveItemPermanent(selectedItem, itemStack);
			SpawnCard.onSpawnedServerGlobal += SpawnCard_onSpawnedServerGlobal;
		}

		private void SpawnCard_onSpawnedServerGlobal(SpawnResult spawnResult)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_002c: Invalid comparison between Unknown and I4
			CharacterMaster val = (Object.op_Implicit((Object)(object)spawnResult.spawnedInstance) ? spawnResult.spawnedInstance.GetComponent<CharacterMaster>() : null);
			if (Object.op_Implicit((Object)(object)val) && (int)val.teamIndex == 2)
			{
				val.inventory.AddItemsFrom(StageModifierDirector.instance.monsterTeamInventory);
			}
		}

		public static int GetItemStack(ItemDef def, int modStack)
		{
			//IL_00e7: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected I4, but got Unknown
			int num = StageModifierDirector.instance?.commonDefaultStack ?? 5;
			int num2 = StageModi