Decompiled source of Rebirth v1.0.8

plugins/rebirth/Rebirth.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
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 COTL_API.CustomFollowerCommand;
using COTL_API.CustomInventory;
using COTL_API.CustomMission;
using COTL_API.CustomObjectives;
using COTL_API.CustomSettings;
using COTL_API.Helpers;
using COTL_API.Saves;
using HarmonyLib;
using Lamb.UI.FollowerInteractionWheel;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("p1xel8ted")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Rebirth")]
[assembly: AssemblyFileVersion("1.0.8")]
[assembly: AssemblyInformationalVersion("1.0.8+ec0b3ff72e33c5c941682f5ba9b3d679c868111f")]
[assembly: AssemblyProduct("Rebirth")]
[assembly: AssemblyTitle("Rebirth")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.8.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 Rebirth
{
	[HarmonyPatch]
	public static class Helper
	{
		public static bool TooOld { get; set; }

		public static bool IsOld(Follower follower)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			if (Plugin.RebirthOldFollowers.Value)
			{
				return false;
			}
			if ((int)follower.Outfit.CurrentOutfit == 7)
			{
				if (!follower.Brain.Info.OldAge)
				{
					return follower.Brain.HasThought((Thought)146);
				}
				return true;
			}
			return false;
		}

		public static bool DoHalfStats()
		{
			return Random.Range(0f, 1f) <= 0.2f;
		}
	}
	public class MissionItem : CustomMission
	{
		public override string InternalName => "REBIRTH_MISSION_1";

		public override ITEM_TYPE RewardType => Plugin.RebirthItem;

		public override int BaseChance => 50;

		public override IntRange RewardRange => new IntRange(15, 25);
	}
	[HarmonyPatch]
	[HarmonyWrapSafe]
	public static class Patches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(DropLootOnDeath), "OnDie")]
		public static void DropLootOnDeath_OnDie(DropLootOnDeath __instance, Health Victim)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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)
			if ((int)Victim.team == 2 && CustomItemManager.DropLoot((CustomInventoryItem)(object)Plugin.RebirthItemInstance, 0.05f))
			{
				Plugin.Log.LogInfo((object)("Got a Rebirth token from " + ((Object)__instance).name + "!"));
				InventoryItem.Spawn(Plugin.RebirthItem, Random.Range(1, 3), ((Component)__instance).transform.position, 4f, (Action<PickUp>)null);
			}
			if (((Object)Victim).name.ToLower(CultureInfo.InvariantCulture).Contains("breakable body pile") && CustomItemManager.DropLoot((CustomInventoryItem)(object)Plugin.RebirthItemInstance, 0.05f))
			{
				Plugin.Log.LogInfo((object)("Got a Rebirth token from " + ((Object)__instance).name + "!"));
				InventoryItem.Spawn(Plugin.RebirthItem, Random.Range(1, 3), ((Component)__instance).transform.position, 4f, (Action<PickUp>)null);
			}
		}
	}
	[BepInPlugin("p1xel8ted.cotl.rebirth", "Rebirth", "1.0.8")]
	[BepInDependency("io.github.xhayper.COTL_API", "0.2.5")]
	[BepInDependency("com.bepis.bepinex.configurationmanager", "18.3")]
	[HarmonyPatch]
	public class Plugin : BaseUnityPlugin
	{
		private const string PluginGuid = "p1xel8ted.cotl.rebirth";

		private const string PluginName = "Rebirth";

		private const string PluginVer = "1.0.8";

		public static readonly ModdedSaveData<List<int>> RebirthSaveData = new ModdedSaveData<List<int>>("p1xel8ted.cotl.rebirth");

		public static ManualLogSource Log { get; private set; }

		public static string PluginPath { get; private set; }

		internal static ConfigEntry<bool> RebirthOldFollowers { get; private set; }

		public static ITEM_TYPE RebirthItem { get; private set; }

		private CustomObjective RebirthCollectItemQuest { get; set; }

		internal static RebirthItem RebirthItemInstance { get; private set; }

		private void Awake()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			((BaseModdedSaveData)RebirthSaveData).LoadOrder = (ModdedSaveLoadOrder)0;
			ModdedSaveManager.RegisterModdedSave((BaseModdedSaveData)(object)RebirthSaveData);
			RebirthOldFollowers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Rebirth Old Followers", false, "Allow old followers to be reborn.");
			Log = ((BaseUnityPlugin)this).Logger;
			PluginPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? throw new DirectoryNotFoundException();
			CustomFollowerCommandManager.Add((CustomFollowerCommand)(object)new RebirthFollowerCommand());
			CustomFollowerCommandManager.Add((CustomFollowerCommand)(object)new RebirthSubCommand());
			RebirthItem = CustomItemManager.Add((CustomInventoryItem)(object)new RebirthItem());
			CustomMissionManager.Add((CustomMission)(object)new MissionItem());
			RebirthItemInstance = new RebirthItem();
			RebirthCollectItemQuest = CustomObjectiveManager.CollectItem(RebirthItem, Random.Range(15, 26), false, (FollowerLocation)7, 4800f);
			RebirthCollectItemQuest.InitialQuestText = "Please leader, please! I'm " + StringExtensions.Wave("weary of this existence") + " and seek to be reborn! I will do anything for you! Can you please help me?";
			CustomSettingsManager.AddBepInExConfig("Rebirth", "Rebirth Old Followers", RebirthOldFollowers, (Action<bool>)delegate(bool b)
			{
				Log.LogInfo((object)("Setting 'Rebirth Old Followers' to " + b));
			});
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "p1xel8ted.cotl.rebirth");
			Log.LogInfo((object)"Loaded Rebirth!");
		}
	}
	internal class RebirthFollowerCommand : CustomFollowerCommand
	{
		public override string InternalName => "REBIRTH_COMMAND";

		public override Sprite CommandIcon => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "assets", "rebirth_command.png"));

		private static bool BornAgainFollower { get; set; }

		public override string GetTitle(Follower follower)
		{
			return "Rebirth";
		}

		public RebirthFollowerCommand()
		{
			((CommandItem)this).SubCommands = FollowerCommandGroups.AreYouSureCommands();
		}

		public override string GetDescription(Follower follower)
		{
			return "This follower getting you down? Order a rebirth!";
		}

		public override string GetLockedDescription(Follower follower)
		{
			if (DataManager.Instance.Followers_Recruit.Count > 0)
			{
				return "You already have a follower awaiting indoctrination!";
			}
			Helper.TooOld = Helper.IsOld(follower);
			if (Helper.TooOld)
			{
				return "Not enough life essence left to satisfy those below.";
			}
			return "Yeah, you shouldn't be seeing this...";
		}

		public override bool IsAvailable(Follower follower)
		{
			if (DataManager.Instance.Followers_Recruit.Count > 0)
			{
				return false;
			}
			Helper.TooOld = Helper.IsOld(follower);
			if (Helper.TooOld)
			{
				return false;
			}
			BornAgainFollower = SaveData.FollowerBornAgain(follower.Brain._directInfoAccess);
			return !BornAgainFollower;
		}

		public override bool ShouldAppearFor(Follower follower)
		{
			bool flag = SaveData.FollowerBornAgain(follower.Brain._directInfoAccess);
			return !flag;
		}

		private static IEnumerator GiveFollowerIE(FollowerInfo f, Follower old)
		{
			yield return DieRoutine(old);
			yield return (object)new WaitForSeconds(3f);
			BiomeBaseManager.Instance.SpawnExistingRecruits = false;
			yield return (object)new WaitForEndOfFrame();
			yield return (object)new WaitForSeconds(3f);
			DataManager.Instance.Followers_Recruit.Add(f);
			FollowerManager.SpawnExistingRecruits(BiomeBaseManager.Instance.RecruitSpawnLocation.transform.position);
			Object.FindObjectOfType<FollowerRecruit>().ManualTriggerAnimateIn();
			BiomeBaseManager.Instance.SpawnExistingRecruits = true;
			yield return (object)new WaitForSeconds(2f);
		}

		internal static void SpawnRecruit(Follower follower)
		{
			BiomeBaseManager.Instance.SpawnExistingRecruits = true;
			NotificationCentre.NotificationsEnabled = false;
			string name = ((Object)follower).name;
			int iD = follower.Brain.Info.ID;
			int xPLevel = follower.Brain.Info.XPLevel;
			int xPLevel2 = Mathf.CeilToInt((float)xPLevel / 2f);
			bool flag = Helper.DoHalfStats();
			FollowerInfo val = FollowerInfo.NewCharacter((FollowerLocation)1, "");
			if (val != null)
			{
				((MonoBehaviour)GameManager.GetInstance()).StartCoroutine(GiveFollowerIE(val, follower));
				Plugin.Log.LogWarning((object)("New follower: " + val.Name));
				SaveData.AddBornAgainFollower(val);
				val.XPLevel = xPLevel;
				if (flag)
				{
					if (val.XPLevel >= 2)
					{
						val.XPLevel--;
					}
					val.XPLevel = xPLevel2;
				}
			}
			else
			{
				Plugin.Log.LogWarning((object)"New follower is null!");
			}
			NotificationCentre.NotificationsEnabled = true;
			((MonoBehaviour)GameManager.GetInstance()).StartCoroutine(ShowMessages(name, flag));
			RemoveFromDeadLists(iD);
		}

		private static IEnumerator ShowMessages(string name, bool halfXp)
		{
			yield return (object)new WaitForSeconds(3f);
			NotificationCentreScreen.Play(name + " died to be reborn! All hail " + name + "!");
			yield return (object)new WaitForSeconds(5f);
			if (halfXp)
			{
				NotificationCentre.Instance.PlayGenericNotification("Oh no! " + name + " lost half of their XP during Rebirth!", (Flair)0);
				yield return (object)new WaitForSeconds(3f);
			}
		}

		private static void RemoveFromDeadLists(int id)
		{
			Follower.Followers.RemoveAll((Follower a) => a.Brain._directInfoAccess.ID == id);
			DataManager.Instance.Followers_Dead.RemoveAll((FollowerInfo a) => a.ID == id);
			DataManager.Instance.Followers_Dead_IDs.RemoveAll((int a) => a == id);
		}

		private static IEnumerator DieRoutine(Follower follower)
		{
			follower.HideAllFollowerIcons();
			yield return (object)new WaitForSeconds(0.5f);
			follower.State.CURRENT_STATE = (State)49;
			yield return (object)new WaitForSeconds(1f);
			follower.SetBodyAnimation("wave", true);
			yield return (object)new WaitForSeconds(0.75f);
			follower.Die((NotificationType)79, true, 1, "die", "dead", (Action<GameObject>)null, true);
		}

		public override void Execute(interaction_FollowerInteraction interaction, FollowerCommands finalCommand)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)finalCommand == 40)
			{
				SpawnRecruit(interaction.follower);
			}
		}
	}
	public sealed class RebirthItem : CustomInventoryItem
	{
		public override Sprite InventoryIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "assets", "rebirth_item.png"));


		public override Sprite Sprite { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "assets", "rebirth_item.png"));


		public override string InternalName => "REBIRTH_ITEM";

		public override bool AddItemToDungeonChests => true;

		public override int DungeonChestSpawnChance => 5;

		public override int DungeonChestMinAmount => 4;

		public override int DungeonChestMaxAmount => 7;

		public override Vector3 LocalScale { get; } = new Vector3(0.5f, 0.5f, 0.5f);


		public override ITEM_TYPE ItemPickUpToImitate => (ITEM_TYPE)20;

		public override ItemRarity Rarity => (ItemRarity)1;

		public override bool AddItemToOfferingShrine => true;

		public override bool CanBeRefined => true;

		public override ITEM_TYPE RefineryInput => (ITEM_TYPE)9;

		public override int RefineryInputQty => 15;

		public override float CustomRefineryDuration => 256f;

		public override ITEM_CATEGORIES ItemCategory => (ITEM_CATEGORIES)8;

		public override bool IsCurrency => true;

		public override string LocalizedDescription()
		{
			return "A special token obtained while on crusades that are used as currency to Rebirth followers.";
		}

		public override string LocalizedName()
		{
			return "Rebirth Token";
		}

		public override string LocalizedLore()
		{
			return "Said to be dropped by Death herself.";
		}
	}
	internal class RebirthSubCommand : CustomFollowerCommand
	{
		private const int ItemQty = 25;

		public override string InternalName => "REBIRTH_SUB_COMMAND";

		public override Sprite CommandIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "assets", "rebirth_command.png"));


		public override string GetTitle(Follower follower)
		{
			return $"Rebirth for {25} tokens.";
		}

		public RebirthSubCommand()
		{
			((CommandItem)this).SubCommands = FollowerCommandGroups.AreYouSureCommands();
		}

		public override string GetDescription(Follower follower)
		{
			return "Perform a Rebirth using special tokens obtained while on crusades.";
		}

		public override string GetLockedDescription(Follower follower)
		{
			if (DataManager.Instance.Followers_Recruit.Count > 0)
			{
				return "You already have a follower awaiting indoctrination!";
			}
			Helper.TooOld = Helper.IsOld(follower);
			if (Helper.TooOld)
			{
				return "Not enough life essence left to satisfy those below.";
			}
			return "Requires 25 Rebirth tokens to perform.";
		}

		public override bool ShouldAppearFor(Follower follower)
		{
			return SaveData.FollowerBornAgain(follower.Brain._directInfoAccess);
		}

		public override bool IsAvailable(Follower follower)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected I4, but got Unknown
			if (DataManager.Instance.Followers_Recruit.Count > 0)
			{
				return false;
			}
			Helper.TooOld = Helper.IsOld(follower);
			if (Helper.TooOld)
			{
				return false;
			}
			return Inventory.GetItemQuantity((int)Plugin.RebirthItem) >= 25;
		}

		public override void Execute(interaction_FollowerInteraction interaction, FollowerCommands finalCommand)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if ((int)finalCommand == 40)
			{
				RebirthFollowerCommand.SpawnRecruit(interaction.follower);
				Inventory.ChangeItemQuantity(Plugin.RebirthItem, -25, 0);
			}
		}
	}
	public static class SaveData
	{
		public static bool FollowerBornAgain(FollowerInfo followerInfo)
		{
			if (Plugin.RebirthSaveData.Data != null)
			{
				return Plugin.RebirthSaveData.Data.Exists((int a) => a == followerInfo.ID);
			}
			return false;
		}

		public static void AddBornAgainFollower(FollowerInfo followerInfo)
		{
			Plugin.RebirthSaveData.Data?.Add(followerInfo.ID);
			((BaseModdedSaveData)Plugin.RebirthSaveData).Save(true, true);
			Plugin.Log.LogInfo((object)("Saved follower data for " + followerInfo.Name));
		}
	}
}