Decompiled source of RiskOfRoutes v1.0.4

RiskOfRoutes.dll

Decompiled 2 weeks 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.Configuration;
using BepInEx.Logging;
using HG;
using HG.Reflection;
using IL.RoR2;
using LeTai.Asset.TranslucentImage;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RiskOfRoutes;
using RiskOfRoutes.StageModifiers;
using RiskOfRoutes.StageModifiers.CombatModifiers;
using RiskOfRoutes.StageModifiers.OtherModifiers;
using RiskOfRoutes.StageModifiers.SceneModifiers;
using RoR2;
using RoR2.Artifacts;
using RoR2.CharacterAI;
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;

[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+1027ebc23d4b579fb2e8fe94723bf2ece01c5281")]
[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]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
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;
		for (int i = 0; i < width; i++)
		{
			for (int j = 1; j < height; j++)
			{
				mapGrid[i, j] = new RouteNode(i, j);
			}
		}
		List<RouteNode> list = SetupPaths(rng);
		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 != 0)
			{
				mapGrid[i, 1].portalType = val.Evaluate(rng.nextNormalizedFloat);
			}
			if (mapGrid[i, 3].portalType != 0)
			{
				mapGrid[i, 3].portalType = val2.Evaluate(rng.nextNormalizedFloat);
			}
			if (mapGrid[i, 2].portalType != 0)
			{
				mapGrid[i, 2].portalType = val2.Evaluate(rng.nextNormalizedFloat);
			}
			if (mapGrid[i, 4].portalType != 0)
			{
				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);
		}
	}

	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 != 0 && 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
}
public enum ModifierTier
{
	Tier1 = 1,
	Tier2,
	Tier3
}
public enum ModifierRarity
{
	Common,
	Rare
}
namespace SamplePlugin
{
	public class CommandHelper : MonoBehaviour
	{
		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetNextStagesScenes(ConCommandArgs args)
		{
			Log.Info("Next stages available:");
			foreach (SceneDef nextStagesScenes in SceneHelper.GetNextStagesScenesList())
			{
				Log.Info(nextStagesScenes.cachedName);
			}
			Log.Info(Run.instance.nextStageScene.destinationsGroup);
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetBannedStage(ConCommandArgs args)
		{
			Log.Info("Banned on stage: ");
			foreach (string item in StageModifierDirector.instance.bannedModifiersStage)
			{
				Log.Info("\t" + item);
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetBannedRun(ConCommandArgs args)
		{
			Log.Info("Banned in run: ");
			foreach (string item in StageModifierDirector.instance.bannedModifiersRun)
			{
				Log.Info("\t" + item);
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetAvailablePrinters(ConCommandArgs args)
		{
			Log.Info("Printer items: ");
			Log.Info("\tUtility pool: ");
			foreach (string item in StageModifierCatalog.utilityPool)
			{
				Log.Info("\t\t" + item);
			}
			Log.Info("Heal pool: ");
			foreach (string item2 in StageModifierCatalog.healPool)
			{
				Log.Info("\t\t" + item2);
			}
			Log.Info("Damage pool: ");
			foreach (string item3 in StageModifierCatalog.combatPool)
			{
				Log.Info("\t\t" + item3);
			}
			Log.Info("Food-related pool: ");
			foreach (string item4 in StageModifierCatalog.chefPool)
			{
				Log.Info("\t\t" + item4);
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetAvailableEnemyItems(ConCommandArgs args)
		{
			Log.Info("Enemy items: ");
			foreach (string item in StageModifierCatalog.generalNegativePool)
			{
				if (item.EndsWith("_EnemyItem"))
				{
					Log.Info("\t" + item);
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetAvailableLunarItems(ConCommandArgs args)
		{
			Log.Info("Lunar items: ");
			foreach (string item in StageModifierCatalog.generalNegativePool)
			{
				if (item.EndsWith("_LunarItem"))
				{
					Log.Info("\t" + item);
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetAvailableArtifacts(ConCommandArgs args)
		{
			Log.Info("Artifacts available: ");
			foreach (string item in StageModifierCatalog.generalNegativePool.Where((string def) => StageModifierCatalog.FindModifier(def).isArtifact))
			{
				Log.Info("\t" + item);
			}
			foreach (string item2 in StageModifierCatalog.rarePool.Where((string def) => StageModifierCatalog.FindModifier(def).isArtifact))
			{
				Log.Info("\t" + item2);
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetAllArtifactDefs(ConCommandArgs args)
		{
			Log.Info("Artifacts defs: ");
			ArtifactDef[] artifactDefs = ArtifactCatalog.artifactDefs;
			foreach (ArtifactDef val in artifactDefs)
			{
				Log.Info("\t" + val.cachedName + " - " + val.nameToken);
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCReinit(ConCommandArgs args)
		{
			StageModifierCatalog.Init(AssetManager.bundle);
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetNextGreenStage(ConCommandArgs args)
		{
			Log.Info($"Modul:{Stage.instance.sceneDef.stageOrder}");
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetDccs(ConCommandArgs args)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Log.Info("Available enemies");
			WeightedSelection<DirectorCard> monsterSelection = ClassicStageInfo.instance.monsterSelection;
			if (monsterSelection != null)
			{
				for (int i = 0; i < monsterSelection.Count; i++)
				{
					DirectorCard value = monsterSelection.GetChoice(i).value;
					Log.Info($"DirectorCard {((Object)value.spawnCard).name}, cost: {value.cost}, weight: {value.selectionWeight}");
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetCurrentNode(ConCommandArgs args)
		{
			List<RouteNodeSync> routeNodesSynced = StageModifierDirector.instance.routeNodesSynced;
			if (routeNodesSynced.Count == 0)
			{
				Log.Error("none");
			}
			foreach (RouteNodeSync item in routeNodesSynced)
			{
				Log.Info($"{item.x}.{item.y}:{item.portalType}-{item.visited}");
			}
			RouteMap.RouteNode currentNode = StageModifierDirector.instance.currentNode;
			Log.Info($"Current node is {currentNode.x},{currentNode.y} with {currentNode.GetPaths().Count} children, visited {currentNode.visited}");
			Log.Info("\tNext scene:" + Run.instance.nextStageScene.cachedName);
			Log.Info("\tCurr scene:" + Stage.instance.sceneDef.cachedName);
			Log.Info($"\tLoop clear count:{Run.instance.loopClearCount}");
			Log.Info($"Child node: {currentNode.GetPaths()[0].x}.{currentNode.GetPaths()[0].y}: {currentNode.GetPaths()[0].portalType}");
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetElitesAvailable(ConCommandArgs args)
		{
			FieldInfo field = typeof(CombatDirector).GetField("eliteTiers", BindingFlags.Static | BindingFlags.NonPublic);
			if (!(field != null))
			{
				return;
			}
			EliteTierDef[] array = (EliteTierDef[])field.GetValue(null);
			Log.Info($"Tier count{array.Length}");
			for (int i = 0; i < array.Length; i++)
			{
				Log.Info($"Tier{i + 1}: {array[i].availableDefs.Count}");
				foreach (EliteDef availableDef in array[i].availableDefs)
				{
					if ((Object)(object)availableDef != (Object)null)
					{
						Log.Info("\t " + ((Object)availableDef).name);
					}
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetItemDefs(ConCommandArgs args)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Log.Info("Enemies can have");
			foreach (ItemDef item in ((IEnumerable<ItemDef>)(object)ItemCatalog.allItemDefs).Where((ItemDef def) => def.DoesNotContainTag((ItemTag)4)))
			{
				Log.Info($"\t{((Object)item).name}, {item.requiredExpansion}");
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCSetPunish(ConCommandArgs args)
		{
			if (NetworkServer.active)
			{
				int value = ((ConCommandArgs)(ref args)).TryGetArgInt(0).Value;
				StageModifierDirector.instance.commandAddedStack = value;
				Log.Info($"Set additional punish to {value}");
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCItemTags(ConCommandArgs args)
		{
			//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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_0043: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Invalid comparison between Unknown and I4
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Invalid comparison between Unknown and I4
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Invalid comparison between Unknown and I4
			Log.Info("Items with damage tag");
			Enumerator<ItemDef> enumerator = ItemCatalog.allItemDefs.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ItemDef current = enumerator.Current;
					if (current.tags.Contains((ItemTag)1) && ((int)current.tier == 0 || (int)current.tier == 1))
					{
						Log.Info("\t" + ((Object)current).name + ":" + Language.GetString(current.nameToken));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			Log.Info("Items with healing tag");
			Enumerator<ItemDef> enumerator2 = ItemCatalog.allItemDefs.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					ItemDef current2 = enumerator2.Current;
					if (current2.tags.Contains((ItemTag)2) && ((int)current2.tier == 0 || (int)current2.tier == 1))
					{
						Log.Info("\t" + ((Object)current2).name + ":" + Language.GetString(current2.nameToken));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2).Dispose();
			}
			Log.Info("Items with utility tag");
			Enumerator<ItemDef> enumerator3 = ItemCatalog.allItemDefs.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					ItemDef current3 = enumerator3.Current;
					if (current3.tags.Contains((ItemTag)3) && ((int)current3.tier == 0 || (int)current3.tier == 1))
					{
						Log.Info("\t" + ((Object)current3).name + ":" + Language.GetString(current3.nameToken));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator3).Dispose();
			}
			Log.Info("Items with food-related tag");
			Enumerator<ItemDef> enumerator4 = ItemCatalog.allItemDefs.GetEnumerator();
			try
			{
				while (enumerator4.MoveNext())
				{
					ItemDef current4 = enumerator4.Current;
					if (current4.tags.Contains((ItemTag)28) && ((int)current4.tier == 0 || (int)current4.tier == 1))
					{
						Log.Info("\t" + ((Object)current4).name + ":" + Language.GetString(current4.nameToken));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator4).Dispose();
			}
			Log.Info("Items with ai_blacklist tag");
			Enumerator<ItemDef> enumerator5 = ItemCatalog.allItemDefs.GetEnumerator();
			try
			{
				while (enumerator5.MoveNext())
				{
					ItemDef current5 = enumerator5.Current;
					if (current5.tags.Contains((ItemTag)4))
					{
						Log.Info("\t" + ((Object)current5).name + ":" + Language.GetString(current5.nameToken));
					}
				}
			}
			finally
			{
				((IDisposable)enumerator5).Dispose();
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetActiveModifiers(ConCommandArgs args)
		{
			Log.Info("Getting synced modifiers");
			if (!((Object)(object)StageModifierDirector.instance != (Object)null))
			{
				return;
			}
			SyncListModifier modifiersSynced = StageModifierDirector.instance.modifiersSynced;
			if (modifiersSynced != null)
			{
				if (((SyncListStruct<ModifierSync>)modifiersSynced).Count > 0)
				{
					foreach (ModifierSync item in (SyncList<ModifierSync>)(object)modifiersSynced)
					{
						Log.Info($"{item.name}:{item.stack}");
					}
					return;
				}
				Log.Info("There are no modifiers");
			}
			else
			{
				Log.Error("Modifiers list is null");
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetSyncedData(ConCommandArgs args)
		{
			Log.Info("Getting synced modifiers");
			if ((Object)(object)StageModifierDirector.instance != (Object)null)
			{
				Log.Info("Modifiers synced");
				{
					foreach (ModifierSync item in (SyncList<ModifierSync>)(object)StageModifierDirector.instance.modifiersSynced)
					{
						Log.Info($"{item.name}:{item.stack}:{item.isArtifact}");
					}
					return;
				}
			}
			Log.Info("StageModifierDirector is null");
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCGetReservedModifiers(ConCommandArgs args)
		{
			if ((Object)(object)StageModifierDirector.instance != (Object)null)
			{
				List<ModifierSync> reservedModifiers = StageModifierDirector.instance.reservedModifiers;
				if (reservedModifiers != null)
				{
					if (reservedModifiers.Count > 0)
					{
						foreach (ModifierSync item in reservedModifiers)
						{
							Log.Info(item);
						}
						return;
					}
					Log.Info("There are no modifiers");
				}
				else
				{
					Log.Error("Modifiers list is null");
				}
			}
			else
			{
				Log.Error("It is null");
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCFindShopPortal(ConCommandArgs args)
		{
			GameObject val = GameObject.Find("Node");
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("Could not find it");
				return;
			}
			Log.Info("Found it");
			Component[] componentsInChildren = val.GetComponentsInChildren<Component>();
			foreach (Component val2 in componentsInChildren)
			{
				Log.Info(((object)val2).GetType());
			}
			SceneExitController component = val.GetComponent<SceneExitController>();
			Log.Info(component.destinationScene);
			Log.Info(component.useRunNextStageScene);
		}
	}
	[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)
		{
			ModifierSync result = default(ModifierSync);
			result.name = reader.ReadString();
			result.stack = (int)reader.ReadPackedUInt32();
			result.isArtifact = reader.ReadBoolean();
			return result;
		}
	}
	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)
		{
			RouteNodeSync result = default(RouteNodeSync);
			result.portalType = (RoutePortalType)reader.ReadInt32();
			result.x = (int)reader.ReadPackedUInt32();
			result.y = (int)reader.ReadPackedUInt32();
			result.frontX = (int)reader.ReadPackedUInt32();
			result.frontY = (int)reader.ReadPackedUInt32();
			result.leftX = (int)reader.ReadPackedUInt32();
			result.leftY = (int)reader.ReadPackedUInt32();
			result.rightX = (int)reader.ReadPackedUInt32();
			result.rightY = (int)reader.ReadPackedUInt32();
			result.bonusX = (int)reader.ReadPackedUInt32();
			result.bonusY = (int)reader.ReadPackedUInt32();
			result.visited = reader.ReadBoolean();
			result.shopVisited = reader.ReadBoolean();
			result.goldshoresVisited = reader.ReadBoolean();
			result.voidFieldsVisited = reader.ReadBoolean();
			return result;
		}
	}
	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 int uniqueModifierLimit = 5;

		public Inventory monsterTeamInventory;

		public RouteMap routeMap;

		public RouteMap.RouteNode currentNode;

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

		[SyncVar]
		public int soulCostStack = 0;

		public int commandAddedStack = 0;

		[SyncVar]
		public float punishmentTime = -1f;

		[SyncVar]
		public bool purifyLunarItemModifier;

		[SyncVar]
		public int doppelStackTime = 30;

		[SyncVar]
		public bool modifiersCanBeBanned = true;

		[SyncVar]
		public bool enemyItemsModifierCanStack = false;

		[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 NetworksoulCostStack
		{
			get
			{
				return soulCostStack;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<int>(value, ref soulCostStack, 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 bool NetworkenemyItemsModifierCanStack
		{
			get
			{
				return enemyItemsModifierCanStack;
			}
			[param: In]
			set
			{
				((NetworkBehaviour)this).SetSyncVar<bool>(value, ref enemyItemsModifierCanStack, 2048u);
			}
		}

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

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

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

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

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

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

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

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

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

		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;
		}

		private void Run_onRunStartGlobal(Run run)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			Log.Info("Run_onRunStartGlobal: Run started");
			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 CreateRunConfiguration()
		{
			NetworkenemyItemsModifierCanStack = global::RiskOfRoutes.RiskOfRoutes.enemyItemsModifierCanStack.Value;
			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();
			if (!global::RiskOfRoutes.RiskOfRoutes.allowAurelioniteModifier.Value)
			{
				bannedModifiersRun.Add("Aurelionite");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowBossRedItemModifier.Value)
			{
				bannedModifiersRun.Add("BossRedItem");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowBossYellowItemModifier.Value)
			{
				bannedModifiersRun.Add("BossYellowItem");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowDroneBossGreenModifier.Value)
			{
				bannedModifiersRun.Add("DroneBossGreen");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowDroneBossRedModifier.Value)
			{
				bannedModifiersRun.Add("DroneBossRed");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowMoreElitesModifier.Value)
			{
				bannedModifiersRun.Add("MoreElites");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowMoreDronesModifier.Value)
			{
				bannedModifiersRun.Add("MoreDrones");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowUpgradeDronesModifier.Value)
			{
				bannedModifiersRun.Add("UpgradeDrones");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowLunarEnemiesModifier.Value)
			{
				bannedModifiersRun.Add("LunarEnemies");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowVoidEnemiesModifier.Value)
			{
				bannedModifiersRun.Add("VoidEnemies");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowYellowPrinterModifier.Value)
			{
				bannedModifiersRun.Add("YellowPrinter");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowRedPrinterModifier.Value)
			{
				bannedModifiersRun.Add("RedPrinter");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowOnlyFlyingModifier.Value)
			{
				bannedModifiersRun.Add("OnlyFlying");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowPowerfulElitesModifier.Value)
			{
				bannedModifiersRun.Add("PowerfulElites");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowRepairModifier.Value)
			{
				bannedModifiersRun.Add("Repair");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowWanderingChefModifier.Value)
			{
				bannedModifiersRun.Add("WanderingChef");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowMountainModifier.Value)
			{
				bannedModifiersRun.Add("Mountain");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowSoulCostModifier.Value)
			{
				bannedModifiersRun.Add("SoulCost");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowDoppelgangerModifier.Value)
			{
				bannedModifiersRun.Add("Doppelganger");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowMysteryArtifact.Value)
			{
				bannedModifiersRun.Add("Mystery");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowChaosArtifact.Value)
			{
				bannedModifiersRun.Add("FriendlyFire");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowCommandArtifact.Value)
			{
				bannedModifiersRun.Add("Command");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowDelusionArtifact.Value)
			{
				bannedModifiersRun.Add("Delusion");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowDevotionArtifact.Value)
			{
				bannedModifiersRun.Add("Devotion");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowDissonanceArtifact.Value)
			{
				bannedModifiersRun.Add("MixEnemy");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowEnigmaArtifact.Value)
			{
				bannedModifiersRun.Add("Enigma");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowEvolutionArtifact.Value)
			{
				bannedModifiersRun.Add("MonsterTeamGainsItems");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowFrailtyArtifact.Value)
			{
				bannedModifiersRun.Add("WeakAssKnees");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowGlassArtifact.Value)
			{
				bannedModifiersRun.Add("Glass");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowHonorArtifact.Value)
			{
				bannedModifiersRun.Add("EliteOnly");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowKinArtifact.Value)
			{
				bannedModifiersRun.Add("SingleMonsterType");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowMetamorphosisArtifact.Value)
			{
				bannedModifiersRun.Add("RandomSurvivorOnRespawn");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowRebirthArtifact.Value)
			{
				bannedModifiersRun.Add("Rebirth");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowSacrificeArtifact.Value)
			{
				bannedModifiersRun.Add("Sacrifice");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowSoulArtifact.Value)
			{
				bannedModifiersRun.Add("WispOnDeath");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowSpiteArtifact.Value)
			{
				bannedModifiersRun.Add("Bomb");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowSwarmsArtifact.Value)
			{
				bannedModifiersRun.Add("Swarms");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowVengeanceArtifact.Value)
			{
				bannedModifiersRun.Add("ShadowClone");
			}
			if (!global::RiskOfRoutes.RiskOfRoutes.allowDeathArtifact.Value)
			{
				bannedModifiersRun.Add("TeamDeath");
			}
			StageModifierCatalog.CreateRunPools(global::RiskOfRoutes.RiskOfRoutes.printerItemPool.Value, global::RiskOfRoutes.RiskOfRoutes.lunarItemPool.Value, global::RiskOfRoutes.RiskOfRoutes.enemyItemPool.Value, global::RiskOfRoutes.RiskOfRoutes.canAppearWithAIBlacklisted.Value, global::RiskOfRoutes.RiskOfRoutes.enemyItemsAllowBoss.Value, global::RiskOfRoutes.RiskOfRoutes.enemyItemsAllowVoid.Value, bannedModifiersRun);
			List<string> list = (from s in global::RiskOfRoutes.RiskOfRoutes.tier1EnemyItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list2 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier2EnemyItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list3 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier3EnemyItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list4 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier1PrinterItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list5 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier2PrinterItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list6 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier3PrinterItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list7 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier1LunarItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list8 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier2LunarItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list9 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier3LunarItems.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list10 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier1Artifacts.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list11 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier2Artifacts.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			List<string> list12 = (from s in global::RiskOfRoutes.RiskOfRoutes.tier3Artifacts.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim()).ToList();
			foreach (string item in list)
			{
				StageModifierCatalog.TryRegEnemy(item, ModifierTier.Tier1, isAdditional: true);
				Log.Info(item + " registering as Tier1 enemy item");
			}
			foreach (string item2 in list2)
			{
				StageModifierCatalog.TryRegEnemy(item2, ModifierTier.Tier2, isAdditional: true);
				Log.Info(item2 + " registering as Tier2 enemy item");
			}
			foreach (string item3 in list3)
			{
				StageModifierCatalog.TryRegEnemy(item3, ModifierTier.Tier3, isAdditional: true);
				Log.Info(item3 + " registering as Tier3 enemy item");
			}
			foreach (string item4 in list4)
			{
				StageModifierCatalog.TryRegPrinter(item4, ModifierTier.Tier1, isAdditional: true);
				Log.Info(item4 + " registering as Tier1 printer item");
			}
			foreach (string item5 in list5)
			{
				StageModifierCatalog.TryRegPrinter(item5, ModifierTier.Tier2, isAdditional: true);
				Log.Info(item5 + " registering as Tier2 printer item");
			}
			foreach (string item6 in list6)
			{
				StageModifierCatalog.TryRegPrinter(item6, ModifierTier.Tier3, isAdditional: true);
				Log.Info(item6 + " registering as Tier3 printer item");
			}
			foreach (string item7 in list7)
			{
				StageModifierCatalog.TryRegLunar(item7, ModifierTier.Tier1, isAdditional: true);
				Log.Info(item7 + " registering as Tier1 lunar item");
			}
			foreach (string item8 in list8)
			{
				StageModifierCatalog.TryRegLunar(item8, ModifierTier.Tier2, isAdditional: true);
				Log.Info(item8 + " registering as Tier2 lunar item");
			}
			foreach (string item9 in list9)
			{
				StageModifierCatalog.TryRegLunar(item9, ModifierTier.Tier3, isAdditional: true);
				Log.Info(item9 + " registering as Tier3 lunar item");
			}
			foreach (string item10 in list10)
			{
				StageModifierCatalog.TryRegArtifact(new ArtifactInfo(item10, 1, isNegative: true), isAdditional: true);
				Log.Info(item10 + " registering as Tier1 artifact");
			}
			foreach (string item11 in list11)
			{
				StageModifierCatalog.TryRegArtifact(new ArtifactInfo(item11, 2, isNegative: true), isAdditional: true);
				Log.Info(item11 + " registering as Tier2 artifact");
			}
			foreach (string item12 in list12)
			{
				StageModifierCatalog.TryRegArtifact(new ArtifactInfo(item12, 3, isNegative: true), isAdditional: true);
				Log.Info(item12 + " registering as Tier3 artifact");
			}
		}

		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 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 is 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 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 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("Added " + current.cachedName);
				}
			}
			finally
			{
				((IDisposable)(RunEnabledArtifacts)(ref enumerator)).Dispose();
			}
			return list;
		}

		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;
			}
			Log.Info(reservedModifiers.Count);
			activeModifiers.Clear();
			bannedModifiersStage.Clear();
			Log.Info("Active");
			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")
				{
					NetworksoulCostStack = reservedModifier2.stack;
				}
			}
			foreach (StageModifier activeModifier in activeModifiers)
			{
				activeModifier.OnStart();
			}
			activePortalInstances.Clear();
			reservedModifiers.Clear();
			SceneDef sceneDefForCurrentScene = SceneCatalog.GetSceneDefForCurrentScene();
			stageEnterTime = Run.instance.GetRunStopwatch();
		}

		private void Stage_onServerStageComplete(Stage obj)
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Invalid comparison between Unknown and I4
			//IL_01a2: 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)
			{
				activeModifier.OnEnd();
			}
			activeModifiers.Clear();
			((SyncList<ModifierSync>)(object)modifiersSynced).Clear();
			Log.Info($"Modul:{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;
		}

		public void GetNextStageModifiers(GameObject portal)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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;
			}
			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))
			{
				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 (CheckPlayersHaveConsumedItems() && Run.instance.stageRng.nextNormalizedFloat > 0.8f && !bannedModifiersRun.Contains("Repair"))
			{
				dictionary.Add("Repair", 1);
			}
			Dictionary<ModifierTier, int> positive = modifierSlots.positive;
			foreach (KeyValuePair<ModifierTier, int> item in positive)
			{
				for (int i = 0; i < item.Value; i++)
				{
					List<string> pool = StageModifierCatalog.GetPool(component.routeNode.portalType);
					ModifierDef modifierDef = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, item.Key, pool);
					if (modifierDef == null)
					{
						continue;
					}
					hashSet.Add(modifierDef.name);
					if (modifierDef.conflictList != null)
					{
						foreach (string conflict in modifierDef.conflictList)
						{
							hashSet.Add(conflict);
						}
					}
					int num = CalculateStack(modifierDef, item.Key);
					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> item2 in negative)
			{
				for (int j = 0; j < item2.Value; j++)
				{
					List<string> pool2 = StageModifierCatalog.GetPool(component.routeNode.portalType, isNegative: true);
					ModifierDef modifierDef2 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, item2.Key, pool2);
					if (modifierDef2 == null)
					{
						continue;
					}
					hashSet.Add(modifierDef2.name);
					if (modifierDef2.conflictList != null)
					{
						foreach (string conflict2 in modifierDef2.conflictList)
						{
							hashSet.Add(conflict2);
						}
					}
					int num2 = CalculateStack(modifierDef2, item2.Key);
					if (dictionary.ContainsKey(modifierDef2.name))
					{
						dictionary[modifierDef2.name] += num2;
						continue;
					}
					dictionary.Add(modifierDef2.name, num2);
					list2.Add(modifierDef2);
				}
			}
			int num3 = (int)((Run.instance.GetRunStopwatch() - stageEnterTime) / (punishmentTime * 60f));
			num3 += commandAddedStack;
			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> pool3 = 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 modifierDef3 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, tier, pool3);
						while (modifierDef3 == null && num5 > 1)
						{
							num5--;
							tier = (ModifierTier)num5;
							modifierDef3 = StageModifierCatalog.SelectModifier(hashSet, component.routeNode.portalType, tier, pool3);
						}
						if (modifierDef3 == null)
						{
							Log.Warning("GetNextStageModifiers: Couldnt add new negative modifiers");
							break;
						}
						hashSet.Add(modifierDef3.name);
						if (modifierDef3.conflictList != null)
						{
							foreach (string conflict3 in modifierDef3.conflictList)
							{
								hashSet.Add(conflict3);
							}
						}
						num3 -= num5;
						int num6 = 0;
						if (num3 > 0 && modifierDef3.isStackable)
						{
							num6 = Run.instance.stageRng.RangeInt(0, num3 + 1);
							num3 -= num6;
						}
						dictionary.Add(modifierDef3.name, 1 + num6);
						Log.Info(string.Format("{0}: Punish added new modifier {1} with stack {2}", "GetNextStageModifiers", modifierDef3.name, 1 + num6));
					}
				}
				else
				{
					for (int k = 0; k < num3; k++)
					{
						ModifierDef modifierDef4 = Run.instance.stageRng.NextElementUniform<ModifierDef>(source.ToArray());
						if (dictionary.ContainsKey(modifierDef4.name))
						{
							dictionary[modifierDef4.name]++;
							Log.Info("GetNextStageModifiers: Added 1 additional stack to " + modifierDef4.name);
						}
					}
				}
			}
			List<ModifierSync> list3 = new List<ModifierSync>();
			foreach (KeyValuePair<string, int> item3 in dictionary)
			{
				ModifierDef modifierDef5 = StageModifierCatalog.FindModifier(item3.Key);
				if (modifierDef5 == null)
				{
					return;
				}
				list3.Add(new ModifierSync(modifierDef5, item3.Value));
			}
			((SyncList<string>)(object)component.stageModifiers).Clear();
			foreach (ModifierSync item4 in list3)
			{
				((SyncList<string>)(object)component.stageModifiers).Add($"{item4.name}={item4.stack}={item4.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 static 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,
						1
					} },
					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.3f);
			val.AddChoice(new ModifierSlotConfiguration
			{
				positive = { 
				{
					ModifierTier.Tier3,
					1
				} },
				negative = 
				{
					{
						ModifierTier.Tier2,
						1
					},
					{
						ModifierTier.Tier1,
						1
					}
				}
			}, 0.3f);
			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");
			}
			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 CheckPlayersHaveConsumedItems()
		{
			//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::CheckPlayersHaveConsumedItems()' 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 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_01fb: 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)soulCostStack);
				writer.Write(punishmentTime);
				writer.Write(purifyLunarItemModifier);
				writer.WritePackedUInt32((uint)doppelStackTime);
				writer.Write(modifiersCanBeBanned);
				writer.Write(enemyItemsModifierCanStack);
				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 & (true ? 1u : 0u)) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				GeneratedNetworkCode._WriteStructSyncListModifier_None(writer, modifiersSynced);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 2u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)mapWidth);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 4u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)mapHeight);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 8u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(isMoonVisited);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x10u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(currentNodeSync);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x20u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(syncedBaseCurse);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x40u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)soulCostStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x80u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(punishmentTime);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x100u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(purifyLunarItemModifier);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x200u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)doppelStackTime);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x400u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(modifiersCanBeBanned);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x800u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.Write(enemyItemsModifierCanStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x1000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)commonDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x2000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)uncommonDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x4000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)legendaryDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x8000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)bossDefaultStack);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x10000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)commonExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x20000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)uncommonExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x40000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)legendaryExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x80000u) != 0)
			{
				if (!flag)
				{
					writer.WritePackedUInt32(((NetworkBehaviour)this).syncVarDirtyBits);
					flag = true;
				}
				writer.WritePackedUInt32((uint)bossExtraRange);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 0x100000u) != 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_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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();
				soulCostStack = (int)reader.ReadPackedUInt32();
				punishmentTime = reader.ReadSingle();
				purifyLunarItemModifier = reader.ReadBoolean();
				doppelStackTime = (int)reader.ReadPackedUInt32();
				modifiersCanBeBanned = reader.ReadBoolean();
				enemyItemsModifierCanStack = 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 (((uint)num & (true ? 1u : 0u)) != 0)
			{
				GeneratedNetworkCode._ReadStructSyncListModifier_None(reader, modifiersSynced);
			}
			if (((uint)num & 2u) != 0)
			{
				mapWidth = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 4u) != 0)
			{
				mapHeight = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 8u) != 0)
			{
				isMoonVisited = reader.ReadBoolean();
			}
			if (((uint)num & 0x10u) != 0)
			{
				currentNodeSync = reader.ReadVector2();
			}
			if (((uint)num & 0x20u) != 0)
			{
				OnBaseCurseSyncedUpdate(reader.ReadSingle());
			}
			if (((uint)num & 0x40u) != 0)
			{
				soulCostStack = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x80u) != 0)
			{
				punishmentTime = reader.ReadSingle();
			}
			if (((uint)num & 0x100u) != 0)
			{
				purifyLunarItemModifier = reader.ReadBoolean();
			}
			if (((uint)num & 0x200u) != 0)
			{
				doppelStackTime = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x400u) != 0)
			{
				modifiersCanBeBanned = reader.ReadBoolean();
			}
			if (((uint)num & 0x800u) != 0)
			{
				enemyItemsModifierCanStack = reader.ReadBoolean();
			}
			if (((uint)num & 0x1000u) != 0)
			{
				commonDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x2000u) != 0)
			{
				uncommonDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x4000u) != 0)
			{
				legendaryDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x8000u) != 0)
			{
				bossDefaultStack = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x10000u) != 0)
			{
				commonExtraRange = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x20000u) != 0)
			{
				uncommonExtraRange = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x40000u) != 0)
			{
				legendaryExtraRange = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x80000u) != 0)
			{
				bossExtraRange = (int)reader.ReadPackedUInt32();
			}
			if (((uint)num & 0x100000u) != 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Invalid comparison between Unknown and I4
			int num = 0;
			int sceneDirectorInteractibleCredits = ClassicStageInfo.instance.sceneDirectorInteractibleCredits;
			float num2 = (float)global::RiskOfRoutes.RiskOfRoutes.droneStackPercent.Value / 100f;
			Log.Info($"Drone stack percent is {num2}");
			int num3 = (int)((float)(sceneDirectorInteractibleCredits * stack) * num2);
			Log.Info("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("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 num4 = 100;
			while (num3 > 0 && num4 > 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++;
				}
				num4--;
			}
			Log.Info($"Spawned {num} more drones");
		}

		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 = default(UniquePickup);
				val2.pickupIndex = pickupIndex;
				UniquePickup val3 = val2;
				component.SetPickup(val3, false);
			}
		}

		private void CreatePrinterSpawnCard()
		{
			//IL_0007: Unknown result type (might be due to invalid