using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using AtlasLib.Utils;
using BepInEx;
using BepInEx.Bootstrap;
using EndlessDelivery.Anticheat;
using EndlessDelivery.Assets;
using EndlessDelivery.Components;
using EndlessDelivery.Config;
using EndlessDelivery.Gameplay;
using EndlessDelivery.Gameplay.EnemyGeneration;
using EndlessDelivery.Scores;
using EndlessDelivery.Scores.Server;
using EndlessDelivery.UI;
using EndlessDelivery.Utils;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using ProjectProphet;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UltraTweaker;
using UltraTweaker.Tweaks;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("EndlessDelivery")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cd8dde03403f8f7e2181d2457477d30a0bcef32a")]
[assembly: AssemblyProduct("EndlessDelivery")]
[assembly: AssemblyTitle("EndlessDelivery")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace AtlasLib.Utils
{
public static class PathUtils
{
public static string GameDirectory()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
string text = Application.dataPath;
if ((int)Application.platform == 1)
{
text = Utility.ParentDirectory(text, 2);
}
else if ((int)Application.platform == 2)
{
text = Utility.ParentDirectory(text, 1);
}
return text;
}
public static string ModDirectory()
{
return Path.Combine(GameDirectory(), "BepInEx", "plugins");
}
public static string ModPath()
{
return Assembly.GetCallingAssembly().Location.Substring(0, Assembly.GetCallingAssembly().Location.LastIndexOf(Path.DirectorySeparatorChar));
}
}
public static class UnityUtils
{
public static GameObject GetChild(this GameObject from, string name)
{
Transform obj = from.transform.Find(name);
return ((obj != null) ? ((Component)obj).gameObject : null) ?? null;
}
public static List<GameObject> FindSceneObjects(string sceneName)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
List<GameObject> list = new List<GameObject>();
GameObject[] array = Object.FindObjectsOfType<GameObject>();
foreach (GameObject val in array)
{
Scene scene = val.scene;
if (((Scene)(ref scene)).name == sceneName)
{
list.Add(val);
}
}
return list;
}
public static List<GameObject> ChildrenList(this GameObject from)
{
List<GameObject> list = new List<GameObject>();
for (int i = 0; i < from.transform.childCount; i++)
{
list.Add(((Component)from.transform.GetChild(i)).gameObject);
}
return list;
}
public static bool Contains(this LayerMask mask, int layer)
{
//IL_0001: 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)
return LayerMask.op_Implicit(mask) == (LayerMask.op_Implicit(mask) | (1 << layer));
}
}
}
namespace EndlessDelivery
{
[BepInPlugin("waffle.ultrakill.christmasdelivery", "Endless Delivery", "1.3.0")]
public class Plugin : BaseUnityPlugin
{
public const string Name = "Endless Delivery";
public const string Version = "1.3.0";
public const string GUID = "waffle.ultrakill.christmasdelivery";
private void Start()
{
Debug.Log((object)"Endless Delivery has started !!");
AddressableManager.Setup();
PatchThis.AddPatches();
Option.Load();
}
private void OnDestroy()
{
Option.Save();
}
}
}
namespace EndlessDelivery.Utils
{
public enum Axis
{
X,
Y,
Z
}
public static class MathsExtensions
{
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
Random rng = new Random();
T[] elements = source.ToArray();
for (int i = elements.Length - 1; i >= 0; i--)
{
int swapIndex = rng.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
}
}
public static List<T> ShuffleAndToList<T>(this IEnumerable<T> source)
{
List<T> list = new List<T>();
Random random = new Random();
T[] array = source.ToArray();
for (int num = array.Length - 1; num >= 0; num--)
{
int num2 = random.Next(num + 1);
list.Add(array[num2]);
array[num2] = array[num];
}
return list;
}
public static T Pick<T>(this T[] array)
{
if (array.Length == 0)
{
return (T)(object)null;
}
return array[Random.Range(0, array.Length)];
}
public static T Pick<T>(this List<T> list)
{
if (list.Count == 0)
{
return (T)(object)null;
}
return list[Random.Range(0, list.Count)];
}
public static Vector3 Only(this Vector3 vector, params Axis[] axes)
{
//IL_0011: 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)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
return new Vector3(axes.Contains(Axis.X) ? vector.x : 0f, axes.Contains(Axis.Y) ? vector.y : 0f, axes.Contains(Axis.Z) ? vector.z : 0f);
}
}
public class PatchThis : Attribute
{
public static Dictionary<Type, PatchThis> AllPatches = new Dictionary<Type, PatchThis>();
private Harmony _harmony;
public readonly string Name;
public static void AddPatches()
{
foreach (Type item in from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetCustomAttribute<PatchThis>() != null
select t)
{
Debug.Log((object)("Adding patch " + item.Name + "..."));
AllPatches.Add(item, item.GetCustomAttribute<PatchThis>());
}
PatchAll();
}
public static void PatchAll()
{
foreach (KeyValuePair<Type, PatchThis> allPatch in AllPatches)
{
PatchThis value = allPatch.Value;
Debug.Log((object)("Patching " + allPatch.Key.Name + "..."));
value._harmony.PatchAll(allPatch.Key);
}
}
public PatchThis(string harmonyName)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
_harmony = new Harmony(harmonyName);
Name = harmonyName;
}
}
public static class TimeUtils
{
public static string Formatted(this TimeSpan span)
{
return span.ToString("mm\\:ss\\:fff", new CultureInfo("en-US"));
}
}
}
namespace EndlessDelivery.UI
{
[PatchThis("waffle.ultrakill.christmasdelivery.AltPresentHud")]
public class AltPresentHud : MonoBehaviour
{
public TMP_Text[] PresentTexts;
public TMP_Text TimerText;
public TMP_Text RoomText;
public Color TimerColour;
public Color TimerDangerColour;
public void Update()
{
//IL_008e: 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)
if (MonoSingleton<GameManager>.Instance.GameStarted)
{
TimerText.text = TimeSpan.FromSeconds(MonoSingleton<GameManager>.Instance.TimeLeft).Formatted();
RoomText.text = (MonoSingleton<GameManager>.Instance.RoomsEntered - 1).ToString();
if (MonoSingleton<GameManager>.Instance.TimeLeft < 10f)
{
((Graphic)TimerText).color = TimerDangerColour;
}
else
{
((Graphic)TimerText).color = TimerColour;
}
int num = 0;
Room currentRoom = MonoSingleton<GameManager>.Instance.CurrentRoom;
TMP_Text[] presentTexts = PresentTexts;
foreach (TMP_Text val in presentTexts)
{
val.text = $"{currentRoom.AmountDelivered[(WeaponVariant)num]}/{currentRoom.PresentColourAmounts[num]}";
num++;
}
}
}
[HarmonyPatch(typeof(HudController), "Start")]
[HarmonyPostfix]
private static void AddSelf(HudController __instance)
{
if (__instance.altHud && !MapInfoBase.InstanceAnyType.hideStockHUD && AddressableManager.InSceneFromThisMod)
{
GameObject val = AddressableManager.Load<GameObject>("Assets/Delivery/Prefabs/HUD/Classic Present Hud.prefab");
Object.Instantiate<GameObject>(val, ((Component)__instance).gameObject.GetChild("Filler").transform);
}
}
}
[PatchThis("waffle.ultrakill.christmasdelivery.BlackFade")]
public class BlackFade : MonoSingleton<BlackFade>
{
private Image _image;
private float _timeBeforeFade;
private void Start()
{
_image = ((Component)this).GetComponent<Image>();
}
private void Update()
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
_timeBeforeFade = Mathf.MoveTowards(_timeBeforeFade, 0f, Time.deltaTime);
if (_timeBeforeFade == 0f)
{
((Graphic)_image).color = new Color(0f, 0f, 0f, Mathf.MoveTowards(((Graphic)_image).color.a, 0f, Time.deltaTime / 1.5f));
}
}
public void Flash(float timeBeforeFade = 0f)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
_timeBeforeFade = timeBeforeFade;
((Graphic)_image).color = Color.black;
}
[HarmonyPatch(typeof(CanvasController), "Awake")]
[HarmonyPostfix]
private static void CreateSelf(CanvasController __instance)
{
Object.Instantiate<GameObject>(AddressableManager.Load<GameObject>("Assets/Delivery/Prefabs/HUD/Black Fade.prefab"), ((Component)__instance).transform);
}
}
public class ColourSetter : MonoBehaviour
{
public static readonly Color[] DefaultColours = (Color[])(object)new Color[4]
{
new Color(0f, 0.91f, 1f),
new Color(0.27f, 1f, 0.27f),
new Color(1f, 0.24f, 0.24f),
new Color(1f, 0.88f, 0.24f)
};
public int Colour;
private void Start()
{
//IL_001a: 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)
Text val = default(Text);
if (((Component)this).TryGetComponent<Text>(ref val))
{
((Graphic)val).color = DefaultColours[Colour];
}
TMP_Text val2 = default(TMP_Text);
if (((Component)this).TryGetComponent<TMP_Text>(ref val2))
{
((Graphic)val2).color = DefaultColours[Colour];
}
}
}
[PatchThis("waffle.ultrakill.christmasdelivery.DeliveryButton")]
public class DeliveryButton
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static UnityAction <>9__0_0;
internal void <AddButton>b__0_0()
{
AddressableManager.LoadScene("Assets/Delivery/Scenes/Game Scene.unity");
}
}
[HarmonyPatch(typeof(CanvasController), "Awake")]
[HarmonyPostfix]
private static void AddButton(CanvasController __instance)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
//IL_00b4: 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_00bf: Expected O, but got Unknown
GameObject child = ((Component)__instance).gameObject.GetChild("Chapter Select");
if ((Object)(object)child == (Object)null)
{
return;
}
GameObject child2 = child.GetChild("The Cyber Grind");
RectTransform component = child2.GetComponent<RectTransform>();
component.sizeDelta -= new Vector2(55f, 0f);
((Transform)component).position = ((Transform)component).position - new Vector3(27.5f, 0f, 0f);
GameObject val = Object.Instantiate<GameObject>(AddressableManager.Load<GameObject>("Assets/Delivery/Prefabs/HUD/Jolly Chapter Select Button.prefab"), child.transform);
ButtonClickedEvent onClick = val.GetComponent<Button>().onClick;
object obj = <>c.<>9__0_0;
if (obj == null)
{
UnityAction val2 = delegate
{
AddressableManager.LoadScene("Assets/Delivery/Scenes/Game Scene.unity");
};
<>c.<>9__0_0 = val2;
obj = (object)val2;
}
((UnityEvent)onClick).AddListener((UnityAction)obj);
}
}
[PatchThis("waffle.ultrakill.christmasdelivery.EndScreen")]
public class EndScreen : MonoSingleton<EndScreen>
{
public GameObject[] ToAppear;
public GameObject AudioObject;
public Image HighscoreFlash;
public float Delay = 0.25f;
public float SkippingDelay = 0.05f;
[Space(10f)]
public ReachValueText Rooms;
public ReachValueText Kills;
public ReachValueText Deliveries;
public ReachValueText TimeElapsed;
[Space(10f)]
public Text BestRooms;
public Text BestKills;
public Text BestDeliveries;
public Text BestTimeElapsed;
[Space(10f)]
public ReachValueText MoneyGainText;
[Space(10f)]
public GameObject Leaderboard;
public GameObject EverythingButLeaderboard;
[HideInInspector]
public bool NewBest;
[HideInInspector]
public ReachValueText CurrentText;
private int _currentIndex;
private float _timeSinceComplete;
private bool _appearedSelf;
private bool _complete;
private bool _leaderboardShown;
public bool Skipping => MonoSingleton<InputManager>.Instance.InputSource.Fire1.WasPerformedThisFrame || MonoSingleton<InputManager>.Instance.InputSource.Jump.WasPerformedThisFrame;
private void Awake()
{
GameObject[] toAppear = ToAppear;
foreach (GameObject val in toAppear)
{
val.SetActive(false);
}
}
public void Appear()
{
SetPanelValues(MonoSingleton<GameManager>.Instance.CurrentScore, Rooms, Kills, Deliveries, TimeElapsed);
SetPanelValues(NewBest ? Score.PreviousHighscore : Score.Highscore, BestRooms, BestKills, BestDeliveries, BestTimeElapsed);
MoneyGainText.Target = MonoSingleton<GameManager>.Instance.CurrentScore.MoneyGain;
((MonoBehaviour)this).StartCoroutine(AppearCoroutine());
}
private IEnumerator AppearCoroutine()
{
TimeController timeController = MonoSingleton<TimeController>.Instance;
timeController.controlTimeScale = false;
while (timeController.timeScale > 0f)
{
timeController.timeScale = Mathf.MoveTowards(timeController.timeScale, 0f, Time.unscaledDeltaTime * (timeController.timeScale + 0.01f));
Time.timeScale = timeController.timeScale * timeController.timeScaleModifier;
MonoSingleton<AudioMixerController>.Instance.allSound.SetFloat("allPitch", timeController.timeScale);
MonoSingleton<AudioMixerController>.Instance.allSound.SetFloat("allVolume", 0.5f + timeController.timeScale / 2f);
MonoSingleton<AudioMixerController>.Instance.musicSound.SetFloat("allPitch", timeController.timeScale);
MonoSingleton<MusicManager>.Instance.volume = 0.5f + timeController.timeScale / 2f;
yield return null;
}
ShowNext();
_appearedSelf = true;
MonoSingleton<MusicManager>.Instance.forcedOff = true;
MonoSingleton<MusicManager>.Instance.StopMusic();
AudioObject.SetActive(!Option.GetValue<bool>("disable_copyrighted_music"));
}
private void SetPanelValues(Score score, ReachValueText rooms, ReachValueText kills, ReachValueText deliveries, ReachValueText time)
{
rooms.Target = score.Rooms;
kills.Target = score.Kills;
deliveries.Target = score.Deliveries;
time.Target = score.Time;
}
private void SetPanelValues(Score score, Text rooms, Text kills, Text deliveries, Text time)
{
rooms.text = score.Rooms.ToString();
kills.text = score.Kills.ToString();
deliveries.text = score.Deliveries.ToString();
time.text = TimeSpan.FromSeconds(score.Time).Formatted();
}
private void Update()
{
if (_appearedSelf)
{
ReachValueText currentText = CurrentText;
if (currentText == null || currentText.Done)
{
_timeSinceComplete += Time.unscaledDeltaTime;
}
if ((_timeSinceComplete >= ((!Skipping) ? Delay : SkippingDelay) && _currentIndex != ToAppear.Length) || Skipping)
{
ShowNext();
_timeSinceComplete = 0f;
}
}
}
private void ShowNext()
{
if (_currentIndex == ToAppear.Length)
{
if (!_leaderboardShown)
{
Leaderboard.SetActive(true);
EverythingButLeaderboard.SetActive(false);
_leaderboardShown = true;
}
else
{
MonoSingleton<NewMovement>.Instance.hp = 0;
_complete = true;
}
}
else
{
ToAppear[_currentIndex++].SetActive(true);
}
}
public void DoFlashIfApplicable()
{
if (NewBest)
{
SetPanelValues(Score.Highscore, BestRooms, BestKills, BestDeliveries, BestTimeElapsed);
((MonoBehaviour)this).StartCoroutine(DoHighscoreFlash());
}
}
private IEnumerator DoHighscoreFlash()
{
((Graphic)HighscoreFlash).color = new Color(1f, 1f, 1f, 1f);
((Component)HighscoreFlash).GetComponent<AudioSource>().Play();
while (((Graphic)HighscoreFlash).color.a != 0f)
{
((Graphic)HighscoreFlash).color = new Color(1f, 1f, 1f, Mathf.MoveTowards(((Graphic)HighscoreFlash).color.a, 0f, Time.unscaledDeltaTime));
yield return null;
}
}
[HarmonyPatch(typeof(CanvasController), "Awake")]
[HarmonyPostfix]
private static void CreateSelf()
{
Object.Instantiate<GameObject>(AddressableManager.Load<GameObject>("Assets/Delivery/Prefabs/HUD/Delivery End Screen.prefab"));
}
}
public class EndScreenLeaderboards : MonoBehaviour
{
public Text[] ConnectingToServerText;
public Transform TopLeaderboardContainer;
public Transform NearbyLeaderboardContainer;
public GameObject EntryTemplate;
public void OnEnable()
{
DoStuff();
}
private async Task DoStuff()
{
if (MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0) != 3)
{
Text[] connectingToServerText = ConnectingToServerText;
foreach (Text text3 in connectingToServerText)
{
text3.text = "LEADERBOARDS ARE ONLY ON VIOLENT (FOR NOW)";
}
return;
}
if (!(await Endpoints.IsServerOnline()))
{
Text[] connectingToServerText2 = ConnectingToServerText;
foreach (Text text2 in connectingToServerText2)
{
text2.text = "FAILED TO CONNECT :^(";
}
return;
}
if (MonoSingleton<EndScreen>.Instance.NewBest)
{
await Endpoints.SendScoreAndReturnPosition(Score.Highscore);
}
List<ScoreResult> nearScores = await Endpoints.GetUserPage(await Endpoints.GetUserPosition(SteamId.op_Implicit(SteamClient.SteamId)));
List<ScoreResult> topScores = await Endpoints.GetScoreRange(0, 10);
foreach (ScoreResult scoreResult2 in nearScores)
{
Object.Instantiate<GameObject>(EntryTemplate, NearbyLeaderboardContainer).GetComponent<LeaderboardEntry>().SetValuesAndEnable(scoreResult2);
}
foreach (ScoreResult scoreResult in topScores)
{
Object.Instantiate<GameObject>(EntryTemplate, TopLeaderboardContainer).GetComponent<LeaderboardEntry>().SetValuesAndEnable(scoreResult);
}
Text[] connectingToServerText3 = ConnectingToServerText;
foreach (Text text in connectingToServerText3)
{
((Component)text).gameObject.SetActive(false);
}
}
}
public class JollyTerminal : MonoBehaviour
{
public TMP_Text ScoreText;
public AudioSource Music;
public GameObject[] DisableIfNotOnHighscoreDifficulty;
private void OnEnable()
{
AssignScoreText();
SetMusicStatus();
bool active = MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0) == 3;
GameObject[] disableIfNotOnHighscoreDifficulty = DisableIfNotOnHighscoreDifficulty;
foreach (GameObject val in disableIfNotOnHighscoreDifficulty)
{
val.SetActive(active);
}
}
public void AssignScoreText()
{
Score highscore = Score.Highscore;
ScoreText.text = $"{highscore.Rooms}\n{highscore.Kills}\n{highscore.Deliveries}\n{TimeSpan.FromSeconds(highscore.Time).Formatted()}";
}
public void SetMusicStatus()
{
if (Option.GetValue<bool>("disable_copyrighted_music"))
{
Music.Pause();
}
else
{
Music.UnPause();
}
}
}
public class JollyTerminalLeaderboards : MonoBehaviour
{
public Button[] PageButtons;
public LeaderboardEntry[] Entries;
public TMP_Text PageText;
private List<ScoreResult> _pageScores;
private bool _hasLoadedScores;
private int _page = 0;
private int _pageAmount;
public void Start()
{
SetStuff();
}
private async void SetStuff()
{
_pageAmount = Mathf.CeilToInt((float)(await Endpoints.GetScoreAmount()) / 5f);
}
public void OnEnable()
{
if (!_hasLoadedScores)
{
LeaderboardEntry[] entries = Entries;
foreach (LeaderboardEntry leaderboardEntry in entries)
{
((Component)leaderboardEntry).gameObject.SetActive(false);
}
RefreshPage();
}
}
public void ScrollPage(int amount)
{
if (_page + amount >= 0 && _page + amount <= _pageAmount - 1)
{
_page += amount;
}
PageText.text = (_page + 1).ToString();
RefreshPage();
}
public void Refresh()
{
RefreshAsync();
}
private async void RefreshAsync()
{
((Component)((Component)this).transform.parent).gameObject.SetActive(false);
await Score.GetServerScoreAndSetIfHigher();
((Component)this).GetComponentInParent<JollyTerminal>().AssignScoreText();
((Component)((Component)this).transform.parent).gameObject.SetActive(true);
}
public async Task RefreshPage()
{
if (!(await Endpoints.IsServerOnline()))
{
MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Server offline!", "", "", 0, false);
((Component)this).gameObject.SetActive(false);
return;
}
Button[] pageButtons = PageButtons;
foreach (Button button in pageButtons)
{
((Selectable)button).interactable = false;
}
try
{
_pageScores = await Endpoints.GetScoreRange(_page * 5, 5);
for (int i = 0; i < 5; i++)
{
if (i < _pageScores.Count)
{
Entries[i].SetValuesAndEnable(_pageScores[i]);
}
else
{
((Component)Entries[i]).gameObject.SetActive(false);
}
}
}
catch (Exception ex)
{
Endpoints.DisplayError("Failed to load scores!!" + ex);
}
Button[] pageButtons2 = PageButtons;
foreach (Button button2 in pageButtons2)
{
((Selectable)button2).interactable = true;
}
}
}
public class LeaderboardEntry : MonoBehaviour
{
[Header("All monobehaviours here should implement IText")]
public MonoBehaviour RankNumber;
public MonoBehaviour Username;
public MonoBehaviour Rooms;
public MonoBehaviour Delivered;
public Image ProfileActual;
public async void SetValuesAndEnable(ScoreResult scoreResult)
{
Friend user = new Friend(SteamId.op_Implicit(scoreResult.SteamId));
((IText)RankNumber).SetText((scoreResult.Index + 1).ToString());
IText text = (IText)Username;
text.SetText(string.Format(await SpecialUserResult.GetFormat(SteamId.op_Implicit(user.Id)), ((Friend)(ref user)).Name));
((IText)Rooms).SetText(scoreResult.Score.Rooms.ToString());
((IText)Delivered).SetText($"({scoreResult.Score.Deliveries})");
SetAvatar(user);
((Component)this).gameObject.SetActive(true);
}
private async void SetAvatar(Friend user)
{
//IL_0019: 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)
Image? image = await ((Friend)(ref user)).GetMediumAvatarAsync();
Texture2D texture2D = new Texture2D((int)image.Value.Width, (int)image.Value.Height, (TextureFormat)4, false);
texture2D.LoadRawTextureData(image.Value.Data);
texture2D.Apply();
ProfileActual.sprite = Sprite.Create(texture2D, new Rect(0f, 0f, (float)((Texture)texture2D).width, (float)((Texture)texture2D).height), Vector2.one / 2f);
}
}
[PatchThis("waffle.ultrakill.christmasdelivery.PresentTimeHud")]
public class PresentTimeHud : MonoSingleton<PresentTimeHud>
{
public const float DangerTime = 10f;
public Image[] PresentImages;
public TMP_Text Timer;
public TMP_Text CompleteRooms;
public Color TimerColour;
public Color TimerDangerColour;
private float _lastSetSeconds;
private float _lerpProgress;
private float _originalFontSize;
private Vector3 _timerStartPos;
public void Start()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
_originalFontSize = Timer.fontSize;
_timerStartPos = Timer.transform.localPosition;
}
private void Update()
{
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
if (!MonoSingleton<GameManager>.Instance.GameStarted)
{
return;
}
if (MonoSingleton<GameManager>.Instance.TimerActive)
{
Timer.text = TimeSpan.FromSeconds(MonoSingleton<GameManager>.Instance.TimeLeft).ToString("mm\\:ss\\.fff", new CultureInfo("en-US"));
Timer.fontSize = Mathf.MoveTowards(Timer.fontSize, _originalFontSize, 75f * Time.deltaTime);
_lastSetSeconds = MonoSingleton<GameManager>.Instance.TimeLeft;
_lerpProgress = 0f;
}
else
{
if (MonoSingleton<GameManager>.Instance.TimeLeft > 10f)
{
MonoSingleton<CameraController>.Instance.StopShake();
}
float num = Mathf.Lerp(_lastSetSeconds, MonoSingleton<GameManager>.Instance.TimeLeft, _lerpProgress);
Timer.text = TimeSpan.FromSeconds(num).Formatted();
Timer.fontSize = _originalFontSize * (1f + _lerpProgress * 0.15f);
_lerpProgress += Time.deltaTime / 0.5f;
}
if (MonoSingleton<GameManager>.Instance.TimeLeft <= 10f)
{
((Graphic)Timer).color = TimerDangerColour;
Timer.transform.localPosition = _timerStartPos + new Vector3((float)Random.Range(-1, 1), (float)Random.Range(-1, 1), 0f);
MonoSingleton<CameraController>.Instance.CameraShake((10f - MonoSingleton<GameManager>.Instance.TimeLeft) / 50f);
}
else
{
((Graphic)Timer).color = TimerColour;
Timer.transform.localPosition = _timerStartPos;
}
if ((Object)(object)MonoSingleton<GameManager>.Instance.CurrentRoom != (Object)null)
{
for (int i = 0; i < 4; i++)
{
PresentImages[i].fillAmount = FindFill((WeaponVariant)i);
}
}
CompleteRooms.text = (MonoSingleton<GameManager>.Instance.RoomsEntered - 1).ToString();
}
private float FindFill(WeaponVariant colour)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
float num = MonoSingleton<GameManager>.Instance.CurrentRoom.PresentColourAmounts[colour];
return 1f - (float)MonoSingleton<GameManager>.Instance.CurrentRoom.AmountDelivered[colour] / num;
}
[HarmonyPatch(typeof(HudController), "Start")]
[HarmonyPostfix]
private static void AddSelf(HudController __instance)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
if (!__instance.altHud && !MapInfoBase.InstanceAnyType.hideStockHUD)
{
GameObject val = AddressableManager.Load<GameObject>("Assets/Delivery/Prefabs/HUD/Present Panel.prefab");
GameObject val2 = Object.Instantiate<GameObject>(val, ((Component)__instance.hudpos).transform);
val2.transform.localPosition = val.transform.localPosition;
val2.gameObject.SetActive(false);
}
}
}
public class ReachValueText : MonoBehaviour
{
public enum IntOrFloat
{
Int,
Float
}
public IntOrFloat Type;
public Text Text;
public float Target;
public string Format;
public string StartValue;
public float ChangePerSecond;
public bool IsTimestamp;
private float _timeElapsed;
private AudioSource _audio;
private float _currentValue;
[HideInInspector]
public bool Done;
private void OnEnable()
{
MonoSingleton<EndScreen>.Instance.CurrentText = this;
Text.text = StartValue;
_audio = ((Component)this).GetComponent<AudioSource>();
AudioSource audio = _audio;
if (audio != null)
{
audio.Play();
}
}
private void Update()
{
if (MonoSingleton<EndScreen>.Instance.Skipping)
{
_currentValue = Target;
SetText();
}
if (Target == _currentValue)
{
SetText();
Done = true;
((Behaviour)this).enabled = false;
AudioSource audio = _audio;
if (audio != null)
{
audio.Stop();
}
}
else
{
_timeElapsed += Time.unscaledDeltaTime;
_currentValue = Mathf.MoveTowards(_currentValue, Target, ChangePerSecond * Time.unscaledDeltaTime);
SetText();
}
}
private void SetText()
{
float num = ((Type == IntOrFloat.Int) ? Mathf.Floor(_currentValue) : _currentValue);
Text.text = ((!IsTimestamp) ? string.Format(Format, num) : TimeSpan.FromSeconds(num).Formatted());
}
}
public interface IText
{
void SetText(string text);
}
public class TmpText : MonoBehaviour, IText
{
private TMP_Text _text;
public void SetText(string text)
{
if ((Object)(object)_text == (Object)null)
{
_text = ((Component)this).GetComponent<TMP_Text>();
}
_text.text = text;
}
}
public class UnityText : MonoBehaviour, IText
{
private Text _text;
public void SetText(string text)
{
if ((Object)(object)_text == (Object)null)
{
_text = ((Component)this).GetComponent<Text>();
}
_text.text = text;
}
}
}
namespace EndlessDelivery.Scores
{
public static class BestTimes
{
private static Dictionary<int, float> _times;
public static string TimesFilePath => Path.Combine(Option.SavePath, string.Format("besttimes_{0}.json", MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0)));
public static float CurrentStartTime => GetRoomTime((int)((Option<long>)Option.AllOptions["start_wave"]).Value);
public static Dictionary<int, float> Times
{
get
{
if (_times == null)
{
if (File.Exists(TimesFilePath))
{
_times = JsonConvert.DeserializeObject<Dictionary<int, float>>(File.ReadAllText(TimesFilePath));
}
else
{
_times = new Dictionary<int, float>();
}
}
return _times;
}
}
public static void SetIfHigher(int room, float time)
{
Debug.Log((object)$"Trying to save {room} at {time}");
if (!Score.CanSubmit)
{
Debug.Log((object)"Early ret?");
return;
}
Debug.Log((object)$"{room} at {time}");
if (Times.ContainsKey(room))
{
Debug.Log((object)$"Checking if it's more than {Times[room]}");
if (time > Times[room])
{
Debug.Log((object)"it is!");
Times[room] = time;
}
Debug.Log((object)"it isnt?");
}
else
{
Debug.Log((object)"doesnt contain");
Times.Add(room, time);
Debug.Log((object)"add?");
Save();
}
}
public static float GetRoomTime(int room)
{
if (room != 0)
{
return Times[room];
}
return 45f;
}
private static async void Save()
{
Directory.CreateDirectory(Option.SavePath);
using StreamWriter sw = new StreamWriter(TimesFilePath);
await sw.WriteAsync(JsonConvert.SerializeObject((object)Times));
}
}
public class Score
{
private static int _lastCheckedDifficulty;
private static Score _highscore;
public readonly int Rooms;
public readonly int Kills;
public readonly int Deliveries;
public readonly float Time;
public static string HighscoreFilePath => Path.Combine(Option.SavePath, string.Format("highscore_{0}.json", MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0)));
public static bool CanSubmit => !EndlessDelivery.Anticheat.Anticheat.HasIllegalMods && !MonoSingleton<CheatsController>.Instance.cheatsEnabled;
public static Score Highscore
{
get
{
if (_highscore == null || _lastCheckedDifficulty != MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0))
{
_lastCheckedDifficulty = MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0);
Score score = (File.Exists(HighscoreFilePath) ? JsonConvert.DeserializeObject<Score>(File.ReadAllText(HighscoreFilePath)) : null);
if (score == null)
{
Debug.Log((object)"Using fallback score!");
Highscore = new Score(0, 0, 0, 0f);
}
else
{
Highscore = score;
}
}
return _highscore;
}
set
{
PreviousHighscore = _highscore;
_highscore = value;
SaveScore(value);
}
}
public static Score PreviousHighscore { get; private set; }
[JsonIgnore]
public int MoneyGain => (int)(Time * 10f);
public static async Task GetServerScoreAndSetIfHigher()
{
Score serverScore = (await Endpoints.GetScoreRange(await Endpoints.GetUserPosition(SteamId.op_Implicit(SteamClient.SteamId)), 1))[0].Score;
if (IsLargerThanOtherScore(serverScore, Highscore))
{
Highscore = serverScore;
}
}
private static void SaveScore(Score score)
{
Directory.CreateDirectory(Option.SavePath);
File.WriteAllText(HighscoreFilePath, JsonConvert.SerializeObject((object)score));
}
public static bool IsLargerThanOtherScore(Score score, Score other)
{
if (score.Rooms != other.Rooms)
{
if (score.Rooms > other.Rooms)
{
return true;
}
return false;
}
if (score.Deliveries != other.Deliveries)
{
if (score.Deliveries > other.Deliveries)
{
return true;
}
return false;
}
if (score.Kills != other.Kills)
{
if (score.Kills > other.Kills)
{
return true;
}
return false;
}
if (score.Time != other.Time)
{
if (score.Time < other.Time)
{
return true;
}
return false;
}
return false;
}
public Score(int rooms, int kills, int deliveries, float time)
{
Rooms = rooms;
Kills = kills;
Deliveries = deliveries;
Time = time;
}
}
}
namespace EndlessDelivery.Scores.Server
{
public class Endpoints
{
private static readonly HttpClient _client = new HttpClient();
private const string Url = "http://159.65.214.169/";
private const string ScoresGetRange = "http://159.65.214.169/scores/get_range?start={0}&count={1}";
private const string ScoresGetAmount = "http://159.65.214.169/scores/get_length";
private const string ScoresGetPosition = "http://159.65.214.169/scores/get_position?steamId={0}";
private const string ScoresAdd = "http://159.65.214.169/scores/add_score?score={0}&ticket={1}&version={2}";
private const string UsersSpecialGet = "http://159.65.214.169/users/get_special_users";
public static async Task<bool> IsServerOnline()
{
return true;
}
public static async Task<List<SpecialUserResult>> GetSpecialUsers()
{
return JsonConvert.DeserializeObject<List<SpecialUserResult>>(await (await _client.GetAsync("http://159.65.214.169/users/get_special_users")).Content.ReadAsStringAsync());
}
public static async Task<List<ScoreResult>> GetScoreRange(int start, int count)
{
string responseBody = await (await _client.GetAsync($"http://159.65.214.169/scores/get_range?start={start}&count={count}")).Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
return JsonConvert.DeserializeObject<List<ScoreResult>>(responseBody);
}
public static async Task<int> GetScoreAmount()
{
string responseBody = await (await _client.GetAsync("http://159.65.214.169/scores/get_length")).Content.ReadAsStringAsync();
Debug.Log((object)(responseBody + " " + JsonConvert.DeserializeObject<Response>(responseBody).Value.GetType()));
return (int)(long)JsonConvert.DeserializeObject<Response>(responseBody).Value;
}
public static async Task<int> GetUserPosition(ulong steamId)
{
try
{
Debug.Log((object)$"http://159.65.214.169/scores/get_position?steamId={steamId}");
string responseBody = await (await _client.GetAsync($"http://159.65.214.169/scores/get_position?steamId={steamId}")).Content.ReadAsStringAsync();
Debug.Log((object)"should be done");
return (int)(long)JsonConvert.DeserializeObject<Response>(responseBody).Value;
}
catch
{
return -1;
}
}
public static async Task<int> SendScoreAndReturnPosition(Score score)
{
try
{
string responseBody = await (await _client.GetAsync(string.Format("http://159.65.214.169/scores/add_score?score={0}&ticket={1}&version={2}", JsonConvert.SerializeObject((object)score), SteamAuth.GetTicket(), "1.3.0"))).Content.ReadAsStringAsync();
Debug.Log((object)("received " + responseBody));
return (int)(long)JsonConvert.DeserializeObject<Response>(responseBody).Value;
}
catch (Exception ex2)
{
Exception ex = ex2;
DisplayError(ex.ToString());
return -1;
}
}
public static void DisplayError(string error)
{
MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("<color=red>AN ERROR HAS OCCURED WITH THE SERVER! Contact Waffle and send your logs.</color>", "", "", 0, false);
Debug.LogError((object)("DISPLAYERROR: " + error));
}
public static async Task<List<ScoreResult>> GetUserPage(float index)
{
int pageNumber = (int)(index / 8f);
return await GetScoreRange(pageNumber * 8, 10);
}
}
public class Response
{
public object Value { get; set; }
public int StatusCode { get; set; }
}
public class ScoreResult
{
public ulong SteamId { get; set; }
public Score Score { get; set; }
public int Index { get; set; }
}
public class SpecialUserResult
{
public static Dictionary<ulong, SpecialUserResult>? SteamIdToUser;
public ulong SteamId { get; set; }
public bool IsBanned { get; set; }
public string NameFormat { get; set; }
private static async Task EnsureDictSet()
{
if (SteamIdToUser == null)
{
SteamIdToUser = (await Endpoints.GetSpecialUsers()).ToDictionary((SpecialUserResult x) => x.SteamId, (SpecialUserResult y) => y);
}
}
public static async Task<string> GetFormat(ulong steamId)
{
await EnsureDictSet();
if (SteamIdToUser.TryGetValue(steamId, out SpecialUserResult result))
{
return result.NameFormat;
}
return "{0}";
}
}
public static class SteamAuth
{
public static string GetTicket()
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
AuthTicket authSessionTicket = SteamUser.GetAuthSessionTicket(default(NetIdentity));
return BitConverter.ToString(authSessionTicket.Data, 0, authSessionTicket.Data.Length).Replace("-", string.Empty);
}
}
}
namespace EndlessDelivery.Gameplay
{
[PatchThis("waffle.ultrakill.christmasdelivery.GameManager")]
public class GameManager : MonoSingleton<GameManager>
{
public const float StartTime = 45f;
public const float TimeAddLength = 0.5f;
public NavMeshSurface Navmesh;
public AudioSource TimeAddSound;
public RoomPool RoomPool;
private Coroutine _pauseCoroutine;
private List<RoomData> _remainingRooms = new List<RoomData>();
private static readonly int _startingPoints = 10;
public bool GameStarted { get; private set; }
public float TimeLeft { get; private set; }
public float TimeElapsed { get; private set; }
public int DeliveredPresents { get; set; }
public int RoomsEntered { get; private set; }
public Room CurrentRoom { get; private set; }
public Room PreviousRoom { get; private set; }
public bool TimerActive { get; private set; }
public int PointsPerWave { get; private set; }
public Score CurrentScore => new Score(RoomsEntered - 1, MonoSingleton<StatsManager>.Instance.kills, DeliveredPresents, TimeElapsed);
public static int GetRoomPoints(int roomNumber)
{
Debug.Log((object)$"sp {_startingPoints}");
int num = _startingPoints;
for (int i = 0; i < roomNumber; i++)
{
num += 3 + (i + 1) / 3;
Debug.Log((object)$"p {_startingPoints} ( + {3 + (i + 1) / 3})");
}
Debug.Log((object)$"ret {num}");
return num;
}
private void Awake()
{
Act3EnemyHack.AddToPools(EnemyGroup.Groups[DeliveryEnemyClass.Projectile], EnemyGroup.Groups[DeliveryEnemyClass.Uncommon]);
}
private void Update()
{
if (GameStarted && MonoSingleton<GunControl>.Instance.activated)
{
TimeLeft = Mathf.MoveTowards(TimeLeft, 0f, Time.deltaTime);
TimeElapsed += Time.deltaTime;
if (TimeLeft == 0f)
{
EndGame();
}
if (!CurrentRoom.RoomCleared && CurrentRoom.RoomActivated && MonoSingleton<EnemyTracker>.Instance.enemies.All((EnemyIdentifier enemy) => enemy.dead))
{
CurrentRoom.RoomCleared = true;
MonoSingleton<MusicManager>.Instance.PlayCleanMusic();
AddTime(4f, "<color=orange>FULL CLEAR</color>");
}
}
}
public void AddTime(float seconds, string reason)
{
AudioSource timeAddSound = TimeAddSound;
if (timeAddSound != null)
{
timeAddSound.Play();
}
TimerActive = false;
if (_pauseCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_pauseCoroutine);
}
_pauseCoroutine = ((MonoBehaviour)this).StartCoroutine(UnpauseTimer());
MonoSingleton<StyleHUD>.Instance.AddPoints(5, $"{reason} <size=20>({seconds}s)</size>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
TimeLeft += seconds;
}
public void SilentAddTime(float seconds)
{
TimeLeft += seconds;
}
private IEnumerator UnpauseTimer()
{
yield return (object)new WaitForSeconds(0.5f);
TimerActive = true;
}
public Room GenerateNewRoom()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: 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)
Collider component = ((Component)CurrentRoom).GetComponent<Collider>();
GameObject prefab = GetRandomRoom().Prefab;
Vector3 position = ((Component)CurrentRoom).gameObject.transform.position;
Vector3 right = Vector3.right;
Bounds bounds = component.bounds;
return Object.Instantiate<GameObject>(prefab, position + right * ((Bounds)(ref bounds)).size.x * 2.5f, Quaternion.identity).GetComponent<Room>();
}
public RoomData GetRandomRoom()
{
if (_remainingRooms.Count == 0)
{
_remainingRooms.AddRange(RoomPool.Rooms);
}
RoomData roomData = _remainingRooms.Pick();
_remainingRooms.Remove(roomData);
return roomData;
}
public void RoomEnd()
{
if (CurrentRoom.RoomHasGameplay)
{
AddTime(8f, "<color=orange>ROOM CLEAR</color>");
PointsPerWave += 3 + RoomsEntered / 3;
BestTimes.SetIfHigher(RoomsEntered, TimeLeft);
}
SetRoom(GenerateNewRoom());
Navmesh.BuildNavMesh();
}
public void SetRoom(Room room)
{
if (!GameStarted && room.RoomHasGameplay)
{
StartGame();
}
if ((Object)(object)CurrentRoom != (Object)(object)room)
{
RoomsEntered++;
PreviousRoom = CurrentRoom;
CurrentRoom = room;
room.Initialize();
}
if (room.RoomHasGameplay && !room.RoomAlreadyVisited)
{
room.RoomAlreadyVisited = true;
}
}
public void StartGame()
{
if (!GameStarted)
{
((Component)MonoSingleton<PresentTimeHud>.Instance).gameObject.SetActive(true);
((Component)((Component)MonoSingleton<StatsManager>.Instance).GetComponentInChildren<MusicManager>(true)).gameObject.SetActive(true);
MonoSingleton<MusicManager>.Instance.StartMusic();
RoomsEntered = (int)Option.GetValue<long>("start_wave");
PointsPerWave = GetRoomPoints(RoomsEntered);
TimeLeft = BestTimes.CurrentStartTime;
TimerActive = true;
GameStarted = true;
}
}
public void EndGame()
{
if (!GameStarted)
{
return;
}
if (!MonoSingleton<NewMovement>.Instance.dead)
{
MonoSingleton<NewMovement>.Instance.GetHurt(1000, false, 1f, false, false, 1f, false);
}
((Component)MonoSingleton<NewMovement>.Instance.blackScreen).gameObject.SetActive(false);
MonoSingleton<NewMovement>.Instance.hp = 100;
GameStarted = false;
if (Score.IsLargerThanOtherScore(CurrentScore, Score.Highscore))
{
if (Score.CanSubmit)
{
Score.Highscore = CurrentScore;
MonoSingleton<EndScreen>.Instance.NewBest = true;
}
else
{
MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Score not submitting due to other mods, or cheats enabled.", "", "", 0, false);
}
}
MonoSingleton<EndScreen>.Instance.Appear();
GameProgressSaver.AddMoney(CurrentScore.MoneyGain);
}
[HarmonyPatch(typeof(SeasonalHats), "Start")]
[HarmonyPrefix]
private static void EnableHats(SeasonalHats __instance)
{
if (AddressableManager.InSceneFromThisMod)
{
__instance.easter.SetActive(false);
__instance.halloween.SetActive(false);
__instance.christmas.SetActive(true);
}
}
[HarmonyPatch(typeof(NewMovement), "GetHurt")]
[HarmonyPostfix]
private static void CustomDeath(NewMovement __instance)
{
if (__instance.dead && AddressableManager.InSceneFromThisMod)
{
MonoSingleton<GameManager>.Instance.EndGame();
}
}
}
public static class GenerationEquations
{
public static int PresentAmount(int wave)
{
int num = Mathf.CeilToInt(Mathf.Log((float)wave, 6.5f) * 3f);
num = Mathf.Clamp(num, 4, 10);
Debug.Log((object)$"{wave} presents: {num}");
return num;
}
public static int[] DistributeBetween(int amount, int number)
{
int[] array = new int[amount];
int num = 0;
while (number >= 1)
{
array[num]++;
number--;
num++;
if (num > amount - 1)
{
num = 0;
}
}
return array;
}
}
public class PlayerChimneyFixer : MonoSingleton<PlayerChimneyFixer>
{
private bool _isInChimney;
private Chimney _currentChimney;
public void EnterChimney(Chimney chimney)
{
_isInChimney = true;
_currentChimney = chimney;
}
public void Exit()
{
_isInChimney = false;
}
private void Update()
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: 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_0084: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
if (_isInChimney)
{
Vector3 position = ((GameObject)(((Object)(object)_currentChimney != (Object)null) ? ((object)((Component)_currentChimney).gameObject) : ((object)MonoSingleton<GameManager>.Instance.CurrentRoom.SpawnPoint))).transform.position;
position.y = ((Component)MonoSingleton<NewMovement>.Instance).transform.position.y;
((Component)MonoSingleton<NewMovement>.Instance).transform.position = Vector3.MoveTowards(((Component)MonoSingleton<NewMovement>.Instance).transform.position, position, Time.deltaTime * 5f);
MonoSingleton<NewMovement>.Instance.rb.velocity = MonoSingleton<NewMovement>.Instance.rb.velocity.Only(Axis.Y);
((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = false;
}
}
}
public class Room : MonoBehaviour
{
public GameObject SpawnPoint;
public ActivateArena Arena;
public EnemySpawnPoint[] SpawnPoints;
public bool RoomHasGameplay = true;
[HideInInspector]
public bool RoomAlreadyVisited;
[Space(15f)]
[Header("Make sure that you have 4 chimneys, one for each colour.")]
public List<Chimney> Chimneys = new List<Chimney>();
[Space(15f)]
[Header("Make sure that you have 10 presents (10 is the maximum, random ones will be chosen)")]
public List<Present> Presents = new List<Present>();
[HideInInspector]
public int[] PresentColourAmounts = new int[4];
[HideInInspector]
public List<Collider> EnvColliders = new List<Collider>();
[HideInInspector]
public List<EnemyIdentifier> Enemies = new List<EnemyIdentifier>();
[HideInInspector]
public bool RoomCleared;
[HideInInspector]
public bool RoomActivated;
public Dictionary<WeaponVariant, Chimney> AllChimneys = new Dictionary<WeaponVariant, Chimney>
{
{
(WeaponVariant)0,
null
},
{
(WeaponVariant)1,
null
},
{
(WeaponVariant)2,
null
},
{
(WeaponVariant)3,
null
}
};
public Dictionary<WeaponVariant, int> AmountDelivered = new Dictionary<WeaponVariant, int>
{
{
(WeaponVariant)0,
0
},
{
(WeaponVariant)1,
0
},
{
(WeaponVariant)2,
0
},
{
(WeaponVariant)3,
0
}
};
private Dictionary<EnemyType, int> _amountSpawned = new Dictionary<EnemyType, int>();
private int _pointsLeft;
private int _meleeSpawnsUsed;
private int _projectileSpawnsUsed;
private int _wavesSinceSpecial;
public bool ChimneysDone => AmountDelivered.All((KeyValuePair<WeaponVariant, int> kvp) => PresentColourAmounts[kvp.Key] <= kvp.Value);
public bool AllDead => Enemies.All((EnemyIdentifier enemy) => enemy?.dead ?? true);
public bool Done(WeaponVariant colour)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
return AmountDelivered[colour] == PresentColourAmounts[colour];
}
public void Deliver(WeaponVariant colour)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: 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)
MonoSingleton<GameManager>.Instance.DeliveredPresents++;
AmountDelivered[colour]++;
if (ChimneysDone)
{
CompleteRoom();
}
}
private void CompleteRoom()
{
foreach (Chimney value in AllChimneys.Values)
{
if (value != null)
{
((Component)value.JumpPad).gameObject.SetActive(false);
}
}
}
public void Initialize()
{
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
if (RoomHasGameplay)
{
PresentColourAmounts = GenerationEquations.DistributeBetween(4, GenerationEquations.PresentAmount(MonoSingleton<GameManager>.Instance.RoomsEntered));
}
DecideChimneyColours();
DecidePresentColours();
DecideSpawnPointEnemies();
for (int i = 0; i < PresentColourAmounts.Length; i++)
{
Chimney chimney = AllChimneys[(WeaponVariant)i];
if ((Object)(object)chimney != (Object)null)
{
chimney.AmountToDeliver = PresentColourAmounts[i];
}
}
if (ChimneysDone)
{
CompleteRoom();
}
Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
foreach (Collider val in componentsInChildren)
{
if (LayerMaskDefaults.Get((LMD)1).Contains(((Component)val).gameObject.layer))
{
EnvColliders.Add(val);
}
}
}
private void DecideChimneyColours()
{
//IL_0002: 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_002e: 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_003e: 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)
WeaponVariant val = (WeaponVariant)0;
foreach (Chimney item in Chimneys.Shuffle())
{
AllChimneys[val] = item;
item.SetColour(val);
item.Room = this;
val = (WeaponVariant)(val + 1);
}
}
private void DecidePresentColours()
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
Dictionary<WeaponVariant, int> dictionary = new Dictionary<WeaponVariant, int>();
for (int i = 0; i < PresentColourAmounts.Length; i++)
{
if (PresentColourAmounts[i] != 0)
{
dictionary.Add((WeaponVariant)i, PresentColourAmounts[i]);
}
}
foreach (Present item in Presents.Shuffle())
{
if (dictionary.Count != 0)
{
KeyValuePair<WeaponVariant, int> keyValuePair = dictionary.ToList().Pick();
item.SetColour(keyValuePair.Key);
dictionary[keyValuePair.Key]--;
if (dictionary[keyValuePair.Key] == 0)
{
dictionary.Remove(keyValuePair.Key);
}
}
else
{
((Component)item).gameObject.SetActive(false);
}
}
}
private void DecideSpawnPointEnemies()
{
_pointsLeft = MonoSingleton<GameManager>.Instance.PointsPerWave;
Debug.Log((object)$"Spawning enemies: starts with {_pointsLeft}");
List<EnemySpawnPoint> projectile = SpawnPoints.Where((EnemySpawnPoint sp) => sp.Class == DeliveryEnemyClass.Projectile).ShuffleAndToList();
List<EnemySpawnPoint> list = SpawnPoints.Where((EnemySpawnPoint sp) => sp.Class == DeliveryEnemyClass.Melee).ShuffleAndToList();
if (MonoSingleton<GameManager>.Instance.RoomsEntered > 10)
{
int max = MonoSingleton<GameManager>.Instance.RoomsEntered / 10 + 1;
DecideUncommons(list, ref max);
if (MonoSingleton<GameManager>.Instance.RoomsEntered >= 15)
{
DecideSpecials(list, ref max);
}
}
DecideNormalMeleeAndProjectile(projectile, list);
}
private void DecideUncommons(List<EnemySpawnPoint> spawns, ref int max)
{
int num = Random.Range(1, max + 1);
max -= num;
Debug.Log((object)$"Spawning {num} uncommons!");
List<EndlessEnemy> list = GetPotentialEnemies(EnemyGroup.Groups[DeliveryEnemyClass.Uncommon]).ShuffleAndToList();
foreach (EndlessEnemy item in list)
{
Debug.Log((object)(" uc" + ((Object)item.prefab).name));
}
while (list.Count > 2)
{
list.RemoveAt(list.Count - 1);
}
if (list.Count == 0)
{
return;
}
if (list.Count == 1)
{
list.Add(list[0]);
}
Debug.Log((object)("Uncommons are " + ((Object)list[0].prefab).name + " and " + ((Object)list[1].prefab).name + "!!"));
int[] array = new int[2];
for (int i = 0; i < num; i++)
{
if (_meleeSpawnsUsed == spawns.Count)
{
Debug.Log((object)$"broke2 with {_pointsLeft}");
break;
}
if (GetRealCost(list[0]) >= _pointsLeft && GetRealCost(list[1]) >= _pointsLeft)
{
Debug.Log((object)"uncommon break | cant afford");
break;
}
int num2 = ((!(Random.value > 0.5f)) ? 1 : 0);
if (GetRealCost(list[0]) >= _pointsLeft)
{
num2 = 1;
}
if (GetRealCost(list[1]) >= _pointsLeft)
{
num2 = 0;
}
array[num2]++;
SetSpawnPoint(spawns[_meleeSpawnsUsed], list[num2], DeliveryEnemyClass.Melee);
}
}
private void DecideSpecials(List<EnemySpawnPoint> spawns, ref int max)
{
int num = Random.Range(0, max + 1);
if (num == 0)
{
if (Random.value < 1f - 1f / (float)_wavesSinceSpecial)
{
num++;
}
_wavesSinceSpecial++;
}
max -= num;
Debug.Log((object)$"Spawning {num} specials!");
foreach (EndlessEnemy item in GetPotentialEnemies(EnemyGroup.Groups[DeliveryEnemyClass.Special]).ShuffleAndToList())
{
Debug.Log((object)$" {item}");
}
for (int i = 0; i < num; i++)
{
if (_meleeSpawnsUsed == spawns.Count)
{
Debug.Log((object)$"broke1 with {_pointsLeft}");
break;
}
List<EndlessEnemy> list = GetPotentialEnemies(EnemyGroup.Groups[DeliveryEnemyClass.Special]).ShuffleAndToList();
if (list.Count == 0)
{
break;
}
SetSpawnPoint(spawns[_meleeSpawnsUsed], list[0], DeliveryEnemyClass.Melee);
}
}
private void DecideNormalMeleeAndProjectile(List<EnemySpawnPoint> projectile, List<EnemySpawnPoint> melee)
{
while (_pointsLeft != 0)
{
Debug.Log((object)$"has {_pointsLeft} points left!");
if (_projectileSpawnsUsed == projectile.Count && _meleeSpawnsUsed == melee.Count)
{
Debug.Log((object)$"broke with {_pointsLeft}");
break;
}
DeliveryEnemyClass deliveryEnemyClass = ((!((double)Random.value < 0.5)) ? DeliveryEnemyClass.Projectile : DeliveryEnemyClass.Melee);
if (_projectileSpawnsUsed >= projectile.Count)
{
deliveryEnemyClass = DeliveryEnemyClass.Melee;
}
if (_meleeSpawnsUsed >= melee.Count)
{
deliveryEnemyClass = DeliveryEnemyClass.Projectile;
}
IEnumerable<EndlessEnemy> potentialEnemies = GetPotentialEnemies(EnemyGroup.Groups[deliveryEnemyClass]);
foreach (EndlessEnemy item in potentialEnemies)
{
Debug.Log((object)(" pm " + ((Object)item.prefab).name));
}
EndlessEnemy val = potentialEnemies.ToList().Pick();
if ((Object)(object)val == (Object)null)
{
break;
}
EnemySpawnPoint point = ((deliveryEnemyClass == DeliveryEnemyClass.Melee) ? melee[_meleeSpawnsUsed] : projectile[_projectileSpawnsUsed]);
SetSpawnPoint(point, val, deliveryEnemyClass);
Debug.Log((object)$"now at {_pointsLeft}");
}
}
private IEnumerable<EndlessEnemy> GetPotentialEnemies(EnemyGroup group)
{
EndlessEnemy[] enemies = group.Enemies;
foreach (EndlessEnemy enemy in enemies)
{
if (enemy.spawnWave <= MonoSingleton<GameManager>.Instance.RoomsEntered && GetRealCost(enemy) <= _pointsLeft)
{
yield return enemy;
}
}
}
private void SetSpawnPoint(EnemySpawnPoint point, EndlessEnemy enemy, DeliveryEnemyClass spawnType)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//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_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
point.Room = this;
point.Enemy = enemy.prefab;
_pointsLeft -= GetRealCost(enemy);
Debug.Log((object)$"just spent {GetRealCost(enemy)}");
_amountSpawned.TryAdd(enemy.enemyType, 0);
_amountSpawned[enemy.enemyType]++;
switch (spawnType)
{
case DeliveryEnemyClass.Melee:
_meleeSpawnsUsed++;
break;
case DeliveryEnemyClass.Projectile:
_projectileSpawnsUsed++;
break;
}
Arena.enemies = CollectionExtensions.AddToArray<GameObject>(Arena.enemies, ((Component)point).gameObject);
}
private int GetRealCost(EndlessEnemy enemy)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
int num = (_amountSpawned.ContainsKey(enemy.enemyType) ? _amountSpawned[enemy.enemyType] : 0);
return enemy.spawnCost + enemy.costIncreasePerSpawn * num;
}
private void OnTriggerEnter(Collider collider)
{
if ((Object)(object)((Component)collider).GetComponent<NewMovement>() != (Object)null && !RoomActivated)
{
RoomActivated = true;
MonoSingleton<GameManager>.Instance.SetRoom(this);
ActivateArena arena = Arena;
if (arena != null)
{
arena.Activate();
}
}
}
}
public class RoomData : ScriptableObject
{
public string Name = "My Super Cool Room";
public string Author = "Waffle";
[Space(15f)]
public GameObject Prefab;
}
public class RoomPool : ScriptableObject
{
public RoomData[] Rooms;
}
[PatchThis("$waffle.ultrakill.christmasdelivery.TimeBonusPatches")]
public class TimeBonusPatches
{
[HarmonyPatch(typeof(StyleCalculator), "AddPoints")]
[HarmonyPrefix]
private static void AddBigKillTime(ref string pointName)
{
if (AddressableManager.InSceneFromThisMod && pointName == "ultrakill.bigkill")
{
MonoSingleton<GameManager>.Instance.AddTime(2f, "<color=orange>BIG KILL</color>");
pointName = "";
}
}
}
}
namespace EndlessDelivery.Gameplay.EnemyGeneration
{
public static class Act3EnemyHack
{
private static bool _hasAdded;
public static void AddToPools(params EnemyGroup[] groups)
{
if (!_hasAdded)
{
_hasAdded = true;
PrefabDatabase database = AddressableManager.Load<PrefabDatabase>("Assets/Data/Cyber Grind Patterns/Data/Prefab Database.asset");
foreach (EnemyGroup group in groups)
{
AddEnemies(group, database);
}
}
}
private static void AddEnemies(EnemyGroup group, PrefabDatabase database)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Invalid comparison between Unknown and I4
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Invalid comparison between Unknown and I4
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Invalid comparison between Unknown and I4
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
List<EndlessEnemy> list = group.Enemies.ToList();
switch (group.Class)
{
case DeliveryEnemyClass.Projectile:
{
EndlessEnemy[] projectileEnemies = database.projectileEnemies;
foreach (EndlessEnemy val2 in projectileEnemies)
{
EnemyType enemyType = val2.enemyType;
if (((int)enemyType == 31 || (int)enemyType == 33) ? true : false)
{
Debug.Log((object)$"Added {val2.enemyType} to {((Object)group).name}!");
list.Add(val2);
}
}
break;
}
case DeliveryEnemyClass.Uncommon:
{
EndlessEnemy[] uncommonEnemies = database.uncommonEnemies;
foreach (EndlessEnemy val in uncommonEnemies)
{
if ((int)val.enemyType == 34)
{
Debug.Log((object)$"Added {val.enemyType} to {((Object)group).name}!");
list.Add(val);
}
}
break;
}
}
group.Enemies = list.ToArray();
}
}
public enum DeliveryEnemyClass
{
Melee,
Projectile,
Uncommon,
Special,
Boss
}
public class EnemyGroup : ScriptableObject
{
public static Dictionary<DeliveryEnemyClass, EnemyGroup> Groups = new Dictionary<DeliveryEnemyClass, EnemyGroup>();
public DeliveryEnemyClass Class;
[Space(10f)]
public EndlessEnemy[] Enemies;
public static void SetGroups(IEnumerable<EnemyGroup> groups)
{
foreach (EnemyGroup group in groups)
{
Groups.Add(group.Class, group);
}
}
}
public class EnemySpawnPoint : MonoBehaviour
{
[Header("SpawnPoints should only be Melee, Projectile, or Boss.")]
public DeliveryEnemyClass Class;
[HideInInspector]
public GameObject Enemy;
[HideInInspector]
public Room Room;
private void Awake()
{
((Component)this).gameObject.SetActive(false);
}
private void OnEnable()
{
Room.Enemies.Add(Object.Instantiate<GameObject>(Enemy, ((Component)this).transform).GetComponent<EnemyIdentifier>());
}
}
}
namespace EndlessDelivery.Config
{
public class Option
{
protected static Dictionary<string, object> AllOptionValues = new Dictionary<string, object>();
public static Dictionary<string, Option> AllOptions = new Dictionary<string, Option>
{
{
"start_wave",
new Option<long>("start_wave", 0L)
},
{
"disable_copyrighted_music",
new Option<bool>("disable_copyrighted_music", defaultValue: false)
}
};
public static string SavePath => Path.Combine(PathUtils.ModPath(), "Savedata");
public static string OptionFilePath => Path.Combine(SavePath, "settings.json");
public static T GetValue<T>(string id)
{
return (AllOptions[id] as Option<T>).Value;
}
public static void Save()
{
Directory.CreateDirectory(SavePath);
File.WriteAllText(OptionFilePath, JsonConvert.SerializeObject((object)AllOptionValues));
}
public static void Load()
{
if (File.Exists(OptionFilePath))
{
AllOptionValues = JsonConvert.DeserializeObject<Dictionary<string, object>>(File.ReadAllText(OptionFilePath));
}
}
}
public class Option<T> : Option
{
private string _id;
private T _defaultValue;
public T Value
{
get
{
if (!Option.AllOptionValues.ContainsKey(_id))
{
Option.AllOptionValues.Add(_id, _defaultValue);
}
return (T)Option.AllOptionValues[_id];
}
set
{
if (!Option.AllOptionValues.ContainsKey(_id))
{
Option.AllOptionValues.Add(_id, value);
}
else
{
Option.AllOptionValues[_id] = value;
}
}
}
public Option(string id, T defaultValue)
{
_id = id;
_defaultValue = defaultValue;
}
}
}
namespace EndlessDelivery.Config.Elements
{
public class BoolElement : MonoBehaviour
{
public TMP_Text EnabledText;
public string Id;
public UltrakillEvent OnToggled;
private Option<bool> _option;
private void Start()
{
_option = (Option<bool>)Option.AllOptions[Id];
UpdateText();
}
public void Toggle()
{
_option.Value = !_option.Value;
UpdateText();
}
private void UpdateText()
{
EnabledText.text = (_option.Value ? "ENABLED" : "DISABLED");
if (_option.Value)
{
OnToggled.Invoke();
}
else
{
OnToggled.Revert();
}
}
}
public class RoomElement : MonoBehaviour
{
public TMP_Text RoomText;
public TMP_Text TimeText;
private Option<long> _option;
private void Start()
{
_option = (Option<long>)Option.AllOptions["start_wave"];
UpdateText();
}
public void ChangeBy(int change)
{
int num = Mathf.Min(Score.Highscore.Rooms / 2, BestTimes.Times.Count);
_option.Value = Mathf.Clamp((int)(_option.Value + change), 0, num);
UpdateText();
}
private void UpdateText()
{
RoomText.text = $"ROOM {_option.Value}";
TimeText.text = TimeSpan.FromSeconds(BestTimes.GetRoomTime((int)_option.Value)).Formatted();
}
}
}
namespace EndlessDelivery.Components
{
public class Chimney : MonoBehaviour
{
public GameObject Glow;
public TMP_Text DeliveredText;
public int AmountToDeliver;
public JumpPad JumpPad;
public AudioSource DeliverSound;
public Animator Animator;
public GameObject Teleporter;
public ParticleSystem Particles;
[HideInInspector]
public Room Room;
private Renderer _glowRenderer;
private float _glowAlpha;
private Coroutine _currentAnimation;
private bool _chimneyEntered;
[field: SerializeField]
public WeaponVariant VariantColour { get; private set; }
private Color _color => ColourSetter.DefaultColours[VariantColour];
private void Start()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
SetRenderer();
SetColour(VariantColour);
}
private void SetRenderer()
{
_glowRenderer = Glow.GetComponent<Renderer>();
_glowAlpha = _glowRenderer.material.GetFloat("_OpacScale");
}
public void SetColour(WeaponVariant colour)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: 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)
if ((Object)(object)_glowRenderer == (Object)null)
{
SetRenderer();
}
VariantColour = colour;
Particles.startColor = _color;
_glowRenderer.material.color = _color;
}
private void Update()
{
//IL_003c: 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 (!((Object)(object)DeliveredText == (Object)null) && !((Object)(object)Room == (Object)null))
{
DeliveredText.text = $"{Room.AmountDelivered[VariantColour]}/{AmountToDeliver}";
((Graphic)DeliveredText).color = _color;
}
}
private void DeliverEffect()
{
DeliverSound.Play();
if (_currentAnimation != null)
{
((MonoBehaviour)this).StopCoroutine(_currentAnimation);
}
_currentAnimation = ((MonoBehaviour)this).StartCoroutine(DeliverEffectAnimation());
}
private IEnumerator DeliverEffectAnimation()
{
Animator.Play("Glow Animation");
yield return (object)new WaitForSeconds(1f / 6f);
Material glowMaterial = _glowRenderer.material;
while (glowMaterial.GetFloat("_OpacScale") != 0f)
{
glowMaterial.SetFloat("_OpacScale", Mathf.MoveTowards(glowMaterial.GetFloat("_OpacScale"), 0f, Time.deltaTime * 2f));
yield return null;
}
if (!Room.Done(VariantColour))
{
yield return (object)new WaitForSeconds(1f);
while (glowMaterial.GetFloat("_OpacScale") != _glowAlpha)
{
glowMaterial.SetFloat("_OpacScale", Mathf.MoveTowards(glowMaterial.GetFloat("_OpacScale"), _glowAlpha, Time.deltaTime));
yield return null;
}
yield break;
}
Vector3 target = DeliveredText.transform.localScale;
target.y = 0f;
while (glowMaterial.GetFloat("_OpacScale") != _glowAlpha / 2f)
{
glowMaterial.SetFloat("_OpacScale", Mathf.MoveTowards(glowMaterial.GetFloat("_OpacScale"), _glowAlpha / 2f, Time.deltaTime));
yield return null;
}
while (DeliveredText.transform.localScale.y != 0f)
{
DeliveredText.transform.localScale = Vector3.MoveTowards(DeliveredText.transform.localScale, target, Time.deltaTime * 2f);
yield return null;
}
}
private void OnTriggerEnter(Collider collider)
{
//IL_000f: 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)
Present present = default(Present);
if (((Component)collider).TryGetComponent<Present>(ref present) && present.VariantColour == VariantColour && !present.Destroyed)
{
present.Deliver(this);
DeliverEffect();
}
if ((Object)(object)((Component)collider).GetComponent<NewMovement>() != (Object)null && Room.ChimneysDone)
{
ChimneyEnter();
}
EnemyIdentifierIdentifier val = default(EnemyIdentifierIdentifier);
if (((Component)collider).gameObject.TryGetComponent<EnemyIdentifierIdentifier>(ref val))
{
EnemyIdentifier eid = val.eid;
if (eid == null || eid.dead)
{
Object.Destroy((Object)(object)((Component)collider).gameObject);
}
}
}
public void ChimneyEnter()
{
//IL_0030: 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 (_chimneyEntered)
{
return;
}
MonoSingleton<GameManager>.Instance.RoomEnd();
MonoSingleton<NewMovement>.Instance.rb.velocity = MonoSingleton<NewMovement>.Instance.rb.velocity.Only(Axis.Y);
((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = false;
((Behaviour)MonoSingleton<NewMovement>.Instance.gc).enabled = false;
foreach (Collider envCollider in MonoSingleton<GameManager>.Instance.PreviousRoom.EnvColliders)
{
Physics.IgnoreCollision((Collider)(object)MonoSingleton<NewMovement>.Instance.playerCollider, envCollider, true);
}
((Behaviour)((Component)MonoSingleton<NewMovement>.Instance).GetComponent<KeepInBounds>()).enabled = false;
MonoSingleton<PlayerChimneyFixer>.Instance.EnterChimney(this);
_chimneyEntered = true;
}
public void ChimneyLeave()
{
((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = true;
((Behaviour)MonoSingleton<NewMovement>.Instance.gc).enabled = true;
((Behaviour)((Component)MonoSingleton<NewMovement>.Instance).GetComponent<KeepInBounds>()).enabled = true;
MonoSingleton<PlayerChimneyFixer>.Instance.Exit();
}
public void WarpPlayerToNextRoom()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: 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)
Object.Destroy((Object)(object)((Component)MonoSingleton<GameManager>.Instance.PreviousRoom).gameObject);
Vector3 vector = ((Component)MonoSingleton<NewMovement>.Instance).transform.position - Teleporter.transform.position;
((Component)MonoSingleton<NewMovement>.Instance).transform.position = MonoSingleton<GameManager>.Instance.CurrentRoom.SpawnPoint.transform.position + vector.Only(Axis.X, Axis.Z);
MonoSingleton<PlayerChimneyFixer>.Instance.EnterChimney(null);
}
}
[PatchThis("waffle.ultrakill.christmasdelivery.MauriceFitter")]
public class MauriceFitter : MonoBehaviour
{
private float _startHeight;
private float _targetHeight;
private EnemyIdentifier _eid;
private void Start()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
_startHeight = ((Component)this).transform.localPosition.y;
_eid = ((Component)this).GetComponent<EnemyIdentifier>();
}
private void Update()
{
//IL_0021: 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_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
if (!_eid.dead)
{
RaycastHit val = default(RaycastHit);
if (Physics.Raycast(((Component)this).transform.parent.position, Vector3.up, ref val, 20f, LayerMask.op_Implicit(LayerMaskDefaults.Get((LMD)1))))
{
_targetHeight = ((RaycastHit)(ref val)).distance - 1f;
}
else
{
_targetHeight = _startHeight;
}
((Component)this).transform.localPosition = Vector3.MoveTowards(((Component)this).transform.localPosition, ((Component)this).transform.localPosition.Only(Axis.X, Axis.Z) + Vector3.up * _targetHeight, Time.deltaTime * 5f);
}
}
[HarmonyPatch(typeof(SpiderBody), "Start")]
[HarmonyPostfix]
private static void AddMauriceFitter(SpiderBody __instance)
{
if (AddressableManager.InSceneFromThisMod)
{
((Component)__instance).gameObject.AddComponent<MauriceFitter>();
}
}
}
[PatchThis("waffle.ultrakill.christmasdelivery.Present")]
public class Present : MonoBehaviour
{
private static List<Collider> _allPresentColliders = new List<Collider>();
public WeaponVariant VariantColour;
public GameObject Particles;
public SpriteRenderer Glow;
private ItemIdentifier _item;
private Collider _collider;
[HideInInspector]
public bool Destroyed;
private Color _colour => ColourSetter.DefaultColours[VariantColour];
private void Start()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
_collider = ((Component)this).GetComponent<Collider>();
_item = ((Component)this).GetComponent<ItemIdentifier>();
_allPresentColliders.Add(_collider);
SetColour(VariantColour);
}
private void Update()
{
((Component)Glow).gameObject.layer = 0;
}
private void OnDisable()
{
_allPresentColliders.Remove(_collider);
}
private void OnDestroy()
{
_allPresentColliders.Remove(_collider);
}
public void SetColour(WeaponVariant colour)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: 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_0038: 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_0055: 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)
VariantColour = colour;
((Component)this).GetComponent<Renderer>().material.color = _colour;
((Component)this).GetComponent<Light>().color = _colour;
((Component)this).GetComponent<ParticleSystem>().startColor = _colour;
Glow.color = new Color(_colour.r, _colour.g, _colour.b, 0.5f);
}
public void Deliver(Chimney chimney)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
chimney.Room.Deliver(VariantColour);
MonoSingleton<GameManager>.Instance.AddTime(6f, "<color=#" + ColorUtility.ToHtmlStringRGB(_colour) + ">DELIVERY</color>");
CreateParticles();
Destroyed = true;
if (_item.hooked)
{
MonoSingleton<HookArm>.Instance.StopThrow(0f, false);
}
if ((Object)(object)MonoSingleton<FistControl>.Instance.currentPunch.heldItem == (Object)(object)_item)
{
MonoSingleton<FistControl>.Instance.currentPunch.ForceThrow();
}
Object.Destroy((Object)(object)_item);
((Component)this).GetComponent<Collider>().enabled = false;
((Component)this).GetComponent<Rigidbody>().detectCollisions = false;
((MonoBehaviour)this).StartCoroutine(DestroyAnimation());
}
public void CreateParticles()
{
//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_0029: 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)
ParticleSystem component = Object.Instantiate<GameObject>(Particles, ((Component)this).transform.position, Quaternion.identity).GetComponent<ParticleSystem>();
((Component)component).GetComponentInChildren<Light>().color = _colour;
component.startColor = _colour;
}
private IEnumerator DestroyAnimation()
{
yield return (object)new WaitForSeconds(0.25f);
while (((Component)this).transform.localScale != Vector3.zero)
{
((Component)this).transform.localScale = Vector3.MoveTowards(((Component)this).transform.localScale, Vector3.zero, Time.deltaTime * 2f);
yield return null;
}
Object.Destroy((Object)(object)((Component)this).gameObject);
}
private void OnTriggerStay(Collider collider)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: 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_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
Chimney chimney = default(Chimney);
if (!Destroyed && ((Component)collider).TryGetComponent<Chimney>(ref chimney) && chimney.VariantColour != VariantColour)
{
Vector3 vector = (((Component)MonoSingleton<NewMovement>.Instance).transform.position - ((Component)this).transform.position) * 2.5f;
Vector3 velocity = Vector3.up * 25f + vector.Only(Axis.X, Axis.Z);
((Component)this).GetComponent<Rigidbody>().velocity = velocity;
}
}
[HarmonyPatch(typeof(Explosion), "Start")]
[HarmonyPostfix]
private static void DisableExplosionToPresentCollisions(Explosion __instance)
{
if (!AddressableManager.InSceneFromThisMod)
{
return;
}
foreach (Collider allPresentCollider in _allPresentColliders)
{
Physics.IgnoreCollision(allPresentCollider, (Collider)(object)__instance.scol);
}
}
}
public class PresentDragZone : MonoBehaviour
{
public float PullStrength;
public Chimney Chimney;
private void OnTriggerStay(Collider collider)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: 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_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: 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_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)
//IL_007d: 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_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: 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_00a9: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
Present present = default(Present);
if (((Component)collider).TryGetComponent<Present>(ref present) && present.VariantColour == Chimney.VariantColour)
{
Rigidbody component = ((Component)collider).GetComponent<Rigidbody>();
Vector3 val = (((Component)collider).transform.position - ((Component)this).transform.position).Only(Axis.X, Axis.Z);
Vector3 val2 = -((Vector3)(ref val)).normalized;
Vector3 velocity = component.velocity;
Vector3 val3 = val2 * ((Vector3)(ref velocity)).magnitude + component.velocity.y * Vector3.up * 1.25f;
component.velocity = Vector3.MoveTowards(component.velocity, val3, Time.deltaTime * PullStrength);
}
}
}
public class PreventItemHooking : MonoBehaviour
{
public float EnableWhippingAtDistance = 7f;
private void Update()
{
//IL_001d: 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)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Invalid comparison between Unknown and I4
if (((Component)this).gameObject.layer != 13)
{
if (Vector3.Distance(((Component)this).transform.position, ((Component)MonoSingleton<NewMovement>.instance).transform.position) <= EnableWhippingAtDistance)
{
((Component)this).gameObject.layer = 22;
}
else
{
((Component)this).gameObject.layer = (((int)MonoSingleton<HookArm>.Instance.state != 1) ? 22 : 0);
}
}
}
}
public class RandomToggler : MonoBehaviour
{
public List<GameObject> Objects;
private void Start()
{
foreach (GameObject @object in Objects)
{
@object.SetActive(false);
}
Objects.Pick().SetActive(true);
}
}
}
namespace EndlessDelivery.Cheats
{
[PatchThis("waffle.ultrakill.christmasdelivery.CheatManager")]
public static class CheatManager
{
[HarmonyPatch(typeof(CheatsManager), "Start")]
[HarmonyPrefix]
private static void AddIfShould(CheatsManager __instance)
{
if (AddressableManager.InSceneFromThisMod)
{
__instance.RegisterExternalCheat((ICheat)(object)new CompleteRoom());
__instance.RegisterExternalCheat((ICheat)(object)new InfiniteTime());
}
}
}
public class CompleteRoom : ICheat
{
public string LongName => "Deliver All Presents";
public string Identifier => "waffle.ultrakill.christmasdelivery.deliverall";
public string ButtonEnabledOverride => null;
public string ButtonDisabledOverride => "DELIVER";
public string Icon => "death";
public bool IsActive => false;
public bool DefaultState => false;
public StatePersistenceMode PersistenceMode => (StatePersistenceMode)0;
public void Enable()
{
MonoSingleton<GameManager>.Instance.CurrentRoom.AmountDelivered = new Dictionary<WeaponVariant, int>
{
{
(WeaponVariant)0,
10
},
{
(WeaponVariant)1,
10
},
{
(WeaponVariant)2,
10
},
{
(WeaponVariant)3,
10
}
};
foreach (Chimney chimney in MonoSingleton<GameManager>.Instance.CurrentRoom.Chimneys)
{
((Component)chimney.JumpPad).gameObject.SetActive(false);
}
}
public void Disable()
{
}
public void Update()
{
}
}
public class InfiniteTime : ICheat
{
private bool _active;
public string LongName => "Infinite Time";
public string Identifier => "waffle.ultrakill.christmasdelivery.inftime";
public string ButtonEnabledOverride { get; }
public string ButtonDisabledOverride { get; }
public string Icon => "death";
public bool IsActive => _active;
public bool DefaultState { get; }
public StatePersistenceMode PersistenceMode => (StatePersistenceMode)0;
public void Enable()
{
_active = true;
}
public void Disable()
{
_active = false;
}
public void Update()
{
MonoSingleton<GameManager>.Instance.SilentAddTime(Time.deltaTime);
}
}
}
namespace EndlessDelivery.Assets
{
[PatchThis("waffle.ultrakill.christmasdelivery.AddressableManager")]
public static class AddressableManager
{
private static List<string> _scenesFromThisMod;
private static bool _dontSanitizeScenes;
public static string AssetPathLocation => "{" + typeof(AddressableManager).FullName + ".AssetPath}";
public static string MonoScriptBundleName => "monoscript_endlessdelivery_monoscripts.bundle";
public static string AssetPath => Path.Combine(PathUtils.ModPath(), "Assets");
public static string CatalogPath => Path.Combine(AssetPath, "catalog.json");
public static string ModDataPath => Path.Combine(AssetPath, "data.json");
public static bool InSceneFromThisMod => _scenesFromThisMod.Contains(SceneHelper.CurrentScene);
public static void Setup()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Addressables.LoadContentCatalogAsync(CatalogPath, true, (string)null).WaitForCompletion();
LoadDataFile();
}
private static void LoadDataFile()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
Dictionary<string, List<string>> dictionary = null;
using (StreamReader streamReader = new StreamReader(File.OpenRead(ModDataPath)))
{
JsonSerializer val = new JsonSerializer();
dictionary = val.Deserialize<Dictionary<string, List<string>>>((JsonReader)new JsonTextReader((TextReader)streamReader));
}
if (dictionary.ContainsKey(typeof(EnemyGroup).FullName))
{
EnemyGroup.SetGroups(GetDataOfType<EnemyGroup>(dictionary));
}
if (dictionary.ContainsKey(typeof(Scene).FullName))
{
_scenesFromThisMod = dictionary[typeof(Scene).FullName];
}
}
private static IEnumerable<T> GetDataOfType<T>(Dictionary<string, List<string>> data) where T : Object
{
if (!data.ContainsKey(typeof(T).FullName))
{
return Array.Empty<T>();
}
return data[typeof(T).FullName].Select(Load<T>);
}
public static T Load<T>(string path)
{
//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)
return Addressables.LoadAssetAsync<T>((object)path).WaitForCompletion();
}
public static void LoadScene(string path)
{
_dontSanitizeScenes = true;
try
{
SceneHelper.LoadScene(path, false);
}
catch (Exception ex)
{
Debug.LogError((object)ex.ToString());
}
_dontSanitizeScenes = false;
}
[HarmonyPatch(typeof(SceneHelper), "SanitizeLevelPath")]
[HarmonyPrefix]
private static bool PreventSanitization(string scene, ref string __result)
{
if (_dontSanitizeScenes)
{
__result = scene;
return false;
}
return true;
}
}
}
namespace EndlessDelivery.Anticheat
{
public abstract class Anticheat
{
private static List<Anticheat> _anticheats = new List<Anticheat>
{
new DetectPresenceAnticheat(),
new MasqueradeDivinityAnticheat(),
new UltraTweakerAnticheat()
};
public static bool HasIllegalMods = !_anticheats.All((Anticheat ac) => ac.ShouldSubmit);
protected abstract bool ShouldSubmit { get; }
}
public class DetectPresenceAnticheat : Anticheat
{
private string[] _mods = new string[4] { "ironfarm.uk.uc", "ironfarm.uk.muda", "plonk.rocketgatling", "maranara_whipfix" };
protected override bool ShouldSubmit => _mods.All((string mod) => !Chainloader.PluginInfos.ContainsKey(mod));
}
public class MasqueradeDivinityAnticheat : Anticheat
{
public const string GUID = "maranara_project_prophet";
protected override bool ShouldSubmit
{
get
{
if (!Chainloader.PluginInfos.ContainsKey("maranara_project_prophet"))
{
return true;
}
return GabeOn();
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private bool GabeOn()
{
return ProjectProphet.gabeOn;
}
}
public class UltraTweakerAnticheat : Anticheat
{
private const string GUID = "waffle.ultrakill.ultratweaker";
protected override bool ShouldSubmit
{
get
{
if (!Chainloader.PluginInfos.ContainsKey("waffle.ultrakill.ultratweaker"))
{
return true;
}
if (HasBadTweaks())
{
return false;
}
return true;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private bool HasBadTweaks()
{
foreach (Tweak value in UltraTweaker.AllTweaks.Values)
{
Attribute? customAttribute = Attribute.GetCustomAttribute(((object)value).GetType(), typeof(TweakMetadata));
TweakMetadata val = (TweakMetadata)(object)((customAttribute is TweakMetadata) ? customAttribute : null);
if (value.IsEnabled && (val == null || !val.AllowCG))
{
return true;
}
}
return false;
}
}
}