Decompiled source of TombRush v0.2.2

TombRush.Common.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx.Logging;
using CommonAPI;
using Microsoft.CodeAnalysis;
using Reptile;
using TMPro;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("TombRush.Common")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+24336a7b08224e766f95663ec2787ccaa08773ad")]
[assembly: AssemblyProduct("TombRush.Common")]
[assembly: AssemblyTitle("TombRush.Common")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Winterland.Common
{
	public enum ShaderNames
	{
		AmbientCharacter,
		AmbientEnvironment,
		AmbientEnvironmentCutout,
		AmbientEnvironmentTransparent,
		AmbientEnvironmentGlass
	}
	public class MaterialReplacer : MonoBehaviour
	{
		public string NameOfMaterialToReplace;

		public Material ReplacementMaterial;

		public bool UseBRCShader;

		public ShaderNames BRCShaderName = ShaderNames.AmbientEnvironment;

		private void Start()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (UseBRCShader)
			{
				string name = Enum.GetName(typeof(ShaderNames), BRCShaderName);
				ShaderNames val = (ShaderNames)Enum.Parse(typeof(ShaderNames), name);
				ReplacementMaterial.shader = AssetAPI.GetShader(val);
			}
			Renderer[] array = Object.FindObjectsOfType<Renderer>();
			foreach (Renderer val2 in array)
			{
				if (!val2.sharedMaterials.Any((Material x) => (Object)(object)x != (Object)null && ((Object)x).name == NameOfMaterialToReplace))
				{
					continue;
				}
				Material[] array2 = (Material[])(object)new Material[val2.sharedMaterials.Length];
				for (int j = 0; j < val2.sharedMaterials.Length; j++)
				{
					Material val3 = val2.sharedMaterials[j];
					if ((Object)(object)val3 != (Object)null && ((Object)val3).name == NameOfMaterialToReplace)
					{
						array2[j] = ReplacementMaterial;
					}
					else
					{
						array2[j] = val3;
					}
				}
				val2.sharedMaterials = array2;
			}
		}
	}
}
namespace TombRush.Common
{
	public class AssetConstants
	{
		public const string PluginDirectoryName = "TombRush";

		public const string LuamodSourceDirectory = "Assets/lua";

		public const string LuamodFilename = "tombrush.luamod";

		public const string CoreAssetsDirectory = "Assets/core";

		public const string StageRootDirectory = "Assets/stage_additions";

		public const string CoreBundleName = "tombrush/core";

		public static readonly string CoreBundleFilename = ConvertBundleNameToFilename("tombrush/core");

		public const string StageBundleNamePrefix = "tombrush/stage_additions/";

		public const string CoreAssetsScriptableObjectPath = "Assets/core/TombRushCoreAssets.asset";

		public const string StageMaterialOverridesSubdirectory = "material_overrides";

		public static string GetStageDirectory(string stage)
		{
			return "Assets/stage_additions/" + stage;
		}

		public static string GetStageBundleName(string stage)
		{
			return "tombrush/stage_additions/" + stage;
		}

		public static string GetStageAssetsScriptableObjectPath(string stage)
		{
			return GetStageDirectory(stage) + "/" + stage + ".asset";
		}

		public static string GetStageBundleFilename(string stage)
		{
			return ConvertBundleNameToFilename(GetStageBundleName(stage));
		}

		public static string ConvertBundleNameToFilename(string name)
		{
			return name.Replace("/", ".");
		}
	}
	public static class GameObjectUtility
	{
		public static GameObject FindIncludingInactive(string path)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			int num = path.IndexOf("/");
			string text = path;
			string text2 = null;
			if (num > 0)
			{
				text = path.Substring(0, num);
				text2 = path.Substring(num + 1);
			}
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			foreach (GameObject val in rootGameObjects)
			{
				if (((Object)val).name == text)
				{
					if (text2 == null)
					{
						return val;
					}
					Transform val2 = val.transform.Find(text2);
					if ((Object)(object)val2 != (Object)null)
					{
						return ((Component)val2).gameObject;
					}
				}
			}
			return null;
		}

		public static T GetComponentInSceneIncludingInactive<T>() where T : Component
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			for (int i = 0; i < rootGameObjects.Length; i++)
			{
				T componentInChildren = rootGameObjects[i].GetComponentInChildren<T>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					return componentInChildren;
				}
			}
			return default(T);
		}
	}
	public static class Log
	{
		public static ManualLogSource Logger;

		public static void Info(string message)
		{
			Logger.LogInfo((object)message);
		}

		public static void Error(string message)
		{
			Logger.LogError((object)message);
		}

		public static void Warning(string message)
		{
			Logger.LogWarning((object)message);
		}

		public static void Debug(string message)
		{
		}
	}
	public static class RandomUtility
	{
		public static T Choose<T>(IList<T> list)
		{
			return list[Random.Range(0, list.Count)];
		}

		public static T Choose<T>(T[] list)
		{
			return list[Random.Range(0, list.Length)];
		}
	}
	public class SugarRushExplainerCutscene : MonoBehaviour
	{
	}
	[CreateAssetMenu(fileName = "TombRushSugarRushStats", menuName = "TombRush/SugarRushStats", order = 1)]
	public class SugarRushStats : ScriptableObject
	{
		public float MaxRushEffect = 1f;

		public float MaxRushMeter = 1f;

		public float PedestrianGrantsRush = 0.1f;

		public float CandycornGrantsRush = 0.05f;

		public float RushHoldDuration = 0.5f;

		public float RushDecayRate = 0.05f;

		public float RushVisualChangeRate = 1f;

		public float AnimationSpeedMultiplier = 1f;

		public float MovementSpeedMultiplier = 1f;

		public float MaxBaseRunSpeedIncrease = 3f;
	}
	internal class TimelineTriggerVolume : MonoBehaviour
	{
		public bool AllowTriggeringMultipleTimes;

		public PlayableDirector director;

		public GameObject[] activateTheseGameObjects;

		public GameObject[] deactivateTheseGameObjects;

		private bool triggered;

		private bool CanTrigger()
		{
			if (!AllowTriggeringMultipleTimes)
			{
				return !triggered;
			}
			return true;
		}

		private void OnTriggerEnter(Collider other)
		{
			if (CanTrigger() && ((Component)other).gameObject.layer == 9 && !((Object)(object)((Component)other).GetComponentInParent<Player>() != (Object)(object)WorldHandler.instance.GetCurrentPlayer()))
			{
				OnPlayerTouch();
			}
		}

		private void OnPlayerTouch()
		{
			if (!CanTrigger())
			{
				return;
			}
			triggered = true;
			if ((Object)(object)director != (Object)null)
			{
				director.Play();
			}
			if (activateTheseGameObjects != null)
			{
				GameObject[] array = activateTheseGameObjects;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].SetActive(true);
				}
			}
			if (deactivateTheseGameObjects != null)
			{
				GameObject[] array = deactivateTheseGameObjects;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].SetActive(false);
				}
			}
		}
	}
	[CreateAssetMenu(fileName = "TombRushCoreAssets", menuName = "TombRush/CoreAssets", order = 1)]
	public class TombRushCoreScriptableObject : ScriptableObject
	{
		public List<string> stages;

		public GameObject zombie;

		public GameObject explodeEffect;

		public GameObject crown;

		public GameObject hitSoundPrefab;

		public List<AudioClip> zombieSounds;

		public AnimationClip thrillerDance;

		public Material skybox;

		public GameObject tombRushUIPrefab;

		public TombRushPedestrianAdditions pedestrianAdditions;

		public SugarRushStats SugarRushStats;

		public int zombieHealth = 3;

		public float zombieInvincibilityTime = 0.25f;

		public float PedestriansRegainCandyWhenThisFarFromPlayer = 200f;

		public float ThisManyPedestriansPerSecondRegainCandy = 20f;
	}
	public class TombRushPedestrianAdditions : MonoBehaviour
	{
		public GameObject[] Masks;

		public GameObject[] CandyBags;

		public GameObject[] ParticleEffects;

		public string[] AttachMaskTo = new string[1] { "root/s1/s2/head" };

		public string[] AttachCandyBagTo = new string[1] { "root/s1/s2/shldl/arm1l/arm2l/handl" };
	}
	[CreateAssetMenu(fileName = "TombRushStageAssets", menuName = "TombRush/StageAssets", order = 1)]
	public class TombRushStageScriptableObject : ScriptableObject
	{
		public GameObject stageAdditionsPrefab;

		public List<Vector3> zombieSpawnLocations;

		public List<int> zombieQuantityPerSpawnLocation;

		public string zombieSpawnParentPath;

		public GameObject satellites;
	}
	public class SugarRushHUD : MonoBehaviour
	{
		public enum MeterStyle
		{
			EffectActive,
			EffectInactive
		}

		[SerializeField]
		private GameObject meterRoot;

		[SerializeField]
		private GameObject backgroundMeter;

		[SerializeField]
		private GameObject foregroundMeter;

		[SerializeField]
		private GameObject effectInactiveMeter;

		[SerializeField]
		private GameObject effectActiveMeter;

		[SerializeField]
		private GameObject effectClipMask;

		[SerializeField]
		private GameObject pedestrianCounterRoot;

		[SerializeField]
		private GameObject pedestrianCounterLabel;

		public bool Visible
		{
			get
			{
				return ((Component)this).gameObject.activeSelf;
			}
			set
			{
				if (value && !((Component)this).gameObject.activeSelf)
				{
					((Component)this).gameObject.SetActive(true);
				}
				else if (!value && ((Component)this).gameObject.activeSelf)
				{
					((Component)this).gameObject.SetActive(false);
				}
			}
		}

		public bool MeterVisible
		{
			get
			{
				return meterRoot.activeSelf;
			}
			set
			{
				if (value && !meterRoot.activeSelf)
				{
					meterRoot.SetActive(true);
				}
				else if (!value && meterRoot.activeSelf)
				{
					meterRoot.SetActive(false);
				}
			}
		}

		public bool PedestrianCounterVisible
		{
			get
			{
				return pedestrianCounterRoot.activeSelf;
			}
			set
			{
				if (value && !pedestrianCounterRoot.activeSelf)
				{
					pedestrianCounterRoot.SetActive(true);
				}
				else if (!value && pedestrianCounterRoot.activeSelf)
				{
					pedestrianCounterRoot.SetActive(false);
				}
			}
		}

		private void Awake()
		{
			MeterVisible = false;
			PedestrianCounterVisible = false;
		}

		public void SetMeterStyle(MeterStyle style)
		{
			switch (style)
			{
			case MeterStyle.EffectActive:
				effectActiveMeter.SetActive(true);
				effectInactiveMeter.SetActive(false);
				break;
			case MeterStyle.EffectInactive:
				effectActiveMeter.SetActive(false);
				effectInactiveMeter.SetActive(true);
				break;
			}
		}

		public void SetMeterValue(float value)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			effectActiveMeter.transform.localScale = new Vector3(value, 1f, 1f);
			effectInactiveMeter.transform.localScale = new Vector3(value, 1f, 1f);
		}

		public void SetPedestrianCounter(int currentAmount, int maxAmount)
		{
			((TMP_Text)pedestrianCounterLabel.GetComponent<TextMeshProUGUI>()).text = $"{currentAmount}/{maxAmount}";
		}
	}
	public class TombRushUI : MonoBehaviour
	{
		[SerializeField]
		public SugarRushHUD SugarRushHUD;

		public static TombRushUI Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Debug.LogError((object)"There is already an instance of TombRushUI in the scene.");
				Object.Destroy((Object)(object)this);
			}
			Instance = this;
		}

		private void OnDestroy()
		{
			Instance = null;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TombRush.Common";

		public const string PLUGIN_NAME = "TombRush.Common";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace TombRush.Common.Runtime
{
	public class Moon : MonoBehaviour
	{
		private Transform sun;

		private void Awake()
		{
			sun = ((Component)Object.FindObjectOfType<AmbientManager>()).transform;
		}

		private void Update()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Camera currentCamera = WorldHandler.instance.currentCamera;
			if (!((Object)(object)currentCamera == (Object)null))
			{
				((Component)this).transform.position = ((Component)currentCamera).transform.position;
				((Component)this).transform.rotation = Quaternion.LookRotation(-sun.forward);
			}
		}
	}
	public class SwirlSky : MonoBehaviour
	{
		public float BaseAlphaOfSwirl = 0.5f;

		public Texture2D Palette;

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			SwirlSkyUpdater val = Object.FindObjectOfType<SwirlSkyUpdater>();
			if (!((Object)(object)val == (Object)null))
			{
				Material val2 = new Material(val.swirlSkyMaterial);
				if ((Object)(object)Palette != (Object)null)
				{
					val2.mainTexture = (Texture)(object)Palette;
				}
				((Component)this).GetComponent<Renderer>().sharedMaterial = val2;
				((Component)this).gameObject.AddComponent<SwirlSkyUpdater>().baseAlphaOfSwirl = BaseAlphaOfSwirl;
			}
		}
	}
	public class VanillaMusicMute : MonoBehaviour
	{
		private void OnEnable()
		{
			Core.Instance.AudioManager.MuteMusic();
		}

		private void Update()
		{
			Core.Instance.AudioManager.MuteMusic();
		}

		private void OnDisable()
		{
			Core.Instance.AudioManager.UnMuteMusic();
		}
	}
	public class ZombieConfig : MonoBehaviour
	{
		public List<SkinnedMeshRenderer> heads;

		public List<SkinnedMeshRenderer> bodies;
	}
}
namespace TombRush.Common.Dependencies
{
	public class AssemblyDependencies
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

TombRush.Plugin.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CommonAPI;
using HarmonyLib;
using MapStation.Common;
using MapStation.Common.Doctor;
using Microsoft.CodeAnalysis;
using ProtoBuf;
using Reptile;
using TombRush.Common;
using TombRush.Common.Dependencies;
using TombRush.Common.Runtime;
using TombRush.Plugin;
using TombRush.Plugin.Dependencies;
using TombRush2023;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("TombRush.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("BepInEx Plugin Assembly for TombRush.")]
[assembly: AssemblyFileVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("0.0.0+f72d2f550b1df8b037608848a3cd4e74232208f5")]
[assembly: AssemblyProduct("TombRush.Plugin")]
[assembly: AssemblyTitle("TombRush.Plugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TombRush2023
{
	public class CoroutineHelper : MonoBehaviour
	{
		public int currentZombieAmount;

		public int totalSatelliteAmount;

		public int currentSatelliteAmount;

		public float timeOfFirstSatelliteDestruction;

		public void LoadScene()
		{
			currentZombieAmount = 0;
			currentSatelliteAmount = 13;
			Log.Debug("Making scene adjustments...");
			Transform[] componentsInChildren = Object.Instantiate<GameObject>(TombRushManager.Instance.currentStageAssets.ScriptableObject.satellites).GetComponentsInChildren<Transform>();
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name.Contains("Satellite"))
				{
					((Component)val).gameObject.AddComponent<Satellite>();
				}
			}
			try
			{
				Plugin2023.hitSoundObject = Object.Instantiate<GameObject>(Plugin2023.hitSoundPrefab, GameObject.Find("Player_HUMAN0").transform);
				Plugin2023.hitSoundSource = Plugin2023.hitSoundObject.GetComponent<AudioSource>();
				Plugin2023.hitSoundSource.outputAudioMixerGroup = Core.Instance.AudioManager.mixerGroups[3];
			}
			catch (Exception)
			{
			}
		}

		public void Test()
		{
			Plugin2023.isKing = true;
			((MonoBehaviour)this).StartCoroutine(AddCrown());
		}

		public IEnumerator AddCrown()
		{
			yield return (object)new WaitForSeconds(3f);
			try
			{
				if (!Plugin2023.isKing)
				{
					yield break;
				}
				bool flag = false;
				Transform[] componentsInChildren = GameObject.Find("Player_HUMAN0").GetComponentsInChildren<Transform>();
				foreach (Transform val in componentsInChildren)
				{
					if (!(((Object)val).name == "head"))
					{
						continue;
					}
					Transform[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Transform>();
					for (int j = 0; j < componentsInChildren2.Length; j++)
					{
						if (((Object)componentsInChildren2[j]).name.Contains("CrownProp"))
						{
							flag = true;
						}
					}
					if (!flag)
					{
						Object.Instantiate<GameObject>(Plugin2023.crown, val.position, GameObject.Find("Player_HUMAN0").transform.rotation, val);
					}
				}
			}
			catch (Exception)
			{
			}
		}

		public void DecreaseZombieCount(int amount)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			currentZombieAmount -= amount;
			if (currentZombieAmount <= 20 && currentSatelliteAmount > 0)
			{
				TombRushStageScriptableObject scriptableObject = TombRushManager.Instance.currentStageAssets.ScriptableObject;
				for (int i = 0; i < scriptableObject.zombieSpawnLocations.Count; i++)
				{
					Vector3 position = scriptableObject.zombieSpawnLocations[i];
					int amount2 = scriptableObject.zombieQuantityPerSpawnLocation[i];
					((MonoBehaviour)this).StartCoroutine(SpawnZombies(amount2, position, Plugin2023.characterShader));
				}
			}
			else if (currentZombieAmount <= 0 && currentSatelliteAmount <= 0)
			{
				Debug.Log((object)"All satellites and zombies defeated! YOU DID ITTTTTT");
				Plugin2023.isKing = true;
				((MonoBehaviour)this).StartCoroutine(AddCrown());
			}
			else
			{
				Debug.Log((object)(currentZombieAmount + " zombies remaining..."));
			}
		}

		public void DecreaseSatelliteCount(int amount)
		{
			if (currentSatelliteAmount == totalSatelliteAmount)
			{
				timeOfFirstSatelliteDestruction = Time.time;
			}
			currentSatelliteAmount -= amount;
			StageRecords records = SaveManager.Instance.Stage.Records;
			float newAttempt = Time.time - timeOfFirstSatelliteDestruction;
			if (currentSatelliteAmount <= 0 && currentZombieAmount > 0)
			{
				Debug.Log((object)"ALL SATELLITES DESTROYED. Zombies can no longer respawn!");
				records.TrySetNewRecordLowerIsBetter(ref records.FastestTimeToDestroyAllSatellites, newAttempt);
			}
			else if (currentSatelliteAmount <= 0 && currentZombieAmount <= 0)
			{
				Debug.Log((object)"All satellites and zombies defeated! YOU DID ITTTTTT");
				Plugin2023.isKing = true;
				SaveManager.Instance.Global.WonCrown = true;
				records.TrySetNewRecordLowerIsBetter(ref records.FastestTimeToBeatSatelliteChallenge, newAttempt);
				((MonoBehaviour)this).StartCoroutine(AddCrown());
			}
			else
			{
				Debug.Log((object)(currentSatelliteAmount + " satellites remaining..."));
			}
		}

		public IEnumerator SpawnZombies(int amount, Vector3 position, Shader characterShader)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			GameObject parent = GameObjectUtility.FindIncludingInactive(TombRushManager.Instance.currentStageAssets.ScriptableObject.zombieSpawnParentPath);
			int i = 0;
			while (i < amount)
			{
				GameObject obj = Object.Instantiate<GameObject>(Plugin2023.zombie, position, Quaternion.identity, parent.transform);
				ZombieConfig componentInChildren = obj.GetComponentInChildren<ZombieConfig>();
				obj.AddComponent<Zombie>();
				currentZombieAmount++;
				List<SkinnedMeshRenderer> heads = componentInChildren.heads;
				int num = Random.Range(0, heads.Count);
				for (int j = 0; j < heads.Count; j++)
				{
					SkinnedMeshRenderer val = heads[j];
					if (j != num)
					{
						Object.Destroy((Object)(object)val);
					}
					else
					{
						((Renderer)val).sharedMaterial.shader = characterShader;
					}
				}
				List<SkinnedMeshRenderer> bodies = componentInChildren.bodies;
				int num2 = Random.Range(0, bodies.Count);
				for (int k = 0; k < bodies.Count; k++)
				{
					SkinnedMeshRenderer val2 = bodies[k];
					if (k != num2)
					{
						Object.Destroy((Object)(object)val2);
					}
					else
					{
						((Renderer)val2).sharedMaterial.shader = characterShader;
					}
				}
				yield return (object)new WaitForSeconds(0.5f);
				int num3 = i + 1;
				i = num3;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "PlayAnim")]
	public class DancePatch
	{
		public static AnimatorOverrideController thrillerOverride;

		public static void Postfix(int newAnim, bool forceOverwrite, bool instant, float atTime, ref Player __instance)
		{
		}
	}
	public class DestroyOnTimer : MonoBehaviour
	{
		public float seconds = 5f;

		private void Start()
		{
			Object.Destroy((Object)(object)((Component)this).gameObject, seconds);
		}
	}
	internal class Plugin2023
	{
		public static Shader characterShader;

		public static GameObject hitSoundObject;

		public static AudioSource hitSoundSource;

		public static bool isKing = false;

		private static ManualLogSource Logger = Logger.CreateLogSource("TombRush2023");

		public static GameObject zombie => Core.zombie;

		public static GameObject explodeEffect => Core.explodeEffect;

		public static GameObject crown => Core.crown;

		public static GameObject hitSoundPrefab => Core.hitSoundPrefab;

		public static List<AudioClip> zombieSounds => Core.zombieSounds;

		public static AnimationClip thrillerDance => Core.thrillerDance;

		public static TombRushCoreScriptableObject Core => TombRushAssets.Instance.CoreAssets;

		public static AssetBundle bundle => TombRushAssets.Instance.CoreBundle;
	}
	public class Satellite : MonoBehaviour
	{
		private int health = 2;

		private bool dead;

		private void Awake()
		{
			AudioSource component = ((Component)this).GetComponent<AudioSource>();
			if ((Object)(object)component != (Object)null)
			{
				component.outputAudioMixerGroup = Core.Instance.AudioManager.mixerGroups[3];
			}
		}

		private void DoExplodeEffect()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(Plugin2023.explodeEffect, ((Component)this).transform.position + Vector3.up, ((Component)this).transform.rotation);
			obj.AddComponent<DestroyOnTimer>();
			AudioSource component = obj.GetComponent<AudioSource>();
			component.volume = 1f;
			component.outputAudioMixerGroup = Core.Instance.AudioManager.mixerGroups[3];
		}

		private void OnTriggerEnter(Collider other)
		{
			if (((Object)other).name == "autoAimCheck")
			{
				health--;
				if (health <= 0 && !dead)
				{
					dead = true;
					Object.FindObjectOfType<CoroutineHelper>().DecreaseSatelliteCount(1);
					DoExplodeEffect();
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				else
				{
					DoExplodeEffect();
				}
			}
		}
	}
	public class Zombie : MonoBehaviour
	{
		private enum States
		{
			Normal,
			Hit,
			Dead
		}

		private int health = TombRushAssets.Instance.CoreAssets.zombieHealth;

		public float InvincibilityTime = TombRushAssets.Instance.CoreAssets.zombieInvincibilityTime;

		public Transform targetedPlayer;

		private Rigidbody rb;

		private float speed;

		private Vector3 lookPos;

		private Animator animator;

		private bool dead;

		private bool stopped;

		private AudioSource audio;

		private States currentState;

		private Collider collider;

		private float timer;

		private float targetTime;

		private Vector3 velocityOnPause = Vector3.zero;

		private float invincibilityTimer;

		private void Start()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			ResetTargetTime();
			collider = ((Component)this).GetComponent<Collider>();
			audio = ((Component)this).GetComponent<AudioSource>();
			audio.outputAudioMixerGroup = Core.Instance.AudioManager.mixerGroups[3];
			audio.pitch = Random.Range(0.7f, 1.1f);
			Core.OnUpdate += new OnUpdateHandler(OnUpdate);
			Core.OnFixedUpdate += new OnFixedUpdateHandler(OnFixedUpdate);
			Core.OnCoreUpdatePaused += new OnCoreUpdateHandler(OnPause);
			Core.OnCoreUpdateUnPaused += new OnCoreUpdateUnpausedHandler(OnUnpause);
		}

		private void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			Core.OnUpdate -= new OnUpdateHandler(OnUpdate);
			Core.OnFixedUpdate -= new OnFixedUpdateHandler(OnFixedUpdate);
			Core.OnCoreUpdatePaused -= new OnCoreUpdateHandler(OnPause);
			Core.OnCoreUpdateUnPaused -= new OnCoreUpdateUnpausedHandler(OnUnpause);
		}

		private void OnEnable()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			rb = ((Component)this).GetComponent<Rigidbody>();
			rb.velocity = Vector3.zero;
			speed = Random.Range(0.3f, 1f);
			animator = ((Component)this).GetComponent<Animator>();
			animator.speed = speed * 2.5f;
			lookPos = new Vector3(0f, ((Component)this).transform.position.y, 0f);
		}

		private void OnPause()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			velocityOnPause = rb.velocity;
			rb.isKinematic = true;
			animator.speed = 0f;
		}

		private void OnUnpause()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			rb.isKinematic = false;
			animator.speed = 1f;
			rb.velocity = velocityOnPause;
		}

		private bool PlayerBusy()
		{
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			if (currentPlayer.IsBusyWithSequence())
			{
				return true;
			}
			if (currentPlayer.ability is CharacterSelectAbility)
			{
				return true;
			}
			return false;
		}

		private void OnUpdate()
		{
			//IL_007d: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerBusy())
			{
				return;
			}
			invincibilityTimer -= Core.dt;
			currentState = States.Normal;
			if (dead)
			{
				currentState = States.Dead;
			}
			if (animator.GetCurrentStateName(0) == "Hit")
			{
				currentState = States.Hit;
			}
			UpdateTimer();
			if ((Object)(object)targetedPlayer != (Object)null)
			{
				if (!dead && !stopped)
				{
					Vector3 val = default(Vector3);
					((Vector3)(ref val))..ctor(targetedPlayer.position.x, ((Component)this).transform.position.y, targetedPlayer.position.z);
					lookPos = Vector3.MoveTowards(lookPos, val, 10f);
					((Component)this).transform.LookAt(lookPos);
				}
			}
			else
			{
				targetedPlayer = ((Component)WorldHandler.instance.GetCurrentPlayer()).transform;
			}
		}

		private void OnFixedUpdate()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (!PlayerBusy() && !dead && !stopped)
			{
				Vector3 val = rb.position + ((Component)this).transform.forward * Time.deltaTime * speed;
				rb.MovePosition(val);
				if ((double)val.y < -200.0)
				{
					Object.FindObjectOfType<CoroutineHelper>().DecreaseZombieCount(1);
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
		}

		private void Die()
		{
			Physics.IgnoreCollision(collider, ((Component)WorldHandler.instance.GetCurrentPlayer()).GetComponent<Collider>());
			animator.SetBool("Dead", true);
			animator.Play("Death");
			dead = true;
			if (Random.Range(0, 10) > 7)
			{
				int index = Random.Range(0, Plugin2023.zombieSounds.Count);
				audio.clip = Plugin2023.zombieSounds[index];
				audio.Play();
			}
			timer = 0f;
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (collision.gameObject.layer != 21)
			{
				return;
			}
			Junk component = collision.gameObject.GetComponent<Junk>();
			if (!((Object)(object)component == (Object)null))
			{
				Vector3 velocity = component.rigidBody.velocity;
				if (((Vector3)(ref velocity)).magnitude >= 6f && !component.rigidBody.isKinematic)
				{
					Core.Instance.AudioManager.PlaySfxGameplay(component.audioClips, WorldHandler.instance.GetSpatialAudioSource(((Component)component).transform.position), 0f);
					Die();
				}
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (invincibilityTimer > 0f || currentState == States.Dead || ((Component)other).gameObject.layer != 18 || (Object)(object)((Component)other).GetComponentInParent<Player>() != (Object)(object)WorldHandler.instance.GetCurrentPlayer())
			{
				return;
			}
			if ((Object)(object)Plugin2023.hitSoundSource != (Object)null && !Plugin2023.hitSoundSource.isPlaying)
			{
				Plugin2023.hitSoundSource.pitch = Random.Range(0.7f, 1.2f);
				Plugin2023.hitSoundSource.Play();
			}
			rb.AddForce((((Component)this).transform.up + -((Component)this).transform.forward) * 5f, (ForceMode)1);
			health--;
			if (health <= 0 && !dead)
			{
				Die();
			}
			else if (!dead)
			{
				invincibilityTimer = InvincibilityTime;
				animator.Play("Hurt", 0, 0f);
				if (Random.Range(0, 10) > 7)
				{
					int index = Random.Range(0, Plugin2023.zombieSounds.Count);
					audio.clip = Plugin2023.zombieSounds[index];
					audio.Play();
				}
			}
		}

		private void ResetTargetTime()
		{
			targetTime = Random.Range(3f, 10f);
		}

		private void UpdateTimer()
		{
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			if (currentState == States.Hit)
			{
				return;
			}
			timer += Core.dt;
			if (currentState == States.Dead)
			{
				if (timer >= 3f)
				{
					Object.FindObjectOfType<CoroutineHelper>().DecreaseZombieCount(1);
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
			else
			{
				if (!(timer >= targetTime))
				{
					return;
				}
				timer = 0f;
				stopped = false;
				ResetTargetTime();
				if (Random.Range(0, 10) >= 7)
				{
					if (!dead)
					{
						if (Random.Range(0, 10) > 7)
						{
							int index = Random.Range(0, Plugin2023.zombieSounds.Count);
							audio.clip = Plugin2023.zombieSounds[index];
							audio.Play();
						}
						animator.Play("Idle");
						stopped = true;
					}
				}
				else
				{
					if (!((Object)(object)targetedPlayer != (Object)null))
					{
						return;
					}
					if ((double)Vector3.Distance(((Component)this).transform.position, ((Component)targetedPlayer).transform.position) <= 2.0)
					{
						if (!dead)
						{
							animator.Play("Hit");
							((Component)targetedPlayer).GetComponent<Player>().GetHit(1, -((Component)this).transform.forward, (KnockbackType)3);
							if (Random.Range(0, 10) > 5)
							{
								int index2 = Random.Range(0, Plugin2023.zombieSounds.Count);
								audio.clip = Plugin2023.zombieSounds[index2];
								audio.Play();
							}
						}
					}
					else if (Random.Range(0, 10) > 5)
					{
						rb.AddForce((((Component)this).transform.up + ((Component)this).transform.forward) * 5f, (ForceMode)1);
					}
				}
			}
		}
	}
}
namespace TombRush.Plugin
{
	public class LocalProgress
	{
		private const byte Version = 4;

		private string savePath;

		public LocalProgress()
		{
			InitializeNew();
		}

		public void InitializeNew()
		{
			savePath = Path.Combine(Paths.ConfigPath, "TombRush/localprogress.mwp");
		}

		public void Save()
		{
			using MemoryStream memoryStream = new MemoryStream();
			using (BinaryWriter writer = new BinaryWriter(memoryStream))
			{
				Write(writer);
			}
			CustomStorage.Instance.WriteFile(memoryStream.ToArray(), savePath);
		}

		public void Load()
		{
			if (!File.Exists(savePath))
			{
				Debug.Log((object)"No TombRush save to load, starting a new game.");
				return;
			}
			using FileStream input = File.Open(savePath, FileMode.Open);
			using BinaryReader reader = new BinaryReader(input);
			try
			{
				Read(reader);
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"Failed to load TombRush save!{Environment.NewLine}{arg}");
			}
		}

		private void Write(BinaryWriter writer)
		{
			writer.Write((byte)4);
		}

		private void Read(BinaryReader reader)
		{
			byte b = reader.ReadByte();
			if (b > 4)
			{
				Debug.LogError((object)$"Attemped to read a TombRush save that's too new (version {b}), current version is {(byte)4}.");
			}
			else
			{
				reader.ReadString();
			}
		}
	}
	[BepInPlugin("TombRush.Plugin", "TombRush.Plugin", "0.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public delegate void UpdateDelegate();

		public static Plugin Instance;

		private static Type ForceLoadTombRushCommonAssembly = typeof(AssemblyDependencies);

		private static Type ForceLoadTombRushPluginAssembly = typeof(AssemblyDependencies);

		public bool ConflictingMovementModsInstalled;

		public static UpdateDelegate UpdateEvent;

		public static UpdateDelegate LateUpdateEvent;

		public Plugin()
		{
			Log.Logger = ((BaseUnityPlugin)this).Logger;
		}

		private void Awake()
		{
			Instance = this;
			try
			{
				Initialize();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin TombRush.Plugin 0.0.0 is loaded!");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("Plugin {0} {1} failed to load!{2}{3}", "TombRush.Plugin", "0.0.0", Environment.NewLine, ex));
			}
		}

		private void Initialize()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			new TombRushConfig(((BaseUnityPlugin)this).Config);
			string? directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			new Harmony("TombRush.Plugin").PatchAll();
			new TombRushAssets(directoryName);
			new SaveManager();
			bool conflictingMovementModsInstalled = Chainloader.PluginInfos.Keys.Any((string x) => x == "com.yuril.MovementPlus");
			ConflictingMovementModsInstalled = conflictingMovementModsInstalled;
			if (ConflictingMovementModsInstalled)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Disabled movement effects because conflicting movement mods are enabled.");
			}
			StageAPI.OnStagePreInitialization = (StageInitializationDelegate)Delegate.Combine((Delegate?)(object)StageAPI.OnStagePreInitialization, (Delegate?)new StageInitializationDelegate(StageAPI_OnStagePreInitialization));
		}

		private void StageAPI_OnStagePreInitialization(Stage newStage, Stage previousStage)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			TombRushManager.Create().SetupStage(newStage);
		}

		private void Update()
		{
			UpdateEvent?.Invoke();
		}

		private void LateUpdate()
		{
			LateUpdateEvent?.Invoke();
		}
	}
	public class SaveManager
	{
		private readonly GlobalSaveFile globalSaveFile;

		public static SaveManager Instance { get; private set; }

		public GlobalSaveData Global => globalSaveFile.Data;

		public StageSaveData Stage => GetStage(Utility.GetCurrentStage());

		public StageSaveData GetStage(Stage stage)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Stage, StageSaveData> stages = globalSaveFile.Data.Stages;
			if (stages.TryGetValue(stage, out var value))
			{
				return value;
			}
			value = new StageSaveData();
			value.Stage = stage;
			stages.Add(stage, value);
			return value;
		}

		public SaveManager()
		{
			if (Instance != null)
			{
				throw new InvalidOperationException("There is already an instance of SaveManager.");
			}
			Instance = this;
			globalSaveFile = new GlobalSaveFile();
			SaveAPI.RegisterCustomSaveData((CustomSaveData)(object)globalSaveFile);
		}
	}
	public abstract class SaveData<T> : CustomSaveData
	{
		public T Data { get; protected set; }

		protected SaveData(string filename)
			: base("TombRush2024", filename)
		{
		}

		public override void Read(BinaryReader reader)
		{
			try
			{
				Data = Serializer.Deserialize<T>(reader.BaseStream);
			}
			catch (Exception)
			{
				base.FailedToLoad = true;
			}
		}

		public override void Write(BinaryWriter writer)
		{
			Serializer.Serialize<T>(writer.BaseStream, Data);
		}
	}
	public class GlobalSaveFile : SaveData<GlobalSaveData>
	{
		public GlobalSaveFile()
			: base("slot{0}_globalprogress.trp")
		{
		}

		public override void Initialize()
		{
			base.Data = new GlobalSaveData();
		}
	}
	[ProtoContract]
	public class GlobalSaveData
	{
		[ProtoMember(1)]
		public bool SugarRushExplained;

		[ProtoMember(2)]
		public bool ZombiesEnabled = true;

		[ProtoMember(3)]
		public bool WonCrown;

		[ProtoMember(4)]
		public GlobalRecords Records = new GlobalRecords();

		[ProtoMember(5)]
		public readonly Dictionary<Stage, StageSaveData> Stages = new Dictionary<Stage, StageSaveData>();
	}
	[ProtoContract]
	public class GlobalRecords
	{
		[ProtoMember(1)]
		public int TotalPedestriansScared;

		[ProtoMember(2)]
		public float TotalCandyCollected;
	}
	[ProtoContract]
	public class StageSaveData
	{
		[ProtoMember(2)]
		public Stage Stage;

		[ProtoMember(1)]
		public StageRecords Records = new StageRecords();
	}
	[ProtoContract]
	public class StageRecords
	{
		[ProtoMember(1)]
		public float FastestTimeTo50PedestriansInSingleCombo = -1f;

		[ProtoMember(2)]
		public float FastestTimeTo100PedestriansInSingleCombo = -1f;

		[ProtoMember(3)]
		public float FastestTimeTo200PedestriansInSingleCombo = -1f;

		[ProtoMember(4)]
		public int MaxPedestriansInSingleCombo = -1;

		[ProtoMember(5)]
		public float MaxTimeWith100PercentRush = -1f;

		[ProtoMember(6)]
		public float FastestTimeTo50TrickCombo = -1f;

		[ProtoMember(7)]
		public float FastestTimeTo100TrickCombo = -1f;

		[ProtoMember(8)]
		public float FastestTimeTo200TrickCombo = -1f;

		[ProtoMember(9)]
		public float FastestTimeToDestroyAllSatellites = -1f;

		[ProtoMember(10)]
		public float FastestTimeToBeatSatelliteChallenge = -1f;

		[ProtoMember(11)]
		public int TotalPedestriansScaredThisStage;

		[ProtoMember(12)]
		public float TotalCandyCollectedThisStage;

		public bool TrySetNewRecordLowerIsBetter(ref float record, float newAttempt)
		{
			if (record < 0f)
			{
				record = newAttempt;
				return true;
			}
			if (newAttempt < record)
			{
				record = newAttempt;
				return true;
			}
			return false;
		}

		public bool TrySetNewRecordHigherIsBetter(ref int record, int newAttempt)
		{
			if (record < 0)
			{
				record = newAttempt;
				return true;
			}
			if (newAttempt > record)
			{
				record = newAttempt;
				return true;
			}
			return false;
		}

		public bool TrySetNewRecordHigherIsBetter(ref float record, float newAttempt)
		{
			if (record < 0f)
			{
				record = newAttempt;
				return true;
			}
			if (newAttempt > record)
			{
				record = newAttempt;
				return true;
			}
			return false;
		}
	}
	public class SugarRushManager : MonoBehaviour
	{
		private TombRushPedestrian[] pedestrians;

		private HashSet<TombRushPedestrian> pedestriansWithCandy = new HashSet<TombRushPedestrian>();

		private List<TombRushPedestrian> pedestriansWithoutCandy = new List<TombRushPedestrian>();

		private Coroutine sugarRushExplainerCoroutine;

		private bool SugarExplaining;

		public static SugarRushManager Instance { get; private set; }

		public bool SugarExplained
		{
			get
			{
				return SaveManager.Instance.Global.SugarRushExplained;
			}
			set
			{
				SaveManager.Instance.Global.SugarRushExplained = value;
			}
		}

		public void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			List<TombRushPedestrian> list = new List<TombRushPedestrian>();
			if ((int)Utility.GetCurrentStage() == 4 || SugarExplained)
			{
				Scene activeScene = SceneManager.GetActiveScene();
				GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
				for (int i = 0; i < rootGameObjects.Length; i++)
				{
					Pedestrian[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<Pedestrian>(true);
					foreach (Pedestrian val in componentsInChildren)
					{
						list.Add(((Component)val).gameObject.AddComponent<TombRushPedestrian>());
					}
				}
			}
			pedestrians = list.ToArray();
			foreach (TombRushPedestrian item in list)
			{
				pedestriansWithCandy.Add(item);
			}
			sugarRushExplainerCoroutine = ((MonoBehaviour)this).StartCoroutine(RespawnCandyCoroutine());
		}

		public void TombRushInitialize()
		{
			TombRushUI.Instance.SugarRushHUD.MeterVisible = SugarExplained;
		}

		public void OnDestroy()
		{
			if (sugarRushExplainerCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(sugarRushExplainerCoroutine);
			}
		}

		public bool CanExplainSugarRush(TombRushPedestrian pedestrian)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if (!SugarExplaining)
			{
				return (int)Utility.GetCurrentStage() == 4;
			}
			return false;
		}

		public Coroutine ExplainSugarRush(TombRushPedestrian pedestrian)
		{
			return ((MonoBehaviour)this).StartCoroutine(ExplainSugarRushCoroutine(pedestrian));
		}

		private IEnumerator ExplainSugarRushCoroutine(TombRushPedestrian pedestrian)
		{
			SugarExplaining = true;
			Debug.Log((object)"This where we trigger candy explainer cutscene");
			yield return (object)new WaitForSeconds(0.2f);
			SugarRushExplainerCutscene componentInSceneIncludingInactive = GameObjectUtility.GetComponentInSceneIncludingInactive<SugarRushExplainerCutscene>();
			if ((Object)(object)componentInSceneIncludingInactive == (Object)null)
			{
				Debug.LogError((object)"No SugarRushExplainerCutscene found in scene. We should add it to SceneDeco");
			}
			else
			{
				((Component)componentInSceneIncludingInactive).gameObject.SetActive(true);
				((Component)componentInSceneIncludingInactive).transform.position = ((Component)pedestrian).transform.position;
				((Component)componentInSceneIncludingInactive).transform.rotation = ((Component)pedestrian).transform.rotation;
			}
			SugarExplained = true;
			TombRushUI.Instance.SugarRushHUD.MeterVisible = true;
		}

		private IEnumerator RespawnCandyCoroutine()
		{
			while (true)
			{
				yield return (object)new WaitForSeconds(1f / TombRushAssets.Instance.CoreAssets.ThisManyPedestriansPerSecondRegainCandy);
				Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
				if ((Object)(object)currentPlayer == (Object)null || PlayerIsComboing())
				{
					continue;
				}
				foreach (TombRushPedestrian item in pedestriansWithoutCandy)
				{
					if (Vector3.Distance(((Component)currentPlayer).transform.position, ((Component)item).transform.position) > TombRushAssets.Instance.CoreAssets.PedestriansRegainCandyWhenThisFarFromPlayer)
					{
						item.ResetCandy();
						break;
					}
				}
			}
		}

		private bool PlayerIsComboing()
		{
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			if ((Object)(object)currentPlayer == (Object)null)
			{
				return false;
			}
			if (!currentPlayer.IsComboing())
			{
				return currentPlayer.ability is AirTrickAbility;
			}
			return true;
		}

		public void NotifyPedestrianHasCandy(TombRushPedestrian pedestrian, bool hasCandy)
		{
			if (hasCandy)
			{
				pedestriansWithCandy.Add(pedestrian);
				pedestriansWithoutCandy.Remove(pedestrian);
			}
			else
			{
				pedestriansWithCandy.Remove(pedestrian);
				pedestriansWithoutCandy.Add(pedestrian);
			}
		}
	}
	public class TombRushAssets
	{
		private readonly Dictionary<string, TombRushStageAssets> assetsByStageName;

		public AssetBundle CoreBundle;

		public TombRushCoreScriptableObject CoreAssets;

		private string folder;

		public static TombRushAssets Instance { get; private set; }

		public TombRushAssets(string folder)
		{
			Instance = this;
			assetsByStageName = new Dictionary<string, TombRushStageAssets>();
			this.folder = folder;
			LoadBundles();
		}

		private void LoadBundles()
		{
			string text = Path.Combine(folder, AssetConstants.CoreBundleFilename);
			CoreBundle = AssetBundle.LoadFromFile(text);
			CoreAssets = CoreBundle.LoadAsset<TombRushCoreScriptableObject>("Assets/core/TombRushCoreAssets.asset");
			foreach (string stage in CoreAssets.stages)
			{
				AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(folder, AssetConstants.GetStageBundleFilename(stage)));
				TombRushStageScriptableObject val2 = val.LoadAsset<TombRushStageScriptableObject>(AssetConstants.GetStageAssetsScriptableObjectPath(stage));
				Debug.Log((object)$"Found bundle {val} for stage {stage}");
				Debug.Log((object)("Found scriptable object " + (object)val2));
				assetsByStageName[stage] = new TombRushStageAssets
				{
					Bundle = val,
					ScriptableObject = val2
				};
			}
		}

		public TombRushStageAssets GetAssetsForStage(Stage stage)
		{
			string key = ((object)(Stage)(ref stage)).ToString().ToLowerInvariant();
			assetsByStageName.TryGetValue(key, out var value);
			return value;
		}

		public GameObject GetPrefabForStage(Stage stage)
		{
			string key = ((object)(Stage)(ref stage)).ToString().ToLowerInvariant();
			if (!assetsByStageName.TryGetValue(key, out var value))
			{
				return null;
			}
			return value.ScriptableObject.stageAdditionsPrefab;
		}

		public void ReloadBundles()
		{
			UnloadBundles();
			LoadBundles();
		}

		private void UnloadBundles()
		{
			AssetBundle coreBundle = CoreBundle;
			if (coreBundle != null)
			{
				coreBundle.Unload(false);
			}
			CoreBundle = null;
			foreach (KeyValuePair<string, TombRushStageAssets> item in assetsByStageName)
			{
				item.Value.Bundle.Unload(false);
			}
			assetsByStageName.Clear();
		}
	}
	public class TombRushStageAssets
	{
		public AssetBundle Bundle;

		public TombRushStageScriptableObject ScriptableObject;
	}
	public class TombRushConfig
	{
		public ConfigEntry<bool> ThisIsAConfigFlag;

		public static TombRushConfig Instance { get; private set; }

		public bool ThisIsAConfigFlagValue => ThisIsAConfigFlag.Value;

		public TombRushConfig()
		{
			Instance = this;
		}

		public TombRushConfig(ConfigFile file)
			: this()
		{
			string text = "General";
			ThisIsAConfigFlag = file.Bind<bool>(text, "ThisIsAFlag", false, "Enable emotive Tryce mode.");
		}
	}
	public class TombRushManager : MonoBehaviour
	{
		public GameObject stageAdditions;

		public static TombRushManager Instance { get; private set; }

		public Stage currentStage { get; private set; }

		public TombRushStageAssets currentStageAssets => TombRushAssets.Instance.GetAssetsForStage(currentStage);

		public static TombRushManager Create()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TombRush Manager");
			TombRushManager result = val.AddComponent<TombRushManager>();
			val.AddComponent<SugarRushManager>();
			return result;
		}

		public void SetupStage(Stage stage)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			currentStage = stage;
			GameObject prefabForStage = TombRushAssets.Instance.GetPrefabForStage(stage);
			if (!((Object)(object)prefabForStage == (Object)null))
			{
				stageAdditions = Object.Instantiate<GameObject>(prefabForStage);
				SugarRushExplainerCutscene componentInChildren = stageAdditions.GetComponentInChildren<SugarRushExplainerCutscene>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((Component)componentInChildren).gameObject.SetActive(true);
				}
				StageObject[] componentsInChildren = stageAdditions.GetComponentsInChildren<StageObject>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].PutInChunk();
				}
			}
		}

		private void SetupUI()
		{
			GameObject tombRushUIPrefab = TombRushAssets.Instance.CoreAssets.tombRushUIPrefab;
			if (!((Object)(object)tombRushUIPrefab == (Object)null))
			{
				GameObject obj = Object.Instantiate<GameObject>(tombRushUIPrefab);
				Transform val = ((Component)Core.Instance.UIManager).transform.Find("GamePlayUI(Clone)").Find("GameplayUI").Find("gameplayUIScreen");
				obj.transform.SetParent(val, false);
			}
		}

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Instance = this;
			LightmapSettings.lightmaps = (LightmapData[])(object)new LightmapData[0];
			QualitySettings.shadowDistance = 150f;
			StageManager.OnStagePostInitialization += new OnStageInitializedDelegate(StageManager_OnStagePostInitialization);
		}

		private void OnDestroy()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			Instance = null;
			StageManager.OnStagePostInitialization -= new OnStageInitializedDelegate(StageManager_OnStagePostInitialization);
		}

		private void StageManager_OnStagePostInitialization()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			SetupUI();
			if ((int)Utility.GetCurrentStage() == 4)
			{
				SetupTombRush();
			}
			SugarRushManager.Instance.TombRushInitialize();
		}

		private void SetupTombRush()
		{
			//IL_0005: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			CoroutineHelper coroutineHelper = new GameObject("SceneController").AddComponent<CoroutineHelper>();
			coroutineHelper.LoadScene();
			Plugin2023.characterShader = ((Renderer)GameObject.Find("meshLank1").GetComponent<SkinnedMeshRenderer>()).sharedMaterial.shader;
			Vector3 position = default(Vector3);
			((Vector3)(ref position))..ctor(327.7377f, -1.6446f, -80.3011f);
			Vector3 position2 = default(Vector3);
			((Vector3)(ref position2))..ctor(280.0308f, -5.4126f, -2.5014f);
			Vector3 position3 = default(Vector3);
			((Vector3)(ref position3))..ctor(373.2899f, -8.8528f, -41.7996f);
			((MonoBehaviour)coroutineHelper).StartCoroutine(coroutineHelper.SpawnZombies(20, position, Plugin2023.characterShader));
			((MonoBehaviour)coroutineHelper).StartCoroutine(coroutineHelper.SpawnZombies(40, position2, Plugin2023.characterShader));
			((MonoBehaviour)coroutineHelper).StartCoroutine(coroutineHelper.SpawnZombies(30, position3, Plugin2023.characterShader));
			ChangeSkybox();
			AddPrefabs();
			((Component)((Component)Object.FindObjectOfType<AmbientManager>(true)).transform.Find("SunSprite")).gameObject.SetActive(false);
		}

		private void AddPrefabs()
		{
			Texture2D[] array = Plugin2023.bundle.LoadAllAssets<Texture2D>();
			MeshRenderer[] componentsInChildren = GameObjectUtility.FindIncludingInactive("stageChunks/openHill").GetComponentsInChildren<MeshRenderer>(true);
			int num = 0;
			MeshRenderer[] array2 = componentsInChildren;
			foreach (MeshRenderer val in array2)
			{
				if (!((Object)((Component)val).gameObject).name.Contains("CombinedMeshes"))
				{
					continue;
				}
				Texture mainTexture = ((Renderer)val).sharedMaterial.mainTexture;
				Texture2D[] array3 = array;
				foreach (Texture2D val2 in array3)
				{
					if (((Object)val2).name.Contains(((Object)mainTexture).name))
					{
						((Renderer)val).sharedMaterial.SetTexture("_MainTex", (Texture)(object)val2);
						_ = ((Renderer)val).sharedMaterial.shader;
						num++;
					}
				}
			}
		}

		private void ChangeSkybox()
		{
			RenderSettings.skybox = TombRushAssets.Instance.CoreAssets.skybox;
		}
	}
	public class TombRushPedestrian : MonoBehaviour
	{
		[SerializeField]
		private GameObject candyBag;

		[SerializeField]
		private GameObject mask;

		[SerializeField]
		private GameObject particleEffectGo;

		private ParticleSystem particleEffect;

		private Pedestrian pedestrian;

		private Transform head;

		private Transform handl;

		public bool HasCandy { get; private set; } = true;


		private void Awake()
		{
			pedestrian = ((Component)this).GetComponent<Pedestrian>();
			TombRushPedestrianAdditions pedestrianAdditions = TombRushAssets.Instance.CoreAssets.pedestrianAdditions;
			string text = pedestrianAdditions.AttachMaskTo[Random.Range(0, pedestrianAdditions.AttachMaskTo.Length)];
			string text2 = pedestrianAdditions.AttachCandyBagTo[Random.Range(0, pedestrianAdditions.AttachCandyBagTo.Length)];
			head = ((Component)pedestrian).transform.Find(text);
			if ((Object)(object)head == (Object)null)
			{
				Debug.LogError((object)"Pedestrian has no head!");
			}
			handl = ((Component)pedestrian).transform.Find(text2);
			if ((Object)(object)handl == (Object)null)
			{
				Debug.LogError((object)"Pedestrian has no hand!");
			}
			mask = Object.Instantiate<GameObject>(RandomUtility.Choose<GameObject>(TombRushAssets.Instance.CoreAssets.pedestrianAdditions.Masks));
			candyBag = Object.Instantiate<GameObject>(RandomUtility.Choose<GameObject>(TombRushAssets.Instance.CoreAssets.pedestrianAdditions.CandyBags));
			mask.transform.SetParent(head, false);
			candyBag.transform.SetParent(handl, false);
			SpawnParticleEffect();
		}

		private void SpawnParticleEffect()
		{
			particleEffectGo = Object.Instantiate<GameObject>(RandomUtility.Choose<GameObject>(TombRushAssets.Instance.CoreAssets.pedestrianAdditions.ParticleEffects));
			particleEffectGo.SetActive(false);
			particleEffectGo.transform.SetParent(((Component)pedestrian).transform, false);
			particleEffect = particleEffectGo.GetComponent<ParticleSystem>();
		}

		public void AnimateGiveCandy()
		{
			HasCandy = false;
			candyBag.SetActive(false);
			mask.SetActive(false);
			particleEffectGo.SetActive(true);
			((Component)particleEffect).GetComponent<ParticleSystem>().Play();
			SugarRushManager.Instance.NotifyPedestrianHasCandy(this, hasCandy: false);
		}

		public void ResetCandy()
		{
			HasCandy = true;
			candyBag.SetActive(true);
			mask.SetActive(true);
			SpawnParticleEffect();
			SugarRushManager.Instance.NotifyPedestrianHasCandy(this, hasCandy: true);
		}
	}
	public class TombRushPlayer : MonoBehaviour
	{
		[HarmonyPatch]
		internal static class Patches
		{
			[HarmonyPostfix]
			[HarmonyPatch(typeof(Player), "Init")]
			private static void Init_Postfix(Player __instance)
			{
				if (PlayerIsLocal(__instance))
				{
					((Component)__instance).gameObject.AddComponent<TombRushPlayer>().player = __instance;
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch(typeof(StreetLifeBehaviour), "Move")]
			private static void Move_Prefix(StreetLifeBehaviour __instance, StreetLifeCluster cluster, StreetLife life, ref StreetLifeHot streetLifeHot, Transform otherTransform)
			{
				TombRushPlayer component = ((Component)otherTransform.parent.parent).GetComponent<TombRushPlayer>();
				if ((Object)(object)component != (Object)null)
				{
					component.OnPedestrianDodge(life);
					Log.Debug("Pedestrian dodged player: " + Doctor.GetGameObjectPath(((Component)life).gameObject));
				}
			}
		}

		public class TombRushPlayerDebugMenu : DebugMenu
		{
			private readonly TombRushPlayer player;

			public override string Name => "TombRush Player";

			public TombRushPlayerDebugMenu(TombRushPlayer player)
			{
				this.player = player;
			}

			public override void OnGUI()
			{
				GUILayout.Label("Status", Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Sugar Rush: {player.sugarRush:F2}", Array.Empty<GUILayoutOption>());
				GUILayout.HorizontalSlider(player.sugarRush, 0f, player.s.MaxRushMeter, Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Sugar Rush Visual: {player.sugarRushVisual:F2}", Array.Empty<GUILayoutOption>());
				GUILayout.HorizontalSlider(player.sugarRushVisual, 0f, player.s.MaxRushMeter, Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Sugar Rush Hold Time Remaining: {player.sugarRushHoldTimeRemaining:F2}", Array.Empty<GUILayoutOption>());
				GUILayout.HorizontalSlider(player.sugarRushHoldTimeRemaining, 0f, player.s.RushHoldDuration, Array.Empty<GUILayoutOption>());
				GUILayout.Space(15f);
				player.useOverriddenFixedRush = GUILayout.Toggle(player.useOverriddenFixedRush, "Override with Locked Rush Amount", Array.Empty<GUILayoutOption>());
				EditFloat("Locked Rush Amount", ref player.overriddenFixedSugarRush, player.s.MaxRushMeter);
				GUILayout.Space(15f);
				GUILayout.Label("Tweak", Array.Empty<GUILayoutOption>());
				GUILayout.Label("Meter can exceed effect, but your animation boost is capped at 'effect' value", Array.Empty<GUILayoutOption>());
				EditFloat("Max Rush Meter", ref player.s.MaxRushMeter, 5f);
				EditFloat("Max Rush Effect", ref player.s.MaxRushEffect, 5f);
				EditFloat("Rush Hold Duration (delay until decay starts)", ref player.s.RushHoldDuration, 5f);
				EditFloat("Decay Rate", ref player.s.RushDecayRate, 5f);
				EditFloat("Visual Change Rate", ref player.s.RushVisualChangeRate, 5f);
				EditFloat("Pedestrian Grants", ref player.s.PedestrianGrantsRush, 5f);
				EditFloat("CandyCorn Grants", ref player.s.CandycornGrantsRush, 5f);
				EditFloat("Animation Speed Multiplier", ref player.s.AnimationSpeedMultiplier, 5f);
				EditFloat("Movement Speed Multiplier", ref player.s.MovementSpeedMultiplier, 5f);
				EditFloat("Max Base Run Speed Increase", ref player.s.MaxBaseRunSpeedIncrease, 5f);
				static void EditFloat(string label, ref float value, float max)
				{
					GUILayout.Label($"{label}: {value:F2}", Array.Empty<GUILayoutOption>());
					string text = GUILayout.TextField(value.ToString(), Array.Empty<GUILayoutOption>());
					if (text != value.ToString() && float.TryParse(text, out var result))
					{
						value = result;
					}
					value = GUILayout.HorizontalSlider(value, 0f, max, Array.Empty<GUILayoutOption>());
				}
			}
		}

		[NonSerialized]
		private Player player;

		private Animator animator;

		private float sugarRush;

		private bool useOverriddenFixedRush;

		private float overriddenFixedSugarRush = 1f;

		private float sugarRushVisual;

		private float sugarRushHoldTimeRemaining;

		private bool isAt100PercentRush;

		private float timeSpentAt100PercentRush;

		private readonly SugarRushStats s = TombRushAssets.Instance.CoreAssets.SugarRushStats;

		private TombRushPlayerDebugMenu debugMenu;

		private bool gotBaseSpeeds;

		private float baseGrindSpeed;

		private float baseAirDashSpeed;

		private float baseBoostSpeed;

		private float baseWallRunMoveSpeed;

		private float baseVertAbilitySpeed;

		private float baseSlideAbilitySpeed;

		private float baseRunSpeedModifier;

		private float baseVertBottomExitSpeed;

		private float baseVertMaxSpeed;

		private float baseVertTopJumpSpeed;

		private static bool gotStaticBaseSpeeds;

		private static float bmxGrindSpeed;

		private static float bmxRunSpeed;

		private static float skateboardGrindSpeed;

		private static float skateboardRunSpeed;

		private static float inlineGrindSpeed;

		private static float inlineRunSpeed;

		public bool Local => PlayerIsLocal(player);

		private float useThisSugarRush
		{
			get
			{
				if (!useOverriddenFixedRush)
				{
					return sugarRush;
				}
				return overriddenFixedSugarRush;
			}
		}

		private float effectiveSugarRush
		{
			get
			{
				float num = useThisSugarRush;
				if (!(num > 0.8f))
				{
					if (!(num > 0.6f))
					{
						if (!(num > 0.4f))
						{
							if (num > 0.2f)
							{
								return 0.25f;
							}
							return 0f;
						}
						return 0.5f;
					}
					return 0.75f;
				}
				return 1f;
			}
		}

		private static bool PlayerIsLocal(Player player)
		{
			return (Object)(object)player == (Object)(object)WorldHandler.instance.GetCurrentPlayer();
		}

		public static TombRushPlayer Get(Player player)
		{
			return ((Component)player).GetComponent<TombRushPlayer>();
		}

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			TryGrabAnimator();
			Core.OnFixedUpdate += new OnFixedUpdateHandler(OnFixedUpdate);
			Core.OnUpdate += new OnUpdateHandler(OnUpdate);
		}

		private void Start()
		{
			GetBaseAbilitySpeeds();
		}

		private void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Core.OnFixedUpdate -= new OnFixedUpdateHandler(OnFixedUpdate);
			Core.OnUpdate -= new OnUpdateHandler(OnUpdate);
		}

		private void OnUpdate()
		{
			UpdateSugarMeter();
			SetAnimatorSpeedBasedOnSugarLevels();
			SetAbilitySpeedsBasedOnSugarLevels();
			UpdateSugarHUD();
			TrackSugarStats();
		}

		private void OnFixedUpdate()
		{
		}

		private void UpdateSugarMeter()
		{
			if (sugarRush > 0f)
			{
				if (sugarRushHoldTimeRemaining > 0f)
				{
					sugarRushHoldTimeRemaining -= Time.deltaTime;
					if (sugarRushHoldTimeRemaining < 0f)
					{
						sugarRushHoldTimeRemaining = 0f;
					}
				}
				else
				{
					sugarRush -= s.RushDecayRate * Time.deltaTime;
					if (sugarRush < 0f)
					{
						sugarRush = 0f;
					}
				}
			}
			if (sugarRushVisual < useThisSugarRush)
			{
				sugarRushVisual += s.RushVisualChangeRate * Time.deltaTime;
				if (sugarRushVisual > useThisSugarRush)
				{
					sugarRushVisual = useThisSugarRush;
				}
			}
			else if (sugarRushVisual > useThisSugarRush)
			{
				sugarRushVisual -= s.RushVisualChangeRate * Time.deltaTime;
				if (sugarRushVisual < useThisSugarRush)
				{
					sugarRushVisual = useThisSugarRush;
				}
			}
		}

		private void TryGrabAnimator()
		{
			animator = ((Component)this).GetComponentInChildren<Animator>();
		}

		private void CollectRush(float amount)
		{
			sugarRush += amount;
			SaveManager.Instance.Global.Records.TotalCandyCollected += amount;
			SaveManager.Instance.Stage.Records.TotalCandyCollectedThisStage += amount;
			if (sugarRush > s.MaxRushMeter)
			{
				sugarRush = s.MaxRushMeter;
			}
			sugarRushHoldTimeRemaining = s.RushHoldDuration;
		}

		private void OnPedestrianDodge(StreetLife pedestrian)
		{
			TombRushPedestrian component = ((Component)pedestrian).GetComponent<TombRushPedestrian>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			bool flag = false;
			if (component.HasCandy)
			{
				if (SugarRushManager.Instance.SugarExplained)
				{
					flag = true;
				}
				else if (SugarRushManager.Instance.CanExplainSugarRush(component))
				{
					SugarRushManager.Instance.ExplainSugarRush(component);
				}
				if (flag)
				{
					CollectRush(s.PedestrianGrantsRush);
					component.AnimateGiveCandy();
					SaveManager.Instance.Global.Records.TotalPedestriansScared++;
					SaveManager.Instance.Stage.Records.TotalPedestriansScaredThisStage++;
				}
			}
		}

		private void GetBaseAbilitySpeeds()
		{
			baseAirDashSpeed = player.airDashAbility.airDashSpeed;
			baseBoostSpeed = player.normalBoostSpeed;
			baseWallRunMoveSpeed = player.wallrunAbility.wallRunMoveSpeed;
			baseRunSpeedModifier = player.runSpeedModifier;
			baseVertBottomExitSpeed = player.vertBottomExitSpeed;
			baseVertMaxSpeed = player.vertMaxSpeed;
			baseVertTopJumpSpeed = player.vertTopJumpSpeed;
			if (!gotStaticBaseSpeeds)
			{
				bmxGrindSpeed = player.bmxMovementStats.grindSpeed;
				bmxRunSpeed = player.bmxMovementStats.runSpeed;
				inlineGrindSpeed = player.inlineMovementStats.grindSpeed;
				inlineRunSpeed = player.inlineMovementStats.runSpeed;
				skateboardGrindSpeed = player.skateboardMovementStats.grindSpeed;
				skateboardRunSpeed = player.skateboardMovementStats.runSpeed;
				gotStaticBaseSpeeds = true;
			}
			gotBaseSpeeds = true;
		}

		private void SetAbilitySpeedsBasedOnSugarLevels()
		{
			if (gotBaseSpeeds && !Plugin.Instance.ConflictingMovementModsInstalled)
			{
				float num = 1f + effectiveSugarRush * s.MovementSpeedMultiplier;
				player.airDashAbility.airDashSpeed = baseAirDashSpeed * num;
				player.normalBoostSpeed = baseBoostSpeed * num;
				player.wallrunAbility.wallRunMoveSpeed = baseWallRunMoveSpeed * num;
				player.runSpeedModifier = baseRunSpeedModifier + effectiveSugarRush * s.MaxBaseRunSpeedIncrease;
				player.bmxMovementStats.grindSpeed = bmxGrindSpeed * num;
				player.bmxMovementStats.runSpeed = bmxRunSpeed * num;
				player.inlineMovementStats.grindSpeed = inlineGrindSpeed * num;
				player.inlineMovementStats.runSpeed = inlineRunSpeed * num;
				player.skateboardMovementStats.grindSpeed = skateboardGrindSpeed * num;
				player.skateboardMovementStats.runSpeed = skateboardRunSpeed * num;
				player.vertBottomExitSpeed = baseVertBottomExitSpeed * num;
				player.vertMaxSpeed = baseVertMaxSpeed * num;
				player.vertTopJumpSpeed = baseVertTopJumpSpeed * num;
			}
		}

		private void SetAnimatorSpeedBasedOnSugarLevels()
		{
			if ((Object)(object)animator == (Object)null)
			{
				TryGrabAnimator();
			}
			if ((Object)(object)animator != (Object)null)
			{
				animator.speed = 1f + effectiveSugarRush * s.AnimationSpeedMultiplier;
			}
		}

		private void UpdateSugarHUD()
		{
			if (!((Object)(object)TombRushUI.Instance == (Object)null))
			{
				TombRushUI.Instance.SugarRushHUD.SetMeterStyle((MeterStyle)(!(effectiveSugarRush > 0f)));
				TombRushUI.Instance.SugarRushHUD.SetMeterValue(sugarRushVisual);
			}
		}

		private void TrackSugarStats()
		{
			if (effectiveSugarRush >= 1f)
			{
				isAt100PercentRush = true;
				timeSpentAt100PercentRush += Time.deltaTime;
				return;
			}
			if (isAt100PercentRush)
			{
				StageRecords records = SaveManager.Instance.Stage.Records;
				records.TrySetNewRecordHigherIsBetter(ref records.MaxTimeWith100PercentRush, timeSpentAt100PercentRush);
				timeSpentAt100PercentRush = 0f;
			}
			isAt100PercentRush = false;
		}
	}
	public static class PlayerExtensions
	{
		public static TombRushPlayer GetTombRushPlayer(this Player player)
		{
			return ((Component)player).GetComponent<TombRushPlayer>();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TombRush.Plugin";

		public const string PLUGIN_NAME = "TombRush.Plugin";

		public const string PLUGIN_VERSION = "0.0.0";
	}
}
namespace TombRush.Plugin.Patches
{
	[HarmonyPatch(typeof(AmbientManager))]
	internal static class AmbientManagerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		private static void Awake_Prefix(AmbientManager __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Scene scene = ((Component)__instance).gameObject.scene;
			if (!(((Scene)(ref scene)).name != "downhill"))
			{
				__instance.AmbientEnvLight = new Color(0.4f, 0.2f, 0.4f, 1f);
				__instance.AmbientEnvShadow = new Color(0.1f, 0.15f, 0.2f, 1f);
			}
		}
	}
}
namespace TombRush.Plugin.Dependencies
{
	public class AssemblyDependencies
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}