Decompiled source of PillarRevive v1.1.0

PillarRevive.dll

Decompiled 7 months ago
using System;
using System.Collections;
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 HG.Reflection;
using On.RoR2;
using R2API;
using R2API.Utils;
using RoR2;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
internal static class log
{
	private static ManualLogSource logger;

	internal static void start(ManualLogSource logSource)
	{
		logger = logSource;
	}

	internal static void start(string name)
	{
		logger = Logger.CreateLogSource(name);
	}

	internal static void info(object data)
	{
		logger.LogInfo(data);
	}

	internal static void message(object data)
	{
		logger.LogMessage(data);
	}

	internal static void warning(object data)
	{
		logger.LogWarning(data);
	}

	internal static void error(object data)
	{
		logger.LogError(data);
	}

	internal static void fatal(object data)
	{
		logger.LogFatal(data);
	}
}
namespace PillarRevive;

[BepInPlugin("dolso.pillarrevive", "PillarRevive", "1.1.0")]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class Main : BaseUnityPlugin
{
	private void Awake()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		log.start(((BaseUnityPlugin)this).Logger);
		PRConfig.DoConfig();
		Prefab.CreatePrefabs();
		GlobalEventManager.OnPlayerCharacterDeath += new hook_OnPlayerCharacterDeath(OnPlayerDeath);
	}

	private void OnPlayerDeath(orig_OnPlayerCharacterDeath orig, GlobalEventManager self, DamageReport damagereport, NetworkUser networkuser)
	{
		orig.Invoke(self, damagereport, networkuser);
		if (PRConfig.Enabled.Value)
		{
			((MonoBehaviour)this).StartCoroutine(TrySpawnPillar(damagereport, networkuser));
		}
	}

	private IEnumerator TrySpawnPillar(DamageReport damagereport, NetworkUser networkuser)
	{
		yield return (object)new WaitForSeconds(1.5f);
		int num;
		if (networkuser == null)
		{
			num = 0;
		}
		else
		{
			CharacterMaster master = networkuser.master;
			num = ((((master != null) ? new bool?(master.IsDeadAndOutOfLivesServer()) : null) == false) ? 1 : 0);
		}
		if (num != 0 || Run.instance.isGameOverServer)
		{
			yield break;
		}
		GameObject val = SpawnPillar(damagereport.victimMaster);
		PlayerRevive component = val.GetComponent<PlayerRevive>();
		component.SetNetworkUser(networkuser);
		if (Object.op_Implicit((Object)(object)TeleporterInteraction.instance))
		{
			if (Run.instance.stageClearCount == 0 && TeleporterInteraction.instance.currentState is IdleState)
			{
				HoldoutZoneController component2 = val.GetComponent<HoldoutZoneController>();
				component2.baseChargeDuration /= PRConfig.EarlyGameDivider.Value;
				CombatDirector component3 = val.GetComponent<CombatDirector>();
				component3.monsterCredit /= PRConfig.EarlyGameDivider.Value;
				log.info("Applied early game boost");
			}
			else if (TeleporterInteraction.instance.currentState is ChargedState)
			{
				HoldoutZoneController component4 = val.GetComponent<HoldoutZoneController>();
				component4.baseChargeDuration /= PRConfig.PostTeleDivider.Value;
				CombatDirector component5 = val.GetComponent<CombatDirector>();
				component5.monsterCredit /= PRConfig.PostTeleDivider.Value;
				component.setTeleFinished = true;
				log.info("Applied post teleporter boost");
			}
		}
	}

	private GameObject SpawnPillar(CharacterMaster master)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = (Vector3)(((??)TeleportHelper.FindSafeTeleportDestination(master.deathFootPosition, master.bodyPrefab.GetComponent<CharacterBody>(), RoR2Application.rng)) ?? master.deathFootPosition);
		GameObject obj = Object.Instantiate<GameObject>(Prefab.prefabs.Evaluate(Run.instance.stageRng.nextNormalizedFloat), val, default(Quaternion));
		NetworkServer.Spawn(obj);
		return obj;
	}

	[ConCommand(/*Could not decode attribute arguments.*/)]
	private static void PRPillarToggle(ConCommandArgs args)
	{
		if (PRConfig.Enabled.Value)
		{
			Debug.Log((object)"Disabled new pillars from spawning");
		}
		else
		{
			Debug.Log((object)"Enabled PillarRevive");
		}
		PRConfig.Enabled.Value = !PRConfig.Enabled.Value;
	}
}
internal class PRConfig
{
	internal class PillarConfig
	{
		public ConfigEntry<float> weight;

		public ConfigEntry<float> chargeDuration;

		public ConfigEntry<float> monsterCredits;

		public PillarConfig(byte index)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			string text = Prefab.pillarNames[index];
			weight = ConfigFile.Bind<float>(text, "Weight", 1f, new ConfigDescription("Spawn weighting of " + text + " Pillar", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			float num = 30f;
			switch (index)
			{
			case 0:
				num = 10f;
				break;
			case 2:
				num = 60f;
				break;
			}
			chargeDuration = ConfigFile.Bind<float>(text, "Charge duration", num, "Charge duration of " + text + " Pillar");
			monsterCredits = ConfigFile.Bind<float>(text, "Monster Credits", 700f, "How many monsters to spawn on pillar activation");
		}
	}

	public static ConfigFile ConfigFile;

	public static ConfigEntry<bool> Enabled;

	public static ConfigEntry<int> CurseStacks;

	public static ConfigEntry<bool> HealingNova;

	public static ConfigEntry<float> EarlyGameDivider;

	public static ConfigEntry<float> PostTeleDivider;

	public static ConfigEntry<bool> AutoPing;

	public static PillarConfig[] pillars = new PillarConfig[4];

	public static void DoConfig()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Expected O, but got Unknown
		ConfigFile = new ConfigFile(Paths.ConfigPath + "//PillarRespawn.cfg", true);
		string text = "_Main";
		Enabled = ConfigFile.Bind<bool>(text, "Enable Mod", true, "Enables mod. Toggle in-game with pillarrevivetoggle command");
		CurseStacks = ConfigFile.Bind<int>(text, "Curse Stacks", 25, "Give n stacks of curse to the revived player, set to 0 to disable");
		HealingNova = ConfigFile.Bind<bool>(text, "Use Lepton Daisy", true, "If revive pillars should use Lepton Daisies. Requires game restart");
		EarlyGameDivider = ConfigFile.Bind<float>(text, "Early game pillar boost", 3f, new ConfigDescription("On stage 1 and teleporter has not been hit, spawn this many less monsters and charge pillar faster", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
		PostTeleDivider = ConfigFile.Bind<float>(text, "Tele finished pillar boost", 5f, new ConfigDescription("After teleporter has been fully completed, spawn this many less monsters and charge pillar faster", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
		AutoPing = ConfigFile.Bind<bool>(text, "Auto ping pillars", true, "Have host automatically ping pillars when they spawn. This is so that they can be highlighted for everyone");
		for (int i = 0; i < pillars.Length; i++)
		{
			pillars[i] = new PillarConfig((byte)i);
		}
	}

	[ConCommand(/*Could not decode attribute arguments.*/)]
	private static void PRPillarConfigReload(ConCommandArgs args)
	{
		ConfigFile.Reload();
		Prefab.CreatePrefabs();
	}
}
internal class Prefab
{
	public static readonly string[] pillarNames = new string[4] { "Blood", "Design", "Mass", "Soul" };

	public static WeightedSelection<GameObject> prefabs = new WeightedSelection<GameObject>(8);

	public static void CreatePrefabs()
	{
		prefabs.Clear();
		for (int i = 0; i < pillarNames.Length; i++)
		{
			string text = pillarNames[i];
			GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/MoonBattery" + text), text + "Pillar", false);
			val.AddComponent<PlayerRevive>().pillarIndex = (Pillar)i;
			HoldoutZoneController component = val.GetComponent<HoldoutZoneController>();
			component.applyHealingNova = PRConfig.HealingNova.Value;
			component.baseChargeDuration = PRConfig.pillars[i].chargeDuration.Value;
			CombatDirector component2 = val.GetComponent<CombatDirector>();
			component2.expRewardCoefficient = 0f;
			component2.goldRewardCoefficient = 0f;
			component2.monsterCredit = PRConfig.pillars[i].monsterCredits.Value;
			prefabs.AddChoice(val, PRConfig.pillars[i].weight.Value);
		}
	}
}
internal enum Pillar
{
	Blood,
	Desgin,
	Mass,
	Soul
}
internal class PlayerRevive : MonoBehaviour
{
	public Pillar pillarIndex;

	private NetworkUser networkUser;

	private bool didRespawn;

	public bool setTeleFinished;

	public void SetNetworkUser(NetworkUser networkUser)
	{
		this.networkUser = networkUser;
		PurchaseInteraction component = ((Component)this).GetComponent<PurchaseInteraction>();
		component.NetworkdisplayNameToken = $"{networkUser.userName}'s {Prefab.pillarNames[(int)pillarIndex]}";
		component.NetworkcontextToken = "Reform " + networkUser.userName;
		if (PRConfig.AutoPing.Value)
		{
			((MonoBehaviour)this).Invoke("PingPillar", 3f);
		}
	}

	private void OnEnable()
	{
		if (NetworkServer.active)
		{
			((UnityEvent<HoldoutZoneController>)(object)((Component)this).GetComponent<HoldoutZoneController>().onCharged).AddListener((UnityAction<HoldoutZoneController>)OnCharged);
		}
	}

	private void OnCharged(HoldoutZoneController holdout)
	{
		//IL_001f: 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_0034: Expected O, but got Unknown
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)networkUser) || !Object.op_Implicit((Object)(object)networkUser.master))
		{
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = "<color=red>Player not found</color>"
			});
			return;
		}
		CharacterMaster master = networkUser.master;
		CharacterBody val = master.Respawn(master.deathFootPosition, default(Quaternion));
		for (int i = 0; i < PRConfig.CurseStacks.Value; i++)
		{
			val.AddBuff(Buffs.PermanentCurse);
		}
		didRespawn = true;
		Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
		{
			baseToken = "<style=cLunarObjective>Reformed " + networkUser.userName + "</style>"
		});
		((MonoBehaviour)this).Invoke("DestroySelf", 60f);
	}

	private void FixedUpdate()
	{
		if (!NetworkServer.active)
		{
			return;
		}
		if (Object.op_Implicit((Object)(object)networkUser) && Object.op_Implicit((Object)(object)networkUser.master))
		{
			if (!didRespawn)
			{
				CharacterBody currentBody = networkUser.GetCurrentBody();
				if (currentBody != null && currentBody.healthComponent.alive)
				{
					goto IL_004d;
				}
			}
			if (!setTeleFinished)
			{
				TeleporterInteraction instance = TeleporterInteraction.instance;
				if (((instance != null) ? instance.currentState : null) is ChargedState)
				{
					HoldoutZoneController component = ((Component)this).GetComponent<HoldoutZoneController>();
					component.baseChargeDuration /= PRConfig.PostTeleDivider.Value;
					CombatDirector component2 = ((Component)this).GetComponent<CombatDirector>();
					component2.monsterCredit /= PRConfig.PostTeleDivider.Value;
					setTeleFinished = true;
					log.info("Applied post teleporter boost");
				}
			}
			return;
		}
		goto IL_004d;
		IL_004d:
		log.info("Pillar detected player missing or alive, removing self");
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}

	private void PingPillar()
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		PingInfo val = default(PingInfo);
		val.active = true;
		val.origin = ((Component)this).transform.position;
		val.normal = Vector3.zero;
		val.targetNetworkIdentity = ((Component)this).GetComponent<NetworkIdentity>();
		PingInfo currentPing = val;
		LocalUserManager.GetFirstLocalUser().cachedMasterObject.GetComponent<PingerController>().SetCurrentPing(currentPing);
	}

	private void DestroySelf()
	{
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}
}