using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using Photon.Pun;
using Steamworks;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("MoreChances")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreChances")]
[assembly: AssemblyTitle("MoreChances")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace MoreChances
{
[BepInPlugin("MoreChances", "MoreChances", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
public static ConfigEntry<bool> AllowArena;
public static ConfigEntry<bool> GoArenaDelete;
public static ConfigEntry<bool> AllDeadDelete;
public static ConfigEntry<bool> ReviveHPEnable;
public static ConfigEntry<bool> WhateverNoDelete;
public static ConfigEntry<int> ReviveHP;
public static ConfigEntry<bool> TruckHealEnable;
public static ConfigEntry<int> TruckHealHP;
public static ConfigEntry<bool> ChargingStationInfinityPower;
private REPOButton reMapBtn;
private REPOButton shopBtn;
private REPOButton testBtn;
private FieldRef<ChargingStation, float> charge = AccessTools.FieldRefAccess<ChargingStation, float>("charge");
private void Awake()
{
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Expected O, but got Unknown
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BaseUnityPlugin)this).Logger;
AllowArena = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Go to Arena", false, "Default: Off, Restart current progress after team wipe, will not go to arena");
GoArenaDelete = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Arena (Delete Save)", false, "Default: Off, Even if you enter the arena, the save will not be deleted");
AllDeadDelete = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Delete Save After Team Wipe", false, "Default: Off, Save will not be deleted after team wipe");
ReviveHPEnable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Adjust HP on Revive", true, "Default: On, Initial HP boost when restarting");
WhateverNoDelete = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "When exiting (deleting archives)", false, "Default: Off, no matter what, the archive is not deleted");
ReviveHP = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Revive HP (%)", 100, new ConfigDescription("Default: 100%, Full HP recovery", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
TruckHealEnable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Adjust HP on Truck", true, "Default: On, HP recovery boost when driving the truck");
TruckHealHP = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Truck Heal HP (%)", 100, new ConfigDescription("Default: 100%, Full HP recovery", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
ChargingStationInfinityPower = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Unlimited Charging (Truck)", true, "Default: On, the truck can be charged infinitely");
Logger.LogInfo((object)"MoreChances loaded!");
new Hook((MethodBase)AccessTools.Method(typeof(RunManager), "Awake", (Type[])null, (Type[])null), (Delegate)(Action<Action<RunManager>, RunManager>)delegate(Action<RunManager> orig, RunManager self)
{
orig(self);
if ((Object)(object)((Component)self).gameObject.GetComponent<MoreChances>() == (Object)null)
{
((Component)self).gameObject.AddComponent<MoreChances>();
((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreChances Added!");
}
}).Apply();
}
public void Update()
{
if (ChargingStationInfinityPower.Value && Object.op_Implicit((Object)(object)ChargingStation.instance) && !SemiFunc.RunIsShop())
{
charge.Invoke(ChargingStation.instance) = 1f;
}
}
}
public class MoreChances : MonoBehaviour
{
private delegate void orig_RunManager_Update(RunManager self);
private delegate void hook_RunManager_Update(orig_RunManager_Update orig, RunManager self);
private delegate void orig_RunManager_ChangeLevel(RunManager self, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType);
private delegate void hook_RunManager_ChangeLevel(orig_RunManager_ChangeLevel orig, RunManager self, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType);
private delegate void orig_DataDirector_SaveDeleteCheck(DataDirector self, bool _leaveGame);
private delegate void hook_DataDirector_SaveDeleteCheck(orig_DataDirector_SaveDeleteCheck orig, DataDirector self, bool _leaveGame);
private delegate void orig_PlayerAvatar_ReviveRPC(PlayerAvatar self, bool _revivedByTruck);
private delegate void hook_PlayerAvatar_ReviveRPC(orig_PlayerAvatar_ReviveRPC orig, PlayerAvatar self, bool _revivedByTruck);
private delegate void orig_PlayerAvatar_FinalHealRPC(PlayerAvatar self);
private delegate void hook_PlayerAvatar_FinalHealRPC(orig_PlayerAvatar_FinalHealRPC orig, PlayerAvatar self);
private delegate IEnumerator orig_PlayerHealth_Fetch(PlayerHealth self);
private delegate IEnumerator hook_PlayerHealth_Fetch(orig_PlayerHealth_Fetch orig, PlayerHealth self);
private static bool isHooked;
private FieldRef<RunManager, bool> restarting = AccessTools.FieldRefAccess<RunManager, bool>("restarting");
private FieldRef<RunManager, bool> runStarted = AccessTools.FieldRefAccess<RunManager, bool>("runStarted");
private FieldRef<RunManager, bool> allPlayersDead = AccessTools.FieldRefAccess<RunManager, bool>("allPlayersDead");
private FieldRef<RunManager, bool> gameOver = AccessTools.FieldRefAccess<RunManager, bool>("gameOver");
private FieldRef<RunManager, int> saveLevel = AccessTools.FieldRefAccess<RunManager, int>("saveLevel");
private FieldRef<RunManager, RunManagerPUN> runManagerPUN = AccessTools.FieldRefAccess<RunManager, RunManagerPUN>("runManagerPUN");
private FieldRef<RunManager, Level> levelPrevious = AccessTools.FieldRefAccess<RunManager, Level>("levelPrevious");
private FieldRef<RunManager, Level> previousRunLevel = AccessTools.FieldRefAccess<RunManager, Level>("previousRunLevel");
private FieldRef<RunManager, Level> debugLevel = AccessTools.FieldRefAccess<RunManager, Level>("debugLevel");
private FieldRef<PlayerAvatar, bool> isDisabled = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");
private FieldRef<PlayerAvatar, bool> finalHeal = AccessTools.FieldRefAccess<PlayerAvatar, bool>("finalHeal");
private FieldRef<PlayerAvatar, string> playerName = AccessTools.FieldRefAccess<PlayerAvatar, string>("playerName");
private FieldRef<PlayerHealth, int> maxHealth = AccessTools.FieldRefAccess<PlayerHealth, int>("maxHealth");
private FieldRef<PlayerHealth, PhotonView> photonView = AccessTools.FieldRefAccess<PlayerHealth, PhotonView>("photonView");
private FieldRef<PlayerHealth, PlayerAvatar> playerAvatar = AccessTools.FieldRefAccess<PlayerHealth, PlayerAvatar>("playerAvatar");
private FieldRef<PlayerHealth, int> health = AccessTools.FieldRefAccess<PlayerHealth, int>("health");
private FieldRef<PlayerHealth, bool> healthSet = AccessTools.FieldRefAccess<PlayerHealth, bool>("healthSet");
private FieldRef<StatsManager, string> saveFileCurrent = AccessTools.FieldRefAccess<StatsManager, string>("saveFileCurrent");
public void Awake()
{
//IL_002c: 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_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: 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)
if (!isHooked)
{
new Hook((MethodBase)AccessTools.Method(typeof(RunManager), "Update", (Type[])null, (Type[])null), (Delegate)new hook_RunManager_Update(RunManager_Update)).Apply();
new Hook((MethodBase)AccessTools.Method(typeof(RunManager), "ChangeLevel", (Type[])null, (Type[])null), (Delegate)new hook_RunManager_ChangeLevel(RunManager_ChangeLevel)).Apply();
new Hook((MethodBase)AccessTools.Method(typeof(DataDirector), "SaveDeleteCheck", (Type[])null, (Type[])null), (Delegate)new hook_DataDirector_SaveDeleteCheck(DataDirector_SaveDeleteCheck)).Apply();
new Hook((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "ReviveRPC", (Type[])null, (Type[])null), (Delegate)new hook_PlayerAvatar_ReviveRPC(PlayerAvatar_ReviveRPC)).Apply();
new Hook((MethodBase)AccessTools.Method(typeof(PlayerHealth), "Fetch", (Type[])null, (Type[])null), (Delegate)new hook_PlayerHealth_Fetch(PlayerAvatar_Fetch)).Apply();
new Hook((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "FinalHealRPC", (Type[])null, (Type[])null), (Delegate)new hook_PlayerAvatar_FinalHealRPC(PlayerAvatar_FinalHealRPC)).Apply();
isHooked = true;
}
}
private void PlayerAvatar_FinalHealRPC(orig_PlayerAvatar_FinalHealRPC orig, PlayerAvatar self)
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
if (finalHeal.Invoke(self))
{
return;
}
if (self.photonView.IsMine)
{
self.playerHealth.EyeMaterialOverride((EyeOverrideState)2, 2f, 1);
TruckScreenText.instance.MessageSendCustom("", playerName.Invoke(self) + " {arrowright}{truck}{check}\n {point}{shades}{pointright}<b><color=#00FF00>+25</color></b>{heart}", 0);
if (Plugin.TruckHealEnable.Value)
{
int num = Mathf.RoundToInt((float)(maxHealth.Invoke(self.playerHealth) * Plugin.TruckHealHP.Value) / 100f);
self.playerHealth.Heal(num, true);
}
else
{
self.playerHealth.Heal(25, true);
}
}
TruckHealer.instance.Heal(self);
self.truckReturn.Play(self.PlayerVisionTarget.VisionTransform.position, 1f, 1f, 1f, 1f);
self.truckReturnGlobal.Play(self.PlayerVisionTarget.VisionTransform.position, 1f, 1f, 1f, 1f);
((Component)self.playerAvatarVisuals.effectGetIntoTruck).gameObject.SetActive(true);
finalHeal.Invoke(self) = true;
}
private IEnumerator PlayerAvatar_Fetch(orig_PlayerHealth_Fetch orig, PlayerHealth self)
{
while (!LevelGenerator.Instance.Generated)
{
yield return (object)new WaitForSeconds(0.1f);
}
maxHealth.Invoke(self) = 100 + StatsManager.instance.GetPlayerMaxHealth(SemiFunc.PlayerGetSteamID(playerAvatar.Invoke(self)));
int num = StatsManager.instance.GetPlayerHealth(SemiFunc.PlayerGetSteamID(playerAvatar.Invoke(self)));
if (num <= 0)
{
num = ((!Plugin.ReviveHPEnable.Value) ? 1 : Mathf.RoundToInt((float)(maxHealth.Invoke(self) * Plugin.ReviveHP.Value) / 100f));
}
health.Invoke(self) = Mathf.Clamp(num, 0, maxHealth.Invoke(self));
if (SemiFunc.RunIsArena())
{
health.Invoke(self) = maxHealth.Invoke(self);
}
StatsManager.instance.SetPlayerHealth(SemiFunc.PlayerGetSteamID(playerAvatar.Invoke(self)), health.Invoke(self), false);
if (GameManager.Multiplayer())
{
photonView.Invoke(self).RPC("UpdateHealthRPC", (RpcTarget)1, new object[3]
{
health.Invoke(self),
maxHealth.Invoke(self),
true
});
}
healthSet.Invoke(self) = true;
}
private void PlayerAvatar_ReviveRPC(orig_PlayerAvatar_ReviveRPC orig, PlayerAvatar self, bool _revivedByTruck)
{
orig(self, _revivedByTruck);
HealPlayer(self);
}
private void HealPlayer(PlayerAvatar self)
{
if (self.photonView.IsMine && Plugin.ReviveHPEnable.Value)
{
int num = Mathf.RoundToInt((float)(maxHealth.Invoke(self.playerHealth) * Plugin.ReviveHP.Value) / 100f);
self.playerHealth.HealOther(num, true);
Plugin.Logger.LogInfo((object)$"HealPlayer Called. heal +{num}hp");
}
}
private void DataDirector_SaveDeleteCheck(orig_DataDirector_SaveDeleteCheck orig, DataDirector self, bool _leaveGame)
{
if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)levelPrevious.Invoke(RunManager.instance) == (Object)(object)RunManager.instance.levelTutorial) && !((Object)(object)levelPrevious.Invoke(RunManager.instance) == (Object)(object)RunManager.instance.levelLobbyMenu) && !((Object)(object)levelPrevious.Invoke(RunManager.instance) == (Object)(object)RunManager.instance.levelMainMenu) && !((Object)(object)levelPrevious.Invoke(RunManager.instance) == (Object)(object)RunManager.instance.levelRecording))
{
bool flag = false;
if (SemiFunc.RunIsArena())
{
flag = Plugin.GoArenaDelete.Value;
}
else if (allPlayersDead.Invoke(RunManager.instance) && (Object)(object)levelPrevious.Invoke(RunManager.instance) != (Object)(object)RunManager.instance.levelMainMenu && (Object)(object)levelPrevious.Invoke(RunManager.instance) != (Object)(object)RunManager.instance.levelLobbyMenu && (Object)(object)levelPrevious.Invoke(RunManager.instance) != (Object)(object)RunManager.instance.levelTutorial && (Object)(object)levelPrevious.Invoke(RunManager.instance) != (Object)(object)RunManager.instance.levelLobby && (Object)(object)levelPrevious.Invoke(RunManager.instance) != (Object)(object)RunManager.instance.levelShop && (Object)(object)levelPrevious.Invoke(RunManager.instance) != (Object)(object)RunManager.instance.levelRecording)
{
flag = Plugin.AllDeadDelete.Value;
}
else if (_leaveGame && RunManager.instance.levelsCompleted == 0)
{
flag = Plugin.WhateverNoDelete.Value;
}
if (flag)
{
SemiFunc.SaveFileDelete(saveFileCurrent.Invoke(StatsManager.instance));
}
}
}
private void RunManager_ChangeLevel(orig_RunManager_ChangeLevel orig, RunManager self, bool _completedLevel, bool _levelFailed, ChangeLevelType _changeLevelType)
{
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Invalid comparison between Unknown and I4
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Invalid comparison between Unknown and I4
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Invalid comparison between Unknown and I4
//IL_0341: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Invalid comparison between Unknown and I4
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Invalid comparison between Unknown and I4
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Invalid comparison between Unknown and I4
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Invalid comparison between Unknown and I4
if ((!SemiFunc.MenuLevel() && !SemiFunc.IsMasterClientOrSingleplayer()) || restarting.Invoke(self))
{
return;
}
gameOver.Invoke(self) = false;
if (_levelFailed && (Object)(object)self.levelCurrent != (Object)(object)self.levelLobby && (Object)(object)self.levelCurrent != (Object)(object)self.levelShop)
{
if ((Object)(object)self.levelCurrent == (Object)(object)self.levelArena)
{
if (Plugin.GoArenaDelete.Value)
{
self.ResetProgress();
}
if (SemiFunc.IsMultiplayer())
{
self.levelCurrent = self.levelLobbyMenu;
}
else
{
self.SetRunLevel();
}
gameOver.Invoke(self) = true;
}
else
{
self.levelCurrent = self.levelArena;
}
}
if (!gameOver.Invoke(self) && (Object)(object)self.levelCurrent != (Object)(object)self.levelArena)
{
if ((int)_changeLevelType == 1)
{
self.SetRunLevel();
}
else if ((int)_changeLevelType == 3)
{
self.levelCurrent = self.levelLobbyMenu;
}
else if ((int)_changeLevelType == 4)
{
self.levelCurrent = self.levelMainMenu;
}
else if ((int)_changeLevelType == 2)
{
self.levelCurrent = self.levelTutorial;
}
else if ((int)_changeLevelType == 6)
{
self.levelCurrent = self.levelRecording;
}
else if ((int)_changeLevelType == 5)
{
self.levelCurrent = self.levelShop;
}
else if ((Object)(object)self.levelCurrent == (Object)(object)self.levelMainMenu || (Object)(object)self.levelCurrent == (Object)(object)self.levelLobbyMenu)
{
self.levelCurrent = self.levelLobby;
}
else if (_completedLevel && (Object)(object)self.levelCurrent != (Object)(object)self.levelLobby && (Object)(object)self.levelCurrent != (Object)(object)self.levelShop)
{
previousRunLevel.Invoke(self) = self.levelCurrent;
self.levelsCompleted++;
SemiFunc.StatSetRunLevel(self.levelsCompleted);
SemiFunc.LevelSuccessful();
self.levelCurrent = self.levelShop;
}
else if ((Object)(object)self.levelCurrent == (Object)(object)self.levelLobby)
{
self.SetRunLevel();
}
else if ((Object)(object)self.levelCurrent == (Object)(object)self.levelShop)
{
self.levelCurrent = self.levelLobby;
}
}
if (Object.op_Implicit((Object)(object)debugLevel.Invoke(self)) && (Object)(object)self.levelCurrent != (Object)(object)self.levelMainMenu && (Object)(object)self.levelCurrent != (Object)(object)self.levelLobbyMenu)
{
self.levelCurrent = debugLevel.Invoke(self);
}
if (GameManager.Multiplayer())
{
((Component)runManagerPUN.Invoke(self)).GetComponent<PhotonView>().RPC("UpdateLevelRPC", (RpcTarget)4, new object[3]
{
((Object)self.levelCurrent).name,
self.levelsCompleted,
gameOver.Invoke(self)
});
}
Debug.Log((object)("Changed level to: " + ((Object)self.levelCurrent).name));
if ((Object)(object)self.levelCurrent == (Object)(object)self.levelShop)
{
saveLevel.Invoke(self) = 1;
}
else
{
saveLevel.Invoke(self) = 0;
}
SemiFunc.StatSetSaveLevel(saveLevel.Invoke(self));
self.RestartScene();
if ((int)_changeLevelType != 2)
{
SemiFunc.OnSceneSwitch(gameOver.Invoke(self), false);
}
}
private void RunManager_Update(orig_RunManager_Update orig, RunManager self)
{
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Invalid comparison between Unknown and I4
if (GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient)
{
return;
}
if (LevelGenerator.Instance.Generated && !SteamClient.IsValid && !((Behaviour)SteamManager.instance).enabled)
{
Debug.LogError((object)"Steam not initialized. Quitting game.");
Application.Quit();
}
if (restarting.Invoke(self))
{
self.RestartScene();
}
if (restarting.Invoke(self) || !runStarted.Invoke(self) || GameDirector.instance.PlayerList.Count <= 0 || SemiFunc.RunIsArena() || (int)GameDirector.instance.currentState != 2)
{
return;
}
bool flag = true;
using (List<PlayerAvatar>.Enumerator enumerator = GameDirector.instance.PlayerList.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (!isDisabled.Invoke(enumerator.Current))
{
flag = false;
break;
}
}
}
if (!flag)
{
return;
}
allPlayersDead.Invoke(self) = true;
if (Object.op_Implicit((Object)(object)SpectateCamera.instance) && SpectateCamera.instance.CheckState((State)1))
{
if (Plugin.AllowArena.Value)
{
self.ChangeLevel(false, true, (ChangeLevelType)0);
}
else
{
self.ChangeLevel(false, false, (ChangeLevelType)1);
}
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "MoreChances";
public const string PLUGIN_NAME = "MoreChances";
public const string PLUGIN_VERSION = "1.0.0";
}
}