using System;
using System.Collections;
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;
using Challenges;
using Challenges.ChallengeScripts;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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;
}
}
}
public class ChallengeKiosk : MonoBehaviourPun, IInteractibleConstant, IInteractible
{
public float interactTime = 0.5f;
public GameObject challengesGUI;
private MaterialPropertyBlock mpb;
private MeshRenderer[] _mr;
private static readonly Action<MenuWindow> OpenMenu = AccessTools.MethodDelegate<Action<MenuWindow>>(AccessTools.Method(typeof(MenuWindow), "Open", (Type[])null, (Type[])null), (object)null, true);
private static MethodInfo _miLoadSceneProcess;
private MeshRenderer[] meshRenderers
{
get
{
if (_mr == null)
{
_mr = ((Component)this).GetComponentsInChildren<MeshRenderer>();
MonoBehaviour.print((object)_mr.Length);
}
return _mr;
}
set
{
_mr = value;
}
}
public bool holdOnFinish { get; }
public bool IsInteractible(Character interactor)
{
return true;
}
public void Awake()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
mpb = new MaterialPropertyBlock();
}
private void Start()
{
//IL_0020: 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)
if (GameHandler.GetService<NextLevelService>().Data.IsSome)
{
NextLevelData value = GameHandler.GetService<NextLevelService>().Data.Value;
Debug.Log((object)$"seconds left until next map... {((NextLevelData)(ref value)).SecondsLeft}");
}
GameHandler.GetService<RichPresenceService>().SetState((RichPresenceState)1);
}
public void Interact(Character interactor)
{
}
public void HoverEnter()
{
if (mpb == null)
{
return;
}
mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 1f);
for (int i = 0; i < meshRenderers.Length; i++)
{
if ((Object)(object)meshRenderers[i] != (Object)null)
{
((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
}
}
}
public void HoverExit()
{
if (mpb != null)
{
mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 0f);
for (int i = 0; i < meshRenderers.Length; i++)
{
((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
}
}
}
public Vector3 Center()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return ((Component)this).transform.position;
}
public Transform GetTransform()
{
return ((Component)this).transform;
}
public string GetInteractionText()
{
return LocalizedText.GetText("BOARDFLIGHT", true);
}
public string GetName()
{
return "CHALLENGE KIOSK";
}
public bool IsConstantlyInteractable(Character interactor)
{
return IsInteractible(interactor);
}
public float GetInteractTime(Character interactor)
{
return interactTime;
}
public void Interact_CastFinished(Character interactor)
{
ChallengesGUILoader.EnsureMenuReady();
if ((Object)(object)challengesGUI == (Object)null)
{
Debug.LogWarning((object)"ChallengeKiosk.Interact_CastFinished called without a linked challenges GUI instance.");
return;
}
MenuWindow component = challengesGUI.GetComponent<MenuWindow>();
if ((Object)(object)component == (Object)null)
{
Debug.LogWarning((object)"ChallengeKiosk.Interact_CastFinished could not find MenuWindow on challenges GUI instance.");
}
else
{
OpenMenu(component);
}
}
public void StartGame(int ascent)
{
ChallengeMultiplayerSync.RequestChallengeStart(ascent);
}
public void CancelCast(Character interactor)
{
}
public void ReleaseInteract(Character interactor)
{
}
[PunRPC]
public void LoadIslandMaster(int ascent)
{
if (PhotonNetwork.IsMasterClient)
{
ChallengeMultiplayerSync.HandleMasterStartRequest(ascent);
}
}
[PunRPC]
public void BeginIslandLoadRPC(string sceneName, int ascent)
{
BeginIslandLoad(sceneName, ascent);
}
internal static void BeginIslandLoad(string sceneName, int ascent)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
MenuWindow.CloseAllWindows();
GameHandler.AddStatus<SceneSwitchingStatus>((GameStatus)new SceneSwitchingStatus());
Debug.Log((object)("Begin scene load RPC: " + sceneName));
Ascents.currentAscent = ascent;
LoadingScreenHandler instance = RetrievableResourceSingleton<LoadingScreenHandler>.Instance;
IEnumerator enumerator = LoadSceneProcess_Internal(instance, sceneName, networked: true, yieldForCharacterSpawn: true, 0f);
instance.Load((LoadingScreenType)1, (Action)null, new IEnumerator[1] { enumerator });
}
internal static string DetermineSceneName()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
NextLevelService service = GameHandler.GetService<NextLevelService>();
string text = "WilIsland";
if (service != null && service.Data.IsSome)
{
text = SingletonAsset<MapBaker>.Instance.GetLevel(service.Data.Value.CurrentLevelIndex);
}
else if (PhotonNetwork.OfflineMode)
{
text = SingletonAsset<MapBaker>.Instance.GetLevel(0);
}
if (string.IsNullOrEmpty(text))
{
text = "WilIsland";
}
return text;
}
private static IEnumerator LoadSceneProcess_Internal(object handler, string sceneName, bool networked, bool yieldForCharacterSpawn, float delay)
{
if (handler == null)
{
throw new ArgumentNullException("handler");
}
if (_miLoadSceneProcess == null)
{
_miLoadSceneProcess = handler.GetType().GetMethod("LoadSceneProcess", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[4]
{
typeof(string),
typeof(bool),
typeof(bool),
typeof(float)
}, null);
if (_miLoadSceneProcess == null)
{
throw new MissingMethodException(handler.GetType().FullName, "LoadSceneProcess(string, bool, bool, float)");
}
}
return (_miLoadSceneProcess.Invoke(handler, new object[4] { sceneName, networked, yieldForCharacterSpawn, delay }) as IEnumerator) ?? throw new InvalidOperationException("LoadSceneProcess did not return an IEnumerator.");
}
}
public static class ChallengeMultiplayerSync
{
private sealed class CallbackTarget : IOnEventCallback, IInRoomCallbacks, IMatchmakingCallbacks
{
public void OnEvent(EventData photonEvent)
{
if (photonEvent != null)
{
switch (photonEvent.Code)
{
case 101:
HandleSelectionEvent(photonEvent.CustomData);
break;
case 102:
HandleStartRequestEvent(photonEvent.CustomData, photonEvent.Sender);
break;
case 103:
HandleStartConfirmedEvent(photonEvent.CustomData);
break;
}
}
}
public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
{
ApplySelectionFromProperties(propertiesThatChanged);
}
public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
}
public void OnPlayerLeftRoom(Player otherPlayer)
{
}
public void OnPlayerEnteredRoom(Player newPlayer)
{
}
public void OnMasterClientSwitched(Player newMasterClient)
{
}
public void OnFriendListUpdate(List<FriendInfo> friendList)
{
}
public void OnCreatedRoom()
{
}
public void OnCreateRoomFailed(short returnCode, string message)
{
}
public void OnJoinRoomFailed(short returnCode, string message)
{
}
public void OnJoinRandomFailed(short returnCode, string message)
{
}
public void OnLeftRoom()
{
}
public void OnJoinedRoom()
{
if (PhotonNetwork.CurrentRoom != null)
{
ApplySelectionFromProperties(((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties);
}
}
public void ApplySelectionFromProperties(Hashtable props)
{
if (props == null || ((Dictionary<object, object>)(object)props).Count == 0 || (!((Dictionary<object, object>)(object)props).ContainsKey((object)"challenge.selected") && !((Dictionary<object, object>)(object)props).ContainsKey((object)"challenge.ascent")))
{
return;
}
((Dictionary<object, object>)(object)props).TryGetValue((object)"challenge.selected", out object value);
((Dictionary<object, object>)(object)props).TryGetValue((object)"challenge.ascent", out object value2);
string text = value as string;
int? ascent = null;
if (value2 != null)
{
try
{
ascent = Convert.ToInt32(value2);
}
catch
{
ascent = null;
}
}
ChallengesGUILoader.ApplyNetworkSelection(string.IsNullOrEmpty(text) ? null : text, ascent);
}
private void HandleSelectionEvent(object payload)
{
if (!(payload is object[] array) || array.Length == 0)
{
return;
}
string text = array[0] as string;
int? ascent = null;
if (array.Length > 1 && array[1] != null)
{
try
{
ascent = Convert.ToInt32(array[1]);
}
catch
{
ascent = null;
}
}
ChallengesGUILoader.ApplyNetworkSelection(string.IsNullOrEmpty(text) ? null : text, ascent);
}
private void HandleStartRequestEvent(object payload, int sender)
{
if (PhotonNetwork.IsMasterClient)
{
int ascent;
try
{
ascent = Convert.ToInt32(payload);
}
catch
{
ascent = Ascents.currentAscent;
}
HandleMasterStartRequest(ascent);
}
}
private void HandleStartConfirmedEvent(object payload)
{
if (payload is object[] array && array.Length >= 2)
{
string text = array[0] as string;
int ascent;
try
{
ascent = Convert.ToInt32(array[1]);
}
catch
{
ascent = Ascents.currentAscent;
}
if (string.IsNullOrEmpty(text))
{
text = ChallengeKiosk.DetermineSceneName();
}
ChallengeKiosk.BeginIslandLoad(text, ascent);
}
}
}
private const byte SelectionEventCode = 101;
private const byte StartRequestEventCode = 102;
private const byte StartConfirmedEventCode = 103;
private const string SelectedChallengeProp = "challenge.selected";
private const string SelectedAscentProp = "challenge.ascent";
private static bool _initialized;
private static CallbackTarget _callbackTarget;
public static void Initialize()
{
if (!_initialized)
{
_callbackTarget = new CallbackTarget();
PhotonNetwork.AddCallbackTarget((object)_callbackTarget);
_initialized = true;
if (PhotonNetwork.CurrentRoom != null)
{
_callbackTarget.ApplySelectionFromProperties(((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties);
}
}
}
public static void BroadcastSelection(Challenge challenge)
{
//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_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_005e: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
Initialize();
if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
{
string text = ((challenge != null) ? challenge.id : string.Empty);
object obj = ((challenge != null) ? ((object)Ascents.currentAscent) : null);
object[] array = new object[2] { text, obj };
PhotonNetwork.RaiseEvent((byte)101, (object)array, new RaiseEventOptions
{
Receivers = (ReceiverGroup)1
}, SendOptions.SendReliable);
Hashtable val = new Hashtable
{
[(object)"challenge.selected"] = (string.IsNullOrEmpty(text) ? null : text),
[(object)"challenge.ascent"] = obj
};
PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
}
}
public static void NotifyAirportLoaded()
{
//IL_001b: 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_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
Initialize();
if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && PhotonNetwork.IsMasterClient)
{
Hashtable val = new Hashtable
{
[(object)"challenge.selected"] = null,
[(object)"challenge.ascent"] = null
};
PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
}
}
public static void RequestChallengeStart(int ascent)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0044: Expected O, but got Unknown
Initialize();
if (!PhotonNetwork.InRoom)
{
ChallengeKiosk.BeginIslandLoad(ChallengeKiosk.DetermineSceneName(), ascent);
return;
}
if (PhotonNetwork.IsMasterClient)
{
HandleMasterStartRequest(ascent);
return;
}
PhotonNetwork.RaiseEvent((byte)102, (object)ascent, new RaiseEventOptions
{
Receivers = (ReceiverGroup)2
}, SendOptions.SendReliable);
}
internal static void HandleMasterStartRequest(int ascent)
{
//IL_001d: 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_0024: 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_0033: Expected O, but got Unknown
string text = ChallengeKiosk.DetermineSceneName();
object[] array = new object[2] { text, ascent };
PhotonNetwork.RaiseEvent((byte)103, (object)array, new RaiseEventOptions
{
Receivers = (ReceiverGroup)1
}, SendOptions.SendReliable);
}
}
public enum ChallengeDifficulty
{
LIGHT,
EASY,
MEDIUM,
MEDIUMCORE,
HARD,
HARDCORE
}
public class Challenge
{
public string title;
public string description;
public ChallengeDifficulty difficulty;
public bool enabled;
public string id { get; }
public int? ascentOverride { get; }
public Challenge(string id, string title = "My Challenge", string description = "Custom Challenge for PEAK", ChallengeDifficulty difficulty = ChallengeDifficulty.MEDIUM, int? ascentOverride = null)
{
this.id = id;
this.title = title;
this.description = description;
this.difficulty = difficulty;
this.ascentOverride = ascentOverride;
}
}
public static class ChallengesAPI
{
public static bool IsHell = false;
public const string HellChallengeId = "hell";
public static Dictionary<string, Challenge> challenges = new Dictionary<string, Challenge>();
private static readonly List<Challenge> _registeredChallenges = new List<Challenge>();
private static bool _sceneHooked;
public static event Action ChallengeListChanged;
private static event Action<Scene, LoadSceneMode> _sceneLoaded;
public static event Action<Scene, LoadSceneMode> SceneLoaded
{
add
{
_sceneLoaded += value;
UpdateSceneSubscription();
}
remove
{
_sceneLoaded -= value;
UpdateSceneSubscription();
}
}
public static void RegisterChallenge(Challenge challenge)
{
if (challenge != null && !string.IsNullOrEmpty(challenge.id))
{
EnsureChallengeDictionary();
if (challenges != null && challenges.TryGetValue(challenge.id, out var value))
{
challenge.enabled = value.enabled;
}
int num = _registeredChallenges.FindIndex((Challenge c) => c != null && c.id == challenge.id);
if (num >= 0)
{
_registeredChallenges[num] = challenge;
}
else
{
_registeredChallenges.Add(challenge);
}
challenges[challenge.id] = challenge;
ChallengesAPI.ChallengeListChanged?.Invoke();
UpdateSceneSubscription();
}
}
public static bool IsChallengeEnabled(string id)
{
EnsureChallengeDictionary();
if (IsHell)
{
return true;
}
if (challenges == null)
{
return false;
}
if (challenges.TryGetValue(id, out var value))
{
return value.enabled;
}
return false;
}
public static void SetSingularChallengeEnabled(string id)
{
EnsureChallengeDictionary();
if (challenges == null || challenges.Count == 0)
{
return;
}
bool flag = false;
bool flag2 = !string.IsNullOrEmpty(id) && id == "hell";
if (IsHell != flag2)
{
IsHell = flag2;
flag = true;
}
foreach (Challenge value in challenges.Values)
{
bool flag3 = flag2 || value.id == id;
if (value.enabled != flag3)
{
value.enabled = flag3;
flag = true;
}
}
if (flag)
{
ChallengesAPI.ChallengeListChanged?.Invoke();
UpdateSceneSubscription();
}
}
public static bool IsOneOfTheseChallengesEnabled(string[] challengeList)
{
for (int i = 0; i < challengeList.Length; i++)
{
if (IsChallengeEnabled(challengeList[i]))
{
return true;
}
}
return false;
}
public static void DisableAllChallenges()
{
EnsureChallengeDictionary();
if (challenges == null || challenges.Count == 0)
{
return;
}
bool flag = false;
foreach (Challenge value in challenges.Values)
{
if (value.enabled)
{
value.enabled = false;
flag = true;
}
}
if (flag)
{
ChallengesAPI.ChallengeListChanged?.Invoke();
UpdateSceneSubscription();
}
}
private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_000b: 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)
ChallengesAPI._sceneLoaded?.Invoke(scene, mode);
if (!AnyChallengeActive())
{
UpdateSceneSubscription();
}
}
private static bool AnyChallengeActive()
{
EnsureChallengeDictionary();
if (IsHell)
{
return true;
}
if (challenges == null || challenges.Count == 0)
{
return false;
}
foreach (Challenge value in challenges.Values)
{
if (value.enabled)
{
return true;
}
}
return false;
}
private static void UpdateSceneSubscription()
{
bool flag = ChallengesAPI._sceneLoaded != null && AnyChallengeActive();
if (flag && !_sceneHooked)
{
SceneManager.sceneLoaded += HandleSceneLoaded;
_sceneHooked = true;
}
else if (!flag && _sceneHooked)
{
SceneManager.sceneLoaded -= HandleSceneLoaded;
_sceneHooked = false;
}
}
internal static void EnsureChallengesRegistered()
{
EnsureChallengeDictionary();
}
private static void EnsureChallengeDictionary()
{
if (challenges == null)
{
challenges = new Dictionary<string, Challenge>();
}
if (challenges.Count > 0 || _registeredChallenges.Count == 0)
{
return;
}
for (int i = 0; i < _registeredChallenges.Count; i++)
{
Challenge challenge = _registeredChallenges[i];
if (challenge != null && !string.IsNullOrEmpty(challenge.id))
{
challenges[challenge.id] = challenge;
}
}
}
}
public static class ChallengesGUILoader
{
private class LoaderHost : MonoBehaviour
{
public void Boot(Action onReady)
{
((MonoBehaviour)this).StartCoroutine(BootNextFrame(onReady));
}
private IEnumerator BootNextFrame(Action onReady)
{
yield return null;
onReady?.Invoke();
}
public IEnumerator RetryUntil(Func<bool> condition, int attempts, float delaySeconds, Action onTick)
{
for (int i = 1; i <= attempts; i++)
{
yield return (object)new WaitForSeconds(delaySeconds);
Log($"Retry {i}/{attempts} – challenges={((ChallengesAPI.challenges != null) ? ChallengesAPI.challenges.Count : 0)}");
onTick?.Invoke();
if (condition())
{
yield break;
}
}
Log("Retries exhausted.");
}
}
private static GameObject _menuPrefab;
private static GameObject _fallbackButtonPrefab;
private static GameObject _menuInstance;
private static Transform _listRoot;
private static GameObject _buttonTemplate;
private static GameObject _selectedPanel;
private static Button _backButton;
private static Button _goButton;
private static MenuWindow _menuWindow;
private static Challenge _selectedChallenge;
private static readonly List<ChallengeKiosk> _linkedKiosks = new List<ChallengeKiosk>();
private static bool _suppressSelectionBroadcast;
private static string _pendingSelectedChallengeId;
private static int _page = 0;
private static int _perPage = 5;
private static LoaderHost _host;
private static bool _pendingRefresh;
public static void Load(GameObject challengesGUINew, GameObject challengeButtonNew)
{
//IL_0057: 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)
_menuPrefab = challengesGUINew;
_fallbackButtonPrefab = challengeButtonNew;
ChallengesAPI.ChallengeListChanged -= OnChallengeListChanged;
ChallengesAPI.ChallengeListChanged += OnChallengeListChanged;
ChallengeMultiplayerSync.Initialize();
SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
{
if (((Scene)(ref scene)).name == "Airport")
{
ChallengesAPI.DisableAllChallenges();
ClearSelection(broadcast: false);
ChallengeMultiplayerSync.NotifyAirportLoaded();
CreateKiosk();
}
};
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).isLoaded && ((Scene)(ref activeScene)).name == "Airport")
{
ChallengesAPI.DisableAllChallenges();
ClearSelection(broadcast: false);
ChallengeMultiplayerSync.NotifyAirportLoaded();
CreateKiosk();
}
}
public static int AssignMasterClientViewID(GameObject go)
{
int num = PhotonNetwork.AllocateViewID(false);
go.GetComponent<PhotonView>().ViewID = num;
return num;
}
private static void Log(string msg)
{
Debug.Log((object)("[ChallengesGUI] " + msg));
}
private static void CreateKiosk()
{
if ((Object)(object)_menuInstance == (Object)null)
{
ResetCachedReferences();
}
if ((Object)(object)_menuInstance != (Object)null)
{
if (EnsureMenuStructure())
{
EnsureHost();
LinkKiosksToMenu();
if (_pendingRefresh && (Object)(object)_listRoot != (Object)null)
{
_pendingRefresh = false;
FillButtons();
}
else if ((Object)(object)_listRoot != (Object)null)
{
ChallengesAPI.EnsureChallengesRegistered();
FillButtons();
}
return;
}
Log("Cached menu references missing; rebuilding GUI instance.");
Object.Destroy((Object)(object)_menuInstance);
ResetCachedReferences();
}
if ((Object)(object)_menuPrefab == (Object)null)
{
Log("Menu prefab is null.");
return;
}
_menuInstance = Object.Instantiate<GameObject>(_menuPrefab);
((Object)_menuInstance).name = "ChallengesGUI";
_menuInstance.SetActive(false);
_menuWindow = (MenuWindow)(object)_menuInstance.AddComponent<ChallengeMenuWindow>();
EnsureHost();
EnsureMenuStructure();
LinkKiosksToMenu();
_host.Boot(delegate
{
TryFillOrRetry();
if (_pendingRefresh && (Object)(object)_listRoot != (Object)null)
{
_pendingRefresh = false;
FillButtons();
}
});
}
internal static void EnsureMenuReady()
{
if ((Object)(object)_menuInstance == (Object)null)
{
CreateKiosk();
return;
}
if (!EnsureMenuStructure())
{
Log("Menu structure invalid when ensuring readiness; rebuilding.");
Object.Destroy((Object)(object)_menuInstance);
ResetCachedReferences();
CreateKiosk();
return;
}
if ((Object)(object)_listRoot == (Object)null)
{
Log("EnsureMenuReady aborted: list root missing after rebuild.");
return;
}
ChallengesAPI.EnsureChallengesRegistered();
if (_pendingRefresh)
{
_pendingRefresh = false;
FillButtons();
}
else
{
FillButtons();
}
}
private static void EnsureHost()
{
if (!((Object)(object)_menuInstance == (Object)null) && !((Object)(object)_host != (Object)null))
{
_host = _menuInstance.GetComponent<LoaderHost>() ?? _menuInstance.AddComponent<LoaderHost>();
}
}
private static bool EnsureMenuStructure()
{
if ((Object)(object)_menuInstance == (Object)null)
{
return false;
}
if ((Object)(object)_listRoot == (Object)null)
{
Transform val = _menuInstance.transform.FindChildRecursive("Content");
Transform val2 = (Object.op_Implicit((Object)(object)val) ? val.Find("Main") : null);
Transform val3 = (Object.op_Implicit((Object)(object)val2) ? val2.Find("ChallengeList") : null);
_listRoot = (Object.op_Implicit((Object)(object)val3) ? val3.Find("Contents") : null);
if ((Object)(object)_listRoot == (Object)null)
{
_listRoot = _menuInstance.transform.FindChildRecursive("Contents");
}
Log("List root: " + (Object.op_Implicit((Object)(object)_listRoot) ? _listRoot.GetHierarchyPath() : "null"));
}
if ((Object)(object)_listRoot != (Object)null && (Object)(object)_buttonTemplate == (Object)null)
{
Transform obj = _listRoot.Find("Challenge");
_buttonTemplate = ((obj != null) ? ((Component)obj).gameObject : null);
if ((Object)(object)_buttonTemplate != (Object)null)
{
Log("Button template: " + _buttonTemplate.transform.GetHierarchyPath());
_buttonTemplate.SetActive(false);
}
else
{
Log("Button template not found. Using fallback prefab.");
}
}
if ((Object)(object)_selectedPanel == (Object)null)
{
Transform obj2 = _menuInstance.transform.FindChildRecursive("SelectedChallenge");
_selectedPanel = ((obj2 != null) ? ((Component)obj2).gameObject : null);
Log("Selected panel: " + (Object.op_Implicit((Object)(object)_selectedPanel) ? _selectedPanel.transform.GetHierarchyPath() : "null"));
if (Object.op_Implicit((Object)(object)_selectedPanel))
{
if (_selectedChallenge == null)
{
_selectedPanel.SetActive(false);
}
else
{
RenderSelectedChallenge();
}
}
}
WireNavigationButtons();
UpdateGoButtonState();
ApplyPendingSelectionIfNeeded();
return (Object)(object)_listRoot != (Object)null;
}
private static void ResetCachedReferences()
{
_menuInstance = null;
_listRoot = null;
_buttonTemplate = null;
_selectedPanel = null;
_backButton = null;
_goButton = null;
_menuWindow = null;
_host = null;
_selectedChallenge = null;
_pendingRefresh = false;
}
private static void LinkKiosksToMenu()
{
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: 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)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_menuInstance == (Object)null)
{
return;
}
PruneKioskList();
ChallengeKiosk[] array = Object.FindObjectsByType<ChallengeKiosk>((FindObjectsSortMode)0);
if (array != null && array.Length != 0)
{
for (int i = 0; i < array.Length; i++)
{
array[i].challengesGUI = _menuInstance;
TrackKiosk(array[i]);
}
Log($"Linked GUI to {array.Length} existing ChallengeKiosk instance(s).");
}
else
{
AirportCheckInKiosk obj = Object.FindFirstObjectByType<AirportCheckInKiosk>();
GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
if ((Object)(object)val != (Object)null)
{
bool activeSelf = val.activeSelf;
val.SetActive(false);
GameObject obj2 = Object.Instantiate<GameObject>(val, val.transform.position, val.transform.rotation, val.transform.parent);
Transform transform = obj2.transform;
transform.position -= new Vector3(0f, 0f, 0.7f);
((Object)obj2).name = "ChallengesKiosk";
PhotonView component = obj2.GetComponent<PhotonView>();
if ((Object)(object)component != (Object)null)
{
PhotonNetwork.AllocateViewID(component);
}
AirportCheckInKiosk component2 = obj2.GetComponent<AirportCheckInKiosk>();
if ((Object)(object)component2 != (Object)null)
{
Object.Destroy((Object)(object)component2);
}
ChallengeKiosk challengeKiosk = obj2.AddComponent<ChallengeKiosk>();
challengeKiosk.challengesGUI = _menuInstance;
TrackKiosk(challengeKiosk);
obj2.SetActive(true);
val.SetActive(activeSelf);
Log("Spawned ChallengesKiosk clone and linked GUI.");
}
else
{
Log("Base AirportCheckInKiosk not found; could not spawn kiosk.");
}
}
if ((Object)(object)_host == (Object)null)
{
_host = _menuInstance.AddComponent<LoaderHost>();
}
if (_pendingRefresh && (Object)(object)_listRoot != (Object)null)
{
_pendingRefresh = false;
FillButtons();
}
}
private static void TryFillOrRetry()
{
ChallengesAPI.EnsureChallengesRegistered();
Log($"Initial challenges count: {ChallengesAPI.challenges.Count}");
FillButtons();
if (ChallengesAPI.challenges.Count == 0)
{
((MonoBehaviour)_host).StartCoroutine(_host.RetryUntil(() => ChallengesAPI.challenges.Count > 0, 8, 0.5f, FillButtons));
}
}
private static void OnChallengeListChanged()
{
if ((Object)(object)_menuInstance == (Object)null || (Object)(object)_listRoot == (Object)null)
{
_pendingRefresh = true;
return;
}
_pendingRefresh = false;
FillButtons();
}
private static void FillButtons()
{
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Expected O, but got Unknown
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Expected O, but got Unknown
if ((Object)(object)_listRoot == (Object)null)
{
Log("FillButtons aborted: list root is null.");
return;
}
ClearListKeepTemplate();
int num = ((ChallengesAPI.challenges != null) ? ChallengesAPI.challenges.Count : 0);
Log($"Render page={_page} perPage={_perPage} total={num}");
if (num == 0)
{
RebuildLayout();
return;
}
List<Challenge> list = ChallengesAPI.challenges.Values.ToList();
int num2 = _page * _perPage;
if (num2 >= num)
{
_page = (num - 1) / _perPage;
num2 = _page * _perPage;
}
int num3 = Mathf.Min(num2 + _perPage, num);
Log($"Slice [{num2}..{num3})");
for (int i = num2; i < num3; i++)
{
Challenge challenge = list[i];
Button val = SpawnButton(challenge.title);
if (!((Object)(object)val == (Object)null))
{
WireChallengeButton(val, challenge);
Log("Spawned button: " + challenge.title);
}
}
bool num4 = _page > 0;
bool flag = num3 < num;
if (num4)
{
Button val2 = SpawnButton("Previous");
if ((Object)(object)val2 != (Object)null)
{
((UnityEvent)val2.onClick).AddListener(new UnityAction(PrevPage));
}
}
if (flag)
{
Button val3 = SpawnButton("Next");
if ((Object)(object)val3 != (Object)null)
{
((UnityEvent)val3.onClick).AddListener(new UnityAction(NextPage));
}
}
RebuildLayout();
if ((Object)(object)_selectedPanel != (Object)null && _selectedChallenge == null)
{
_selectedPanel.SetActive(false);
}
}
private static void ClearListKeepTemplate()
{
for (int num = _listRoot.childCount - 1; num >= 0; num--)
{
GameObject gameObject = ((Component)_listRoot.GetChild(num)).gameObject;
if (!((Object)(object)_buttonTemplate != (Object)null) || gameObject != _buttonTemplate)
{
Object.Destroy((Object)(object)gameObject);
}
}
}
private static Button SpawnButton(string label)
{
GameObject val = _buttonTemplate ?? _fallbackButtonPrefab;
if ((Object)(object)val == (Object)null)
{
Log("No button prefab available.");
return null;
}
GameObject val2 = Object.Instantiate<GameObject>(val, _listRoot, false);
((Object)val2).name = ((Object)val).name + "_Clone";
val2.SetActive(true);
Button obj = val2.GetComponent<Button>() ?? val2.AddComponent<Button>();
Image component = val2.GetComponent<Image>();
if ((Object)(object)component != (Object)null)
{
((Graphic)component).raycastTarget = true;
}
TMP_Text val3 = null;
Transform val4 = val2.transform.Find("Text");
if (Object.op_Implicit((Object)(object)val4))
{
val3 = ((Component)val4).GetComponent<TMP_Text>();
}
if ((Object)(object)val3 == (Object)null)
{
val3 = val2.GetComponentInChildren<TMP_Text>(true);
}
if ((Object)(object)val3 != (Object)null)
{
val3.text = label;
}
((UnityEventBase)obj.onClick).RemoveAllListeners();
return obj;
}
private static void WireChallengeButton(Button btn, Challenge c)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
((UnityEventBase)btn.onClick).RemoveAllListeners();
((UnityEvent)btn.onClick).AddListener((UnityAction)delegate
{
SelectChallenge(c);
});
if (c.enabled && (_selectedChallenge == null || _selectedChallenge.id != c.id))
{
SelectChallenge(c, broadcast: false);
}
}
private static void SelectChallenge(Challenge challenge, bool broadcast = true)
{
if (challenge == null)
{
ClearSelection(broadcast);
return;
}
string a = ((_selectedChallenge != null) ? _selectedChallenge.id : null);
_selectedChallenge = challenge;
_pendingSelectedChallengeId = challenge.id;
if (challenge.ascentOverride.HasValue)
{
Ascents.currentAscent = challenge.ascentOverride.Value;
}
RenderSelectedChallenge();
UpdateGoButtonState();
Log($"Selected: {challenge.title} ({challenge.difficulty})");
if (broadcast && !_suppressSelectionBroadcast && !string.Equals(a, challenge.id, StringComparison.Ordinal))
{
ChallengeMultiplayerSync.BroadcastSelection(challenge);
}
}
private static void WireNavigationButtons()
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Expected O, but got Unknown
if (!((Object)(object)_menuInstance == (Object)null))
{
Transform val = _menuInstance.transform.FindChildRecursive("BACK");
if ((Object)(object)val != (Object)null)
{
_backButton = ((Component)val).GetComponent<Button>() ?? ((Component)val).gameObject.AddComponent<Button>();
((UnityEventBase)_backButton.onClick).RemoveAllListeners();
((UnityEvent)_backButton.onClick).AddListener(new UnityAction(HandleBackPressed));
}
Transform val2 = _menuInstance.transform.FindChildRecursive("Go");
if ((Object)(object)val2 == (Object)null && (Object)(object)_selectedPanel != (Object)null)
{
val2 = _selectedPanel.transform.FindChildRecursive("Go");
}
if ((Object)(object)val2 != (Object)null)
{
_goButton = ((Component)val2).GetComponent<Button>() ?? ((Component)val2).gameObject.AddComponent<Button>();
((UnityEventBase)_goButton.onClick).RemoveAllListeners();
((UnityEvent)_goButton.onClick).AddListener(new UnityAction(HandleGoPressed));
}
}
}
private static void HandleBackPressed()
{
MenuWindow.CloseAllWindows();
if ((Object)(object)_menuInstance != (Object)null)
{
_menuInstance.SetActive(false);
}
ClearSelection(broadcast: false);
}
private static void HandleGoPressed()
{
if (_selectedChallenge != null)
{
ChallengesAPI.SetSingularChallengeEnabled(_selectedChallenge.id);
ChallengeKiosk anyKiosk = GetAnyKiosk();
if ((Object)(object)anyKiosk != (Object)null)
{
int currentAscent = Ascents.currentAscent;
anyKiosk.StartGame(currentAscent);
}
else
{
Log("No ChallengeKiosk available to start the run.");
}
}
}
private static void UpdateGoButtonState()
{
if (!((Object)(object)_goButton == (Object)null))
{
((Selectable)_goButton).interactable = _selectedChallenge != null;
}
}
private static void RenderSelectedChallenge()
{
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_selectedPanel == (Object)null)
{
return;
}
if (_selectedChallenge == null)
{
_selectedPanel.SetActive(false);
return;
}
_selectedPanel.SetActive(true);
Transform val = _selectedPanel.transform.Find("Title");
Transform val2 = _selectedPanel.transform.Find("Subtext");
Transform obj = _selectedPanel.transform.Find("Description");
Transform val3 = ((obj != null) ? obj.Find("Body") : null);
TMP_Text val4 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<TMP_Text>() : null);
TMP_Text val5 = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).GetComponent<TMP_Text>() : null);
TMP_Text val6 = (Object.op_Implicit((Object)(object)val3) ? ((Component)val3).GetComponent<TMP_Text>() : null);
if ((Object)(object)val4 != (Object)null)
{
val4.text = _selectedChallenge.title;
}
if ((Object)(object)val5 != (Object)null)
{
((Graphic)val5).color = DifficultyColour(_selectedChallenge.difficulty);
val5.text = _selectedChallenge.difficulty.ToString();
}
if ((Object)(object)val6 != (Object)null)
{
val6.text = _selectedChallenge.description;
}
}
private static void ClearSelection(bool broadcast)
{
bool num = _selectedChallenge != null;
_selectedChallenge = null;
_pendingSelectedChallengeId = null;
if ((Object)(object)_selectedPanel != (Object)null)
{
_selectedPanel.SetActive(false);
}
UpdateGoButtonState();
if (num && broadcast && !_suppressSelectionBroadcast)
{
ChallengeMultiplayerSync.BroadcastSelection(null);
}
}
private static void ApplyPendingSelectionIfNeeded()
{
if (!string.IsNullOrEmpty(_pendingSelectedChallengeId) && !((Object)(object)_selectedPanel == (Object)null))
{
ChallengesAPI.EnsureChallengesRegistered();
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.TryGetValue(_pendingSelectedChallengeId, out var value))
{
ChallengesAPI.SetSingularChallengeEnabled(_pendingSelectedChallengeId);
SelectChallenge(value, broadcast: false);
_pendingSelectedChallengeId = null;
}
}
}
private static void TrackKiosk(ChallengeKiosk kiosk)
{
if (!((Object)(object)kiosk == (Object)null) && !_linkedKiosks.Contains(kiosk))
{
_linkedKiosks.Add(kiosk);
}
}
private static void PruneKioskList()
{
for (int num = _linkedKiosks.Count - 1; num >= 0; num--)
{
if ((Object)(object)_linkedKiosks[num] == (Object)null)
{
_linkedKiosks.RemoveAt(num);
}
}
}
private static ChallengeKiosk GetAnyKiosk()
{
PruneKioskList();
if (_linkedKiosks.Count > 0)
{
return _linkedKiosks[0];
}
ChallengeKiosk challengeKiosk = Object.FindFirstObjectByType<ChallengeKiosk>();
TrackKiosk(challengeKiosk);
return challengeKiosk;
}
public static void NextPage()
{
int num = ((ChallengesAPI.challenges != null) ? ChallengesAPI.challenges.Count : 0);
if ((_page + 1) * _perPage < num)
{
_page++;
FillButtons();
}
}
public static void PrevPage()
{
if (_page != 0)
{
_page--;
FillButtons();
}
}
private static void RebuildLayout()
{
Transform listRoot = _listRoot;
RectTransform val = (RectTransform)(object)((listRoot is RectTransform) ? listRoot : null);
if ((Object)(object)val != (Object)null)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(val);
}
}
internal static void ApplyNetworkSelection(string challengeId, int? ascent)
{
bool suppressSelectionBroadcast = _suppressSelectionBroadcast;
_suppressSelectionBroadcast = true;
try
{
if (ascent.HasValue)
{
Ascents.currentAscent = ascent.Value;
}
string a = ((_selectedChallenge != null) ? _selectedChallenge.id : null);
if (string.IsNullOrEmpty(challengeId))
{
ChallengesAPI.DisableAllChallenges();
ClearSelection(broadcast: false);
return;
}
ChallengesAPI.EnsureChallengesRegistered();
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.TryGetValue(challengeId, out var value))
{
ChallengesAPI.SetSingularChallengeEnabled(challengeId);
if (!string.Equals(a, challengeId, StringComparison.Ordinal) || (Object)(object)_selectedPanel == (Object)null)
{
SelectChallenge(value, broadcast: false);
}
}
else
{
_pendingSelectedChallengeId = challengeId;
}
}
finally
{
_suppressSelectionBroadcast = suppressSelectionBroadcast;
}
}
private static Color DifficultyColour(ChallengeDifficulty d)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: 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_006e: 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_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
return (Color)(d switch
{
ChallengeDifficulty.LIGHT => new Color(0.6f, 1f, 0.6f),
ChallengeDifficulty.EASY => new Color(0.1f, 0.9f, 0.1f),
ChallengeDifficulty.MEDIUM => new Color(1f, 0.85f, 0.1f),
ChallengeDifficulty.MEDIUMCORE => new Color(1f, 0.55f, 0f),
ChallengeDifficulty.HARD => new Color(0.9f, 0.1f, 0.1f),
ChallengeDifficulty.HARDCORE => new Color(0.5f, 0f, 0f),
_ => Color.white,
});
}
}
public static class TransformFindExtensions
{
public static Transform FindChildRecursive(this Transform parent, string name)
{
if ((Object)(object)parent == (Object)null)
{
return null;
}
for (int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
if (((Object)child).name == name)
{
return child;
}
Transform val = child.FindChildRecursive(name);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
public static string GetHierarchyPath(this Transform t)
{
if ((Object)(object)t == (Object)null)
{
return "null";
}
Stack<string> stack = new Stack<string>();
Transform val = t;
while ((Object)(object)val != (Object)null)
{
stack.Push(((Object)val).name);
val = val.parent;
}
return string.Join("/", stack);
}
}
[BepInPlugin("com.khakixd.challenges", "Challenges", "1.0.0")]
public class ChallengesPlugin : BaseUnityPlugin
{
private void Awake()
{
Harmony.CreateAndPatchAll(typeof(ChallengesPlugin).Assembly, "com.khakixd.challenges");
BundleLoader.LoadBundleAndContentsWithName((BaseUnityPlugin)(object)this, "peakchallenges.peakbundle", (Action<PeakBundle>)delegate(PeakBundle bundle)
{
GameObject challengesGUINew = bundle.LoadAsset<GameObject>("Challenges");
GameObject challengeButtonNew = bundle.LoadAsset<GameObject>("Challenge");
DXWarning.Init(bundle.LoadAsset<GameObject>("DXWarning"));
ChallengesGUILoader.Load(challengesGUINew, challengeButtonNew);
BuiltinChallenges.RegisterAll();
});
}
}
namespace Challenges
{
public static class BuiltinChallenges
{
public static int highestAscent = 7;
public static void RegisterAll()
{
ChallengesAPI.RegisterChallenge(new Challenge("permasnow", "Frostbite", " - Ascent 5\n - It is always storming in The Alpines\n - It is always raining in The Tropics\n - The Alpines is forced\nPLEASE USE THE FAIR SNOWSTORMS MOD.", ChallengeDifficulty.MEDIUMCORE, 5));
ChallengesAPI.RegisterChallenge(new Challenge("instagib", "Instagib", " - Ascent 7\n - Going unconcious instantly kills you.\n", ChallengeDifficulty.HARD, 7));
ChallengesAPI.RegisterChallenge(new Challenge("cappedluggage", "Baggage Allowance", " - Ascent 1\n - Only one item in luggage\n", ChallengeDifficulty.EASY, 1));
ChallengesAPI.RegisterChallenge(new Challenge("hunger", "The Hunger", " - Ascent 3\n - Stamina only recovers after eating\n", ChallengeDifficulty.HARDCORE, 3));
ChallengesAPI.RegisterChallenge(new Challenge("inversion", "Inversion", " - Ascent 4\n - Natural affliction recovery is reversed\n", ChallengeDifficulty.HARD, 4));
ChallengesAPI.RegisterChallenge(new Challenge("narcolepsy", "Narcolepsy", " - Ascent 4\n - Knocked out by drowsiness every 1-3 minutes\n", ChallengeDifficulty.MEDIUM, 4));
ChallengesAPI.RegisterChallenge(new Challenge("afflictionrandomizer", "Affliction Randomizer", " - Ascent 5\n - Added statuses become random afflictions\n", ChallengeDifficulty.HARD, 5));
ChallengesAPI.RegisterChallenge(new Challenge("scoutmasterlurks", "Scoutmaster Lurks", " - Ascent Tenderfoot (-1)\n - Scoutmaster only hunts at night\n - He always goes for the closest camper\n", ChallengeDifficulty.MEDIUM, -1));
ChallengesAPI.RegisterChallenge(new Challenge("planecrash", "Plane Crash", " - Ascent Tenderfoot (-1)\n - Start with 90% injury\n", ChallengeDifficulty.LIGHT, -1));
ChallengesAPI.RegisterChallenge(new Challenge("friendslop", "Friendslop", " - Ascent Tenderfoot (-1)\n - Bonkables now fling at 5x their normal fling speed\n - Bonkables now knock players out for 5 seconds\n - All items are bonkable", ChallengeDifficulty.LIGHT, -1));
ChallengesAPI.RegisterChallenge(new Challenge("tuckered_out", "Tuckered Out", " - Ascent 2\n - Carrying weight makes you drowsy", ChallengeDifficulty.MEDIUM, 2));
ChallengesAPI.RegisterChallenge(new Challenge("hell", "Hell", $" - Ascent {highestAscent}\n" + " - All other challenges are enabled\n", ChallengeDifficulty.HARDCORE, highestAscent));
ChooseBiome.Init();
SnowPatch.Init();
}
}
public class ChallengeMenuWindow : MenuWindow
{
public override bool openOnStart => false;
public override bool selectOnOpen => true;
public override bool closeOnPause => false;
public override bool closeOnUICancel => true;
public override bool autoHideOnClose => false;
}
public class DeleteLaterDebris : MonoBehaviour
{
private float timeAlive;
public float timeToKill = 15f;
private void Update()
{
timeAlive += Time.deltaTime;
if (timeAlive >= timeToKill)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
}
public static class DXWarning
{
private static GameObject menuPopup;
public static void Init(GameObject popup)
{
menuPopup = popup;
SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Invalid comparison between Unknown and I4
if (((Scene)(ref scene)).name == "Title" && (int)SystemInfo.graphicsDeviceType != 21)
{
GameObject obj = Object.Instantiate<GameObject>(menuPopup, (Transform)null, true);
((Object)obj).name = "MenuPopup";
obj.AddComponent<DeleteLaterDebris>();
}
};
}
}
}
namespace Challenges.ChallengeScripts
{
internal static class AfflictionRandomizerPatch
{
[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
private static class CharacterAfflictionsAddStatusRandomizer
{
[HarmonyPrefix]
private static void Prefix(ref STATUSTYPE statusType)
{
//IL_0020: 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)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Expected I4, but got Unknown
//IL_0041: 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_0058: Unknown result type (might be due to invalid IL or missing references)
if (IsRandomizerEnabled() && (int)statusType != 6 && StatusTypes != null && StatusTypes.Length != 0)
{
STATUSTYPE val = statusType;
int num = Random.Range(0, StatusTypes.Length);
STATUSTYPE val2 = StatusTypes[num];
if (StatusTypes.Length > 1 && val2 == val)
{
num = (num + 1) % StatusTypes.Length;
val2 = StatusTypes[num];
}
statusType = (STATUSTYPE)(int)val2;
}
}
}
private const string ChallengeId = "afflictionrandomizer";
private static readonly STATUSTYPE[] StatusTypes = Enum.GetValues(typeof(STATUSTYPE)).Cast<STATUSTYPE>().ToArray();
private static bool IsRandomizerEnabled()
{
return ChallengesAPI.IsChallengeEnabled("afflictionrandomizer");
}
}
public static class BonkablePatch
{
[HarmonyPatch(typeof(Bonkable))]
[HarmonyPatch("Awake")]
private static class BonkableFriendslopPatch
{
[HarmonyPostfix]
private static void Postfix(Bonkable __instance)
{
if (ChallengesAPI.IsChallengeEnabled("friendslop"))
{
__instance.bonkForce = 1010f;
__instance.ragdollTime *= 2f;
__instance.bonkRange = 2.5f;
}
}
}
[HarmonyPatch(typeof(Item))]
[HarmonyPatch("Awake")]
private static class ItemFriendslopPatch
{
[HarmonyPostfix]
private static void Postfix(Item __instance)
{
if ((Object)(object)((Component)__instance).gameObject.GetComponent<Bonkable>() == (Object)null && ChallengesAPI.IsChallengeEnabled("friendslop"))
{
((Component)__instance).gameObject.AddComponent<Bonkable>();
}
}
}
[HarmonyPatch(typeof(Bonkable), "Bonk")]
private static class BonkableBonkForeachPatch
{
private static readonly FieldRef<Bonkable, float> bonkCooldownRef = AccessTools.FieldRefAccess<Bonkable, float>("bonkCooldown");
private static readonly Action<Character, float> Fall1 = TryMakeDelegate<Action<Character, float>>(typeof(Character), "Fall", new Type[1] { typeof(float) });
private static readonly Action<Character, float, float> Fall2 = TryMakeDelegate<Action<Character, float, float>>(typeof(Character), "Fall", new Type[2]
{
typeof(float),
typeof(float)
});
private static readonly Action<Character, Vector3, Vector3, float> AddForceAtPositionDel = TryMakeDelegate<Action<Character, Vector3, Vector3, float>>(typeof(Character), "AddForceAtPosition", new Type[3]
{
typeof(Vector3),
typeof(Vector3),
typeof(float)
});
[HarmonyPrefix]
private static bool Prefix(Bonkable __instance, Collision coll)
{
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
Character componentInParent = coll.gameObject.GetComponentInParent<Character>();
if ((Object)(object)componentInParent == (Object)null)
{
return false;
}
float num = bonkCooldownRef.Invoke(__instance);
if (Time.time <= __instance.lastBonkedTime + num)
{
return false;
}
if (Fall2 != null)
{
Fall2(componentInParent, __instance.ragdollTime, 0f);
}
else if (Fall1 != null)
{
Fall1(componentInParent, __instance.ragdollTime);
}
SFX_Instance[] bonk = __instance.bonk;
if (bonk != null)
{
SFX_Instance[] array = bonk;
foreach (SFX_Instance obj in array)
{
if (obj != null)
{
obj.Play(((Component)__instance).transform.position);
}
}
}
__instance.lastBonkedTime = Time.time;
Vector3 arg = ((coll.contactCount > 0) ? ((ContactPoint)(ref coll.contacts[0])).point : ((Component)__instance).transform.position);
Vector3 relativeVelocity = coll.relativeVelocity;
Vector3 arg2 = -((Vector3)(ref relativeVelocity)).normalized * __instance.bonkForce;
if (AddForceAtPositionDel != null)
{
AddForceAtPositionDel(componentInParent, arg2, arg, __instance.bonkRange);
}
return false;
}
private static T TryMakeDelegate<T>(Type type, string name, Type[] args) where T : Delegate
{
MethodInfo methodInfo = AccessTools.Method(type, name, args, (Type[])null);
if (methodInfo == null)
{
return null;
}
try
{
return AccessTools.MethodDelegate<T>(methodInfo, (object)null, true);
}
catch
{
return null;
}
}
}
}
[HarmonyPatch(typeof(Luggage), "OpenLuggageRPC")]
internal static class CappedLuggagePatch
{
private const string ChallengeId = "cappedluggage";
private static void Prefix(ref bool spawnItems, ref bool __state)
{
if (__state = spawnItems && ShouldCap())
{
spawnItems = false;
}
}
private static void Postfix(Luggage __instance, bool __state)
{
if (__state && !((Object)(object)__instance == (Object)null))
{
((MonoBehaviour)__instance).StartCoroutine(SpawnSingleItem(__instance));
}
}
private static IEnumerator SpawnSingleItem(Luggage luggage)
{
if ((Object)(object)luggage == (Object)null)
{
yield break;
}
yield return (object)new WaitForSeconds(0.1f);
Traverse val = Traverse.Create((object)luggage);
IList value = val.Method("GetSpawnSpots", Array.Empty<object>()).GetValue<IList>();
if (value == null || value.Count <= 0)
{
yield break;
}
IList list;
try
{
list = Activator.CreateInstance(value.GetType()) as IList;
}
catch
{
list = null;
}
if (list == null)
{
list = value;
if (list.IsFixedSize || list.IsReadOnly)
{
yield break;
}
for (int num = list.Count - 1; num >= 1; num--)
{
list.RemoveAt(num);
}
}
else
{
list.Add(value[0]);
}
val.Method("SpawnItems", new object[1] { list }).GetValue();
}
private static bool ShouldCap()
{
Dictionary<string, Challenge> challenges = ChallengesAPI.challenges;
if (challenges == null)
{
return false;
}
if (!challenges.ContainsKey("cappedluggage"))
{
return false;
}
return ChallengesAPI.IsChallengeEnabled("cappedluggage");
}
}
public static class ChooseBiome
{
private const string FrostbiteId = "permasnow";
private static bool _initialized;
public static void Init()
{
if (!_initialized)
{
_initialized = true;
ChallengesAPI.SceneLoaded += HandleSceneLoaded;
}
}
public static void SetMesa()
{
//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)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).isLoaded)
{
ToggleSceneObject(activeScene, "Map/Biome_3/Desert", enable: true);
ToggleSceneObject(activeScene, "Map/Biome_3/Snow", enable: false);
}
}
public static void SetAlpines()
{
//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)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).isLoaded)
{
ToggleSceneObject(activeScene, "Map/Biome_3/Desert", enable: false);
ToggleSceneObject(activeScene, "Map/Biome_3/Snow", enable: true);
}
}
private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (IsGameplayScene(scene) && IsFrostbiteEnabled())
{
SetAlpines();
}
}
private static bool IsGameplayScene(Scene scene)
{
if (!((Scene)(ref scene)).IsValid())
{
return false;
}
string text = ((Scene)(ref scene)).name ?? string.Empty;
if (!(text == "WilIsland"))
{
return text.StartsWith("level_", StringComparison.OrdinalIgnoreCase);
}
return true;
}
private static bool IsFrostbiteEnabled()
{
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("permasnow"))
{
return ChallengesAPI.IsChallengeEnabled("permasnow");
}
return false;
}
private static void ToggleSceneObject(Scene scene, string hierarchyPath, bool enable)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
GameObject val = FindSceneObject(scene, hierarchyPath);
if ((Object)(object)val == (Object)null)
{
Debug.LogWarning((object)("[ChooseBiome] Could not find object '" + hierarchyPath + "' in scene '" + ((Scene)(ref scene)).name + "'."));
}
else if (val.activeSelf != enable)
{
val.SetActive(enable);
}
}
private static GameObject FindSceneObject(Scene scene, string hierarchyPath)
{
if (!((Scene)(ref scene)).isLoaded || string.IsNullOrEmpty(hierarchyPath))
{
return null;
}
string[] array = hierarchyPath.Split(new char[1] { '/' });
if (array.Length == 0)
{
return null;
}
GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
for (int i = 0; i < rootGameObjects.Length; i++)
{
Transform val = FindByPathRecursive(rootGameObjects[i].transform, array, 0);
if ((Object)(object)val != (Object)null)
{
return ((Component)val).gameObject;
}
}
return null;
}
private static Transform FindByPathRecursive(Transform current, string[] segments, int index)
{
if ((Object)(object)current == (Object)null || segments == null || index >= segments.Length)
{
return null;
}
if (!string.Equals(((Object)current).name, segments[index], StringComparison.Ordinal))
{
if (index == 0)
{
for (int i = 0; i < current.childCount; i++)
{
Transform val = FindByPathRecursive(current.GetChild(i), segments, index);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
}
return null;
}
if (index == segments.Length - 1)
{
return current;
}
for (int j = 0; j < current.childCount; j++)
{
Transform val2 = FindByPathRecursive(current.GetChild(j), segments, index + 1);
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
return null;
}
}
internal static class HungerPatch
{
[HarmonyPatch(typeof(Character), "CanRegenStamina")]
private static class DisableNaturalStaminaRegen
{
[HarmonyPostfix]
private static void Postfix(Character __instance, ref bool __result)
{
if (__result && IsHungerEnabled() && (!((Object)(object)__instance != (Object)null) || !__instance.infiniteStam))
{
__result = false;
}
}
}
[HarmonyPatch(typeof(Action_RestoreHunger), "RunAction")]
private static class RestoreStaminaWhenFed
{
[HarmonyPostfix]
private static void Postfix(Action_RestoreHunger __instance)
{
if (!IsHungerEnabled())
{
return;
}
Character character = GetCharacter(__instance);
if ((Object)(object)character == (Object)null)
{
return;
}
CharacterData data = character.data;
if (!((Object)(object)data == (Object)null))
{
float num = character.GetMaxStamina();
if (num < 0f)
{
num = 0f;
}
float num2 = num - data.currentStamina;
if (num2 > 0f)
{
character.AddStamina(num2);
}
data.currentStamina = num;
character.ClampStamina();
}
}
}
private const string HungerChallengeId = "hunger";
private static bool IsHungerEnabled()
{
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("hunger") && ChallengesAPI.IsChallengeEnabled("hunger"))
{
return IsInGameplayScene();
}
return false;
}
private static bool IsInGameplayScene()
{
//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();
if (!((Scene)(ref activeScene)).IsValid())
{
return false;
}
string text = ((Scene)(ref activeScene)).name ?? string.Empty;
if (string.Equals(text, "WilIsland", StringComparison.OrdinalIgnoreCase))
{
return true;
}
return text.StartsWith("level_", StringComparison.OrdinalIgnoreCase);
}
private static Character GetCharacter(Action_RestoreHunger instance)
{
if ((Object)(object)instance == (Object)null)
{
return null;
}
Traverse val = Traverse.Create((object)instance);
Character value = val.Field("character").GetValue<Character>();
if ((Object)(object)value != (Object)null)
{
return value;
}
return val.Property("character", (object[])null).GetValue<Character>();
}
}
[HarmonyPatch(typeof(Character), "RPCA_PassOut")]
internal static class InstagibPassOutPatch
{
private const string InstagibChallengeId = "instagib";
private const string DieInstantlyMethodName = "DieInstantly";
private static void Postfix(Character __instance)
{
if ((Object)(object)__instance == (Object)null || !ShouldInstagib() || NarcolepsyPatch.ShouldPreventInstagib(__instance))
{
return;
}
CharacterAfflictions val = __instance.refs?.afflictions;
if ((Object)(object)val != (Object)null)
{
float currentStatus = val.GetCurrentStatus((STATUSTYPE)6);
if (currentStatus > 0f && val.GetCurrentStatus((STATUSTYPE)0) - currentStatus < 1f)
{
return;
}
}
PhotonView photonView = ((MonoBehaviourPun)__instance).photonView;
if (!((Object)(object)photonView == (Object)null) && photonView.IsMine)
{
((MonoBehaviour)__instance).Invoke("DieInstantly", 0.02f);
}
}
private static bool ShouldInstagib()
{
Dictionary<string, Challenge> challenges = ChallengesAPI.challenges;
if (challenges == null)
{
return false;
}
if (!challenges.ContainsKey("instagib"))
{
return false;
}
return ChallengesAPI.IsChallengeEnabled("instagib");
}
}
internal static class InversionAfflictionsPatch
{
[HarmonyPatch(typeof(CharacterAfflictions), "UpdateNormalStatuses")]
private static class UpdateNormalStatusesInversion
{
[HarmonyPrefix]
private static bool Prefix(CharacterAfflictions __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return true;
}
if (!IsInversionEnabled())
{
return true;
}
Character character = __instance.character;
if ((Object)(object)character == (Object)null)
{
return true;
}
if (!character.IsLocal)
{
return false;
}
if (Ascents.isNightCold && Object.op_Implicit((Object)(object)Singleton<MountainProgressHandler>.Instance) && Singleton<MountainProgressHandler>.Instance.maxProgressPointReached < 3 && (Object)(object)DayNightManager.instance != (Object)null && DayNightManager.instance.isDay < 0.5f)
{
__instance.AddStatus((STATUSTYPE)2, Time.deltaTime * (1f - DayNightManager.instance.isDay) * Ascents.nightColdRate, false);
}
if ((Object)(object)character.data != (Object)null && character.data.fullyConscious)
{
__instance.AddStatus((STATUSTYPE)1, Time.deltaTime * __instance.hungerPerSecond * Ascents.hungerRateMultiplier, false);
}
if (__instance.GetCurrentStatus((STATUSTYPE)3) > 0f && Time.time - __instance.LastAddedStatus((STATUSTYPE)3) > __instance.poisonReductionCooldown)
{
__instance.AddStatus((STATUSTYPE)3, __instance.poisonReductionPerSecond * Time.deltaTime, false);
}
if (__instance.GetCurrentStatus((STATUSTYPE)6) > 0f && Time.time - __instance.LastAddedStatus((STATUSTYPE)6) > __instance.drowsyReductionCooldown)
{
float num = __instance.drowsyReductionPerSecond * Time.deltaTime;
if (ShouldInvertDrowsy())
{
__instance.AddStatus((STATUSTYPE)6, num, false);
}
else
{
__instance.SubtractStatus((STATUSTYPE)6, num, false);
}
}
if (__instance.GetCurrentStatus((STATUSTYPE)8) > 0f && Time.time - __instance.LastAddedStatus((STATUSTYPE)8) > __instance.hotReductionCooldown)
{
__instance.AddStatus((STATUSTYPE)8, __instance.hotReductionPerSecond * Time.deltaTime, false);
}
return false;
}
}
private const string InversionChallengeId = "inversion";
private const string NarcolepsyChallengeId = "narcolepsy";
private static bool IsInversionEnabled()
{
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("inversion"))
{
return ChallengesAPI.IsChallengeEnabled("inversion");
}
return false;
}
private static bool ShouldInvertDrowsy()
{
if (!ChallengesAPI.IsHell)
{
return true;
}
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("narcolepsy"))
{
return !ChallengesAPI.IsChallengeEnabled("narcolepsy");
}
return true;
}
}
internal static class NarcolepsyPatch
{
[HarmonyPatch(typeof(CharacterAfflictions))]
[HarmonyPatch("Update")]
private static class CharacterAfflictionsUpdateNarcolepsy
{
[HarmonyPostfix]
private static void Postfix(CharacterAfflictions __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
if (!IsNarcolepsyEnabled())
{
States.Clear();
return;
}
Character character = __instance.character;
if ((Object)(object)character == (Object)null || character.isBot || !character.IsLocal)
{
return;
}
PhotonView photonView = ((MonoBehaviourPun)character).photonView;
if ((Object)(object)photonView == (Object)null || !photonView.IsMine)
{
return;
}
CharacterData data = character.data;
bool flag = (Object)(object)data != (Object)null && data.fullyConscious;
NarcolepsyState orCreateState = GetOrCreateState(((Object)character).GetInstanceID(), flag);
if (!flag)
{
if (orCreateState.WasConscious)
{
orCreateState.NextTrigger = Time.time + GetNextIntervalSeconds();
}
orCreateState.WasConscious = false;
return;
}
orCreateState.WasConscious = true;
float time = Time.time;
if (!(time < orCreateState.NextTrigger))
{
float num = Mathf.Max(0f, 1f - (__instance.GetCurrentStatus((STATUSTYPE)0) + __instance.GetCurrentStatus((STATUSTYPE)1) + __instance.GetCurrentStatus((STATUSTYPE)9) + __instance.GetCurrentStatus((STATUSTYPE)2) + __instance.GetCurrentStatus((STATUSTYPE)8) + __instance.GetCurrentStatus((STATUSTYPE)3))) + 0.1f;
if (num > 0f && __instance.GetCurrentStatus((STATUSTYPE)6) < 0.05f)
{
__instance.AddStatus((STATUSTYPE)6, num, false);
}
photonView.RPC("RPCA_PassOut", (RpcTarget)0, Array.Empty<object>());
orCreateState.InstagibGraceUntil = time + 1f;
orCreateState.NextTrigger = time + GetNextIntervalSeconds();
}
}
}
private sealed class NarcolepsyState
{
public float NextTrigger;
public bool WasConscious;
public float InstagibGraceUntil;
}
private const string NarcolepsyChallengeId = "narcolepsy";
private const float MinIntervalSeconds = 60f;
private const float MaxIntervalSeconds = 360f;
private const float InstagibGracePeriod = 1f;
private static readonly Dictionary<int, NarcolepsyState> States = new Dictionary<int, NarcolepsyState>();
private static bool IsNarcolepsyEnabled()
{
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("narcolepsy"))
{
return ChallengesAPI.IsChallengeEnabled("narcolepsy");
}
return false;
}
private static float GetNextIntervalSeconds()
{
return Random.Range(60f, 360f);
}
private static NarcolepsyState GetOrCreateState(int key, bool isConscious)
{
if (!States.TryGetValue(key, out var value))
{
value = new NarcolepsyState
{
NextTrigger = Time.time + GetNextIntervalSeconds(),
WasConscious = isConscious
};
States[key] = value;
}
return value;
}
internal static bool ShouldPreventInstagib(Character character)
{
if ((Object)(object)character == (Object)null)
{
return false;
}
if (!IsNarcolepsyEnabled())
{
return false;
}
int instanceID = ((Object)character).GetInstanceID();
if (!States.TryGetValue(instanceID, out var value))
{
return false;
}
return Time.time <= value.InstagibGraceUntil;
}
}
internal static class PlaneCrashPatch
{
[HarmonyPatch(typeof(CharacterAfflictions))]
[HarmonyPatch("Update")]
private static class CharacterAfflictionsUpdatePlaneCrash
{
[HarmonyPostfix]
private static void Postfix(CharacterAfflictions __instance)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null)
{
return;
}
EnsureInitialized();
if (!IsPlaneCrashEnabled())
{
AppliedCharacters.Clear();
return;
}
Character character = __instance.character;
if ((Object)(object)character == (Object)null || character.isBot || !character.IsLocal)
{
return;
}
PhotonView photonView = ((MonoBehaviourPun)character).photonView;
if ((Object)(object)photonView == (Object)null || !photonView.IsMine)
{
return;
}
Scene activeScene = SceneManager.GetActiveScene();
if (!((Scene)(ref activeScene)).IsValid() || !string.Equals(((Scene)(ref activeScene)).name ?? string.Empty, "Airport", StringComparison.OrdinalIgnoreCase))
{
int instanceID = ((Object)character).GetInstanceID();
if (!AppliedCharacters.Contains(instanceID))
{
__instance.SetStatus((STATUSTYPE)0, 0.9f);
AppliedCharacters.Add(instanceID);
}
}
}
}
private const string PlaneCrashChallengeId = "planecrash";
private const float InjuryAmount = 0.9f;
private static readonly HashSet<int> AppliedCharacters = new HashSet<int>();
private static bool _initialized;
private static bool IsPlaneCrashEnabled()
{
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("planecrash"))
{
return ChallengesAPI.IsChallengeEnabled("planecrash");
}
return false;
}
private static void EnsureInitialized()
{
if (!_initialized)
{
ChallengesAPI.SceneLoaded += HandleSceneLoaded;
_initialized = true;
}
}
private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
{
AppliedCharacters.Clear();
}
}
internal static class ScoutmasterLurksPatch
{
[HarmonyPatch(typeof(Scoutmaster), "LookForTarget")]
private static class ScoutmasterLookForTarget
{
[HarmonyPrefix]
private static bool Prefix(Scoutmaster __instance)
{
if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
{
return true;
}
if (SinceLookForTargetField == null || CharacterField == null)
{
return true;
}
if (!(SinceLookForTargetField.GetValue(__instance) is float num))
{
return true;
}
bool flag = IsNight();
if (!flag && num < 30f)
{
return false;
}
SinceLookForTargetField.SetValue(__instance, 0f);
if (!flag)
{
SetCurrentTarget(__instance, null, 0f);
return false;
}
Character scoutmasterCharacter = GetScoutmasterCharacter(__instance);
if ((Object)(object)scoutmasterCharacter == (Object)null)
{
SetCurrentTarget(__instance, null, 0f);
return false;
}
Character closestLivingPlayer = GetClosestLivingPlayer(scoutmasterCharacter);
if (!IsValidTarget(closestLivingPlayer))
{
SetCurrentTarget(__instance, null, 0f);
return false;
}
SetCurrentTarget(__instance, closestLivingPlayer, 0f);
return false;
}
}
[HarmonyPatch(typeof(Scoutmaster), "VerifyTarget")]
private static class ScoutmasterVerifyTarget
{
[HarmonyPrefix]
private static bool Prefix(Scoutmaster __instance)
{
if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
{
return true;
}
Character scoutmasterCharacter = GetScoutmasterCharacter(__instance);
if ((Object)(object)scoutmasterCharacter == (Object)null)
{
return true;
}
Character val = __instance.currentTarget;
if (!IsValidTarget(val))
{
val = null;
}
Character closestLivingPlayer = GetClosestLivingPlayer(scoutmasterCharacter);
if (!IsValidTarget(closestLivingPlayer))
{
if ((Object)(object)val != (Object)null)
{
SetCurrentTarget(__instance, null, 0f);
}
return false;
}
if ((Object)(object)val != (Object)(object)closestLivingPlayer)
{
SetCurrentTarget(__instance, closestLivingPlayer, 0f);
}
return false;
}
}
[HarmonyPatch(typeof(Scoutmaster), "Update")]
private static class ScoutmasterUpdate
{
[HarmonyPostfix]
private static void Postfix(Scoutmaster __instance)
{
if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
{
return;
}
PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
if (!((Object)(object)component != (Object)null) || component.IsMine)
{
int instanceID = ((Object)__instance).GetInstanceID();
if (IsNight())
{
LeftForDay.Remove(instanceID);
}
else if (LeftForDay.Add(instanceID))
{
SetCurrentTarget(__instance, null, 0f);
ForceTeleportAway(__instance);
}
}
}
}
[HarmonyPatch(typeof(Scoutmaster), "Chase")]
private static class ScoutmasterChase
{
[HarmonyPostfix]
private static void Postfix(Scoutmaster __instance)
{
//IL_004b: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
if (!IsChallengeEnabled() || (Object)(object)__instance == (Object)null)
{
return;
}
PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
if ((Object)(object)component != (Object)null && !component.IsMine)
{
return;
}
Character scoutmasterCharacter = GetScoutmasterCharacter(__instance);
Character currentTarget = __instance.currentTarget;
if (!IsValidTarget(currentTarget) || (Object)(object)scoutmasterCharacter == (Object)null)
{
return;
}
float num = Vector3.Distance(scoutmasterCharacter.Center, currentTarget.Center);
float num2 = 0f;
if (TargetHasSeenCounterField != null)
{
num2 = (float)TargetHasSeenCounterField.GetValue(__instance);
}
if (!(num2 >= 0.5f) && !(num < 18f))
{
float num3 = Mathf.Clamp((num - 4f) / 12f, 0f, 1f);
if (num < 12f)
{
num3 = Mathf.Clamp((num - 10f) / 8f, -0.2f, 0.25f);
}
scoutmasterCharacter.input.movementInput = new Vector2(0f, num3);
bool useSecondaryIsPressed = num < 3.5f && num2 > 0.2f;
scoutmasterCharacter.input.useSecondaryIsPressed = useSecondaryIsPressed;
if (num < 8f && ChillForSecondsField != null && (float)ChillForSecondsField.GetValue(__instance) < 0.75f)
{
ChillForSecondsField.SetValue(__instance, 0.75f);
}
}
}
}
private const string ChallengeId = "scoutmasterlurks";
private static readonly FieldInfo SinceLookForTargetField = AccessTools.Field(typeof(Scoutmaster), "sinceLookForTarget");
private static readonly FieldInfo CharacterField = AccessTools.Field(typeof(Scoutmaster), "character");
private static readonly MethodInfo SetCurrentTargetMethod = AccessTools.Method(typeof(Scoutmaster), "SetCurrentTarget", (Type[])null, (Type[])null);
private static readonly FieldInfo ChillForSecondsField = AccessTools.Field(typeof(Scoutmaster), "chillForSeconds");
private static readonly FieldInfo TpCounterField = AccessTools.Field(typeof(Scoutmaster), "tpCounter");
private static readonly FieldInfo TargetHasSeenCounterField = AccessTools.Field(typeof(Scoutmaster), "targetHasSeenMeCounter");
private static readonly HashSet<int> LeftForDay = new HashSet<int>();
private static bool IsChallengeEnabled()
{
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("scoutmasterlurks"))
{
return ChallengesAPI.IsChallengeEnabled("scoutmasterlurks");
}
return false;
}
private static Character GetScoutmasterCharacter(Scoutmaster scoutmaster)
{
if ((Object)(object)scoutmaster == (Object)null)
{
return null;
}
object? obj = CharacterField?.GetValue(scoutmaster);
Character val = (Character)((obj is Character) ? obj : null);
if ((Object)(object)val != (Object)null)
{
return val;
}
return ((Component)scoutmaster).GetComponent<Character>();
}
private static bool IsNight()
{
if ((Object)(object)DayNightManager.instance != (Object)null)
{
return DayNightManager.instance.isDay < 0.5f;
}
return false;
}
private static bool IsValidTarget(Character character)
{
if ((Object)(object)character == (Object)null || character.isBot)
{
return false;
}
CharacterData data = character.data;
if ((Object)(object)data == (Object)null || data.dead || data.fullyPassedOut)
{
return false;
}
return true;
}
private static Character GetClosestLivingPlayer(Character scoutmasterCharacter)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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_0046: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)scoutmasterCharacter == (Object)null)
{
return null;
}
Character result = null;
float num = float.MaxValue;
Vector3 center = scoutmasterCharacter.Center;
foreach (Character allCharacter in Character.AllCharacters)
{
if (IsValidTarget(allCharacter) && !((Object)(object)allCharacter == (Object)(object)scoutmasterCharacter))
{
float num2 = Vector3.Distance(center, allCharacter.Center);
if (num2 < num)
{
num = num2;
result = allCharacter;
}
}
}
return result;
}
private static void SetCurrentTarget(Scoutmaster scoutmaster, Character target, float force)
{
if (!((Object)(object)scoutmaster == (Object)null) && !(SetCurrentTargetMethod == null))
{
SetCurrentTargetMethod.Invoke(scoutmaster, new object[2] { target, force });
}
}
private static void ForceTeleportAway(Scoutmaster scoutmaster)
{
//IL_0020: 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_0033: 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)
if ((Object)(object)scoutmaster == (Object)null)
{
return;
}
Character scoutmasterCharacter = GetScoutmasterCharacter(scoutmaster);
if ((Object)(object)scoutmasterCharacter != (Object)null)
{
Vector3 position = ((Component)scoutmasterCharacter).transform.position;
if (position.z > 4900f && Mathf.Abs(position.x) < 20f && Mathf.Abs(position.y) < 20f)
{
return;
}
}
if (TpCounterField != null)
{
TpCounterField.SetValue(scoutmaster, 0f);
}
if (ChillForSecondsField != null)
{
ChillForSecondsField.SetValue(scoutmaster, 5f);
}
scoutmaster.TeleportFarAway();
}
}
public static class SnowPatch
{
private class FrostbiteWindController : MonoBehaviour
{
private static readonly Vector2 ForcedOnRange = new Vector2(999999f, 999999f);
private static readonly Vector2 ForcedOffRange = Vector2.zero;
private static readonly MethodInfo ToggleWind = typeof(WindChillZone).GetMethod("RPCA_ToggleWind", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly MethodInfo RandomWind = typeof(WindChillZone).GetMethod("RandomWindDirection", BindingFlags.Instance | BindingFlags.NonPublic);
private WindChillZone _zone;
private PhotonView _view;
private float _retryTimer;
private void Awake()
{
_zone = ((Component)this).GetComponent<WindChillZone>();
_view = ((Component)this).GetComponent<PhotonView>();
}
private void OnEnable()
{
EnsureStorm(forceRpc: true);
}
private void Update()
{
EnsureStorm();
}
private void EnsureStorm(bool forceRpc = false)
{
//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)
//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)
if ((Object)(object)_zone == (Object)null)
{
((Behaviour)this).enabled = false;
return;
}
_zone.windTimeRangeOn = ForcedOnRange;
_zone.windTimeRangeOff = ForcedOffRange;
if (_zone.windActive && !forceRpc)
{
MaintainSwitchTimer();
}
else
{
TryActivateStorm();
}
}
private void MaintainSwitchTimer()
{
if (PhotonNetwork.IsMasterClient)
{
_retryTimer -= Time.deltaTime;
if (!(_retryTimer > 0f))
{
_retryTimer = 30f;
TryActivateStorm();
}
}
}
private void TryActivateStorm()
{
//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)
//IL_0024: 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_008f: 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)
Vector3 val = Vector3.forward;
if (RandomWind != null)
{
try
{
val = (Vector3)RandomWind.Invoke(_zone, null);
}
catch
{
}
}
if (PhotonNetwork.IsMasterClient && (Object)(object)_view != (Object)null)
{
_view.RPC("RPCA_ToggleWind", (RpcTarget)0, new object[2] { true, val });
}
else
{
ToggleWind?.Invoke(_zone, new object[2] { true, val });
}
}
}
private const string FrostbiteId = "permasnow";
private const float ForcedStormDuration = 999999f;
private static bool _initialized;
public static void Init()
{
if (!_initialized)
{
_initialized = true;
ChallengesAPI.SceneLoaded += HandleSceneLoaded;
}
}
private static void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0007: 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)
if (IsFrostbiteEnabled() && IsGameplayScene(scene))
{
ApplyStorm(scene);
}
}
private static bool IsGameplayScene(Scene scene)
{
if (!((Scene)(ref scene)).IsValid())
{
return false;
}
string text = ((Scene)(ref scene)).name ?? string.Empty;
if (!(text == "WilIsland"))
{
return text.StartsWith("level_", StringComparison.OrdinalIgnoreCase);
}
return true;
}
private static bool IsFrostbiteEnabled()
{
if (ChallengesAPI.challenges != null && ChallengesAPI.challenges.ContainsKey("permasnow"))
{
return ChallengesAPI.IsChallengeEnabled("permasnow");
}
return false;
}
private static void ApplyStorm(Scene scene)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
WindChillZone[] array = FindWindChillZones();
if (array == null || array.Length == 0)
{
return;
}
foreach (WindChillZone val in array)
{
if (!((Object)(object)val == (Object)null) && !(((Component)val).gameObject.scene != scene))
{
AttachController(val);
}
}
}
private static WindChillZone[] FindWindChillZones()
{
try
{
return Object.FindObjectsOfType<WindChillZone>(true);
}
catch
{
return Object.FindObjectsOfType<WindChillZone>();
}
}
private static void AttachController(WindChillZone zone)
{
if (!((Object)(object)((Component)zone).gameObject.GetComponent<FrostbiteWindController>() != (Object)null))
{
((Component)zone).gameObject.AddComponent<FrostbiteWindController>();
}
}
}
public static class TuckeredOut
{
[HarmonyPatch(typeof(CharacterAfflictions), "UpdateNormalStatuses")]
private static class TuckeredOutPatch
{
[HarmonyPostfix]
private static void Postfix(CharacterAfflictions __instance)
{
if (ChallengesAPI.IsChallengeEnabled("tuckered_out") && __instance.character.IsLocal && __instance.character.refs.afflictions.GetCurrentStatus((STATUSTYPE)7) > 0f)
{
__instance.character.refs.afflictions.AddStatus((STATUSTYPE)6, __instance.character.refs.afflictions.GetCurrentStatus((STATUSTYPE)7) * Time.deltaTime / 60f, false);
}
}
}
}
}