using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
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;
using Lamb.UI.FollowerInteractionWheel;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using Shared;
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-Thunderstore")]
[assembly: AssemblyDescription("Rebirth")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+1a04e7525d8bbef28f43e92d0e0b25dc7884ab0c")]
[assembly: AssemblyProduct("Rebirth")]
[assembly: AssemblyTitle("Rebirth")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.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
{
public static class Helper
{
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) <= (float)Plugin.XpPenaltyChance.Value / 100f;
}
}
public class MissionItem : CustomMission
{
public override string InternalName => "REBIRTH_MISSION_1";
public override ITEM_TYPE RewardType => Plugin.RebirthItem;
public override int BaseChance => Plugin.MissionBaseChance.Value;
public override IntRange RewardRange => new IntRange(Plugin.MissionRewardMin.Value, Plugin.MissionRewardMax.Value);
}
[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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
if ((int)Victim.team == 2)
{
if (Random.Range(0, 101) <= Plugin.EnemyDropRate.Value)
{
Plugin.Log.LogInfo((object)("Got a Rebirth token from " + ((Object)__instance).name + "!"));
InventoryItem.Spawn(Plugin.RebirthItem, Random.Range(Plugin.DropMinQuantity.Value, Plugin.DropMaxQuantity.Value + 1), ((Component)__instance).transform.position, 4f, (Action<PickUp>)null);
}
}
else if (((Object)Victim).name.ToLower(CultureInfo.InvariantCulture).Contains("breakable body pile") && Random.Range(0, 101) <= Plugin.EnemyDropRate.Value)
{
Plugin.Log.LogInfo((object)("Got a Rebirth token from " + ((Object)__instance).name + "!"));
InventoryItem.Spawn(Plugin.RebirthItem, Random.Range(Plugin.DropMinQuantity.Value, Plugin.DropMaxQuantity.Value + 1), ((Component)__instance).transform.position, 4f, (Action<PickUp>)null);
}
}
}
[BepInPlugin("p1xel8ted.cotl.rebirth", "Rebirth", "1.1.1")]
[BepInDependency("io.github.xhayper.COTL_API", "0.3.1")]
[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.1.1";
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; }
public static ITEM_TYPE RebirthItem { get; private set; }
private CustomObjective RebirthCollectItemQuest { get; set; }
internal static ConfigEntry<bool> RebirthOldFollowers { get; private set; }
internal static ConfigEntry<int> XpPenaltyChance { get; private set; }
internal static ConfigEntry<int> XpPenaltyMultiplier { get; private set; }
internal static ConfigEntry<int> TokenCost { get; private set; }
internal static ConfigEntry<int> EnemyDropRate { get; private set; }
internal static ConfigEntry<int> DropMinQuantity { get; private set; }
internal static ConfigEntry<int> DropMaxQuantity { get; private set; }
internal static ConfigEntry<int> ChestSpawnChance { get; private set; }
internal static ConfigEntry<int> ChestMinAmount { get; private set; }
internal static ConfigEntry<int> ChestMaxAmount { get; private set; }
internal static ConfigEntry<int> BoneCost { get; private set; }
internal static ConfigEntry<int> RefineryDuration { get; private set; }
internal static ConfigEntry<int> MissionRewardMin { get; private set; }
internal static ConfigEntry<int> MissionRewardMax { get; private set; }
internal static ConfigEntry<int> MissionBaseChance { get; private set; }
private void Awake()
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
((BaseModdedSaveData)RebirthSaveData).LoadOrder = (ModdedSaveLoadOrder)0;
ModdedSaveManager.RegisterModdedSave((BaseModdedSaveData)(object)RebirthSaveData);
Log = ((BaseUnityPlugin)this).Logger;
PluginPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? throw new DirectoryNotFoundException();
BindConfig();
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());
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?";
RegisterSettings();
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "p1xel8ted.cotl.rebirth");
Helpers.PrintModLoaded("Rebirth", ((BaseUnityPlugin)this).Logger);
}
private void BindConfig()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Expected O, but got Unknown
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Expected O, but got Unknown
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Expected O, but got Unknown
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Expected O, but got Unknown
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Expected O, but got Unknown
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Expected O, but got Unknown
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
//IL_0214: Expected O, but got Unknown
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Expected O, but got Unknown
//IL_0277: Unknown result type (might be due to invalid IL or missing references)
//IL_0281: Expected O, but got Unknown
//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
//IL_02b4: Expected O, but got Unknown
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_02e7: Expected O, but got Unknown
RebirthOldFollowers = ((BaseUnityPlugin)this).Config.Bind<bool>("01. Rebirth", "Rebirth Old Followers", false, "Allow old followers to be reborn.");
XpPenaltyChance = ((BaseUnityPlugin)this).Config.Bind<int>("01. Rebirth", "XP Penalty Chance", 20, new ConfigDescription("Chance (%) of losing XP during rebirth.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
XpPenaltyMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("01. Rebirth", "XP Kept On Penalty", 50, new ConfigDescription("Percentage of XP kept when penalty triggers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 90), Array.Empty<object>()));
TokenCost = ((BaseUnityPlugin)this).Config.Bind<int>("01. Rebirth", "Token Cost", 25, new ConfigDescription("Tokens required for subsequent rebirths.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
EnemyDropRate = ((BaseUnityPlugin)this).Config.Bind<int>("02. Token Drops", "Enemy Drop Rate", 5, new ConfigDescription("Chance (%) of tokens dropping from enemies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
DropMinQuantity = ((BaseUnityPlugin)this).Config.Bind<int>("02. Token Drops", "Drop Min Quantity", 1, new ConfigDescription("Minimum tokens per drop.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
DropMaxQuantity = ((BaseUnityPlugin)this).Config.Bind<int>("02. Token Drops", "Drop Max Quantity", 2, new ConfigDescription("Maximum tokens per drop.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
ChestSpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("03. Dungeon Chests", "Chest Spawn Chance", 5, new ConfigDescription("Chance (%) of tokens appearing in dungeon chests.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
ChestMinAmount = ((BaseUnityPlugin)this).Config.Bind<int>("03. Dungeon Chests", "Chest Min Amount", 4, new ConfigDescription("Minimum tokens per chest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
ChestMaxAmount = ((BaseUnityPlugin)this).Config.Bind<int>("03. Dungeon Chests", "Chest Max Amount", 7, new ConfigDescription("Maximum tokens per chest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
BoneCost = ((BaseUnityPlugin)this).Config.Bind<int>("04. Refinery", "Bone Cost", 15, new ConfigDescription("Bones required to refine a token.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
RefineryDuration = ((BaseUnityPlugin)this).Config.Bind<int>("04. Refinery", "Refinery Duration", 256, new ConfigDescription("Refinery duration in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 600), Array.Empty<object>()));
MissionRewardMin = ((BaseUnityPlugin)this).Config.Bind<int>("05. Missions", "Mission Reward Min", 15, new ConfigDescription("Minimum token reward from missions.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
MissionRewardMax = ((BaseUnityPlugin)this).Config.Bind<int>("05. Missions", "Mission Reward Max", 25, new ConfigDescription("Maximum token reward from missions.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
MissionBaseChance = ((BaseUnityPlugin)this).Config.Bind<int>("05. Missions", "Mission Base Chance", 50, new ConfigDescription("Mission appearance chance (%).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
}
private static void RegisterSettings()
{
CustomSettingsManager.AddBepInExConfig("Rebirth", "Rebirth Old Followers", RebirthOldFollowers, (Action<bool>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth", "XP Penalty Chance", XpPenaltyChance, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth", "XP Kept On Penalty", XpPenaltyMultiplier, 5, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth", "Token Cost", TokenCost, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Drops", "Enemy Drop Rate", EnemyDropRate, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Drops", "Drop Min Quantity", DropMinQuantity, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Drops", "Drop Max Quantity", DropMaxQuantity, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Chests", "Chest Spawn Chance", ChestSpawnChance, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Chests", "Chest Min Amount", ChestMinAmount, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Chests", "Chest Max Amount", ChestMaxAmount, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Refinery", "Bone Cost", BoneCost, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Refinery", "Refinery Duration", RefineryDuration, 10, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Missions", "Mission Reward Min", MissionRewardMin, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Missions", "Mission Reward Max", MissionRewardMax, 1, (ValueDisplayFormat)1, (Action<int>)null);
CustomSettingsManager.AddBepInExConfig("Rebirth - Missions", "Mission Base Chance", MissionBaseChance, 1, (ValueDisplayFormat)1, (Action<int>)null);
}
}
internal class RebirthFollowerCommand : CustomFollowerCommand
{
[CompilerGenerated]
private sealed class <DieRoutine>d__18 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Follower follower;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DieRoutine>d__18(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: 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
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
follower.HideAllFollowerIcons();
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
follower.State.CURRENT_STATE = (State)49;
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
follower.SetBodyAnimation("wave", true);
<>2__current = (object)new WaitForSeconds(0.75f);
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
follower.Die((NotificationType)79, true, 1, "die", "dead", (Action<GameObject>)null, true);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <GiveFollowerIE>d__14 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Follower old;
public FollowerInfo f;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GiveFollowerIE>d__14(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: 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_00d9: 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_0114: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = DieRoutine(old);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(3f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
BiomeBaseManager.Instance.SpawnExistingRecruits = false;
<>2__current = (object)new WaitForEndOfFrame();
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(3f);
<>1__state = 4;
return true;
case 4:
{
<>1__state = -1;
DataManager.Instance.Followers_Recruit.Add(f);
FollowerManager.SpawnExistingRecruits(BiomeBaseManager.Instance.RecruitSpawnLocation.transform.position);
FollowerRecruit obj = Object.FindObjectOfType<FollowerRecruit>();
if (obj != null)
{
obj.ManualTriggerAnimateIn();
}
BiomeBaseManager.Instance.SpawnExistingRecruits = true;
NotificationCentre.NotificationsEnabled = true;
<>2__current = (object)new WaitForSeconds(2f);
<>1__state = 5;
return true;
}
case 5:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <ShowMessages>d__16 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public string name;
public bool halfXp;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ShowMessages>d__16(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(3f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
NotificationCentreScreen.Play(name + " died to be reborn! All hail " + name + "!");
<>2__current = (object)new WaitForSeconds(5f);
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
if (!halfXp)
{
return false;
}
NotificationCentre.Instance.PlayGenericNotification("Oh no! " + name + " lost half of their XP during Rebirth!", (Flair)0);
<>2__current = (object)new WaitForSeconds(3f);
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
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!";
}
if (Helper.IsOld(follower))
{
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;
}
if (Helper.IsOld(follower))
{
return false;
}
BornAgainFollower = SaveData.FollowerBornAgain(follower.Brain._directInfoAccess);
return !BornAgainFollower;
}
public override bool ShouldAppearFor(Follower follower)
{
return !SaveData.FollowerBornAgain(follower.Brain._directInfoAccess);
}
[IteratorStateMachine(typeof(<GiveFollowerIE>d__14))]
private static IEnumerator GiveFollowerIE(FollowerInfo f, Follower old)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <GiveFollowerIE>d__14(0)
{
f = f,
old = old
};
}
internal static void SpawnRecruit(Follower follower)
{
BiomeBaseManager.Instance.SpawnExistingRecruits = true;
NotificationCentre.NotificationsEnabled = false;
string name = follower.Brain.Info.Name;
int iD = follower.Brain.Info.ID;
int xPLevel = follower.Brain.Info.XPLevel;
int num = Mathf.CeilToInt((float)(xPLevel * Plugin.XpPenaltyMultiplier.Value) / 100f);
bool flag = Helper.DoHalfStats();
FollowerInfo val = FollowerInfo.NewCharacter((FollowerLocation)1, "");
if (val != null)
{
((MonoBehaviour)GameManager.GetInstance()).StartCoroutine(GiveFollowerIE(val, follower));
Plugin.Log.LogInfo((object)("New follower: " + val.Name));
SaveData.AddBornAgainFollower(val);
val.XPLevel = (flag ? num : xPLevel);
}
else
{
Plugin.Log.LogWarning((object)"New follower is null!");
NotificationCentre.NotificationsEnabled = true;
}
((MonoBehaviour)GameManager.GetInstance()).StartCoroutine(ShowMessages(name, flag));
RemoveFromDeadLists(iD);
}
[IteratorStateMachine(typeof(<ShowMessages>d__16))]
private static IEnumerator ShowMessages(string name, bool halfXp)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ShowMessages>d__16(0)
{
name = name,
halfXp = halfXp
};
}
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);
}
[IteratorStateMachine(typeof(<DieRoutine>d__18))]
private static IEnumerator DieRoutine(Follower follower)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DieRoutine>d__18(0)
{
follower = follower
};
}
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)
{
interaction.Close(true, true, false);
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 => Plugin.ChestSpawnChance.Value;
public override int DungeonChestMinAmount => Plugin.ChestMinAmount.Value;
public override int DungeonChestMaxAmount => Plugin.ChestMaxAmount.Value;
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 => Plugin.BoneCost.Value;
public override float CustomRefineryDuration => Plugin.RefineryDuration.Value;
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 static int ItemQty => Plugin.TokenCost.Value;
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 {ItemQty} 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!";
}
if (Helper.IsOld(follower))
{
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_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected I4, but got Unknown
if (DataManager.Instance.Followers_Recruit.Count > 0)
{
return false;
}
if (Helper.IsOld(follower))
{
return false;
}
return Inventory.GetItemQuantity((int)Plugin.RebirthItem) >= ItemQty;
}
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_001a: Unknown result type (might be due to invalid IL or missing references)
if ((int)finalCommand == 40)
{
interaction.Close(true, true, false);
RebirthFollowerCommand.SpawnRecruit(interaction.follower);
Inventory.ChangeItemQuantity(Plugin.RebirthItem, -ItemQty, 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));
}
}
}
namespace Shared
{
public static class Helpers
{
private static class StorefrontDetector
{
private static readonly string[] PiracyFiles = new string[42]
{
"SmartSteamEmu.ini", "codex.ini", "steam_emu.ini", "goldberg_emulator.dll", "3dmgame.dll", "ALI213.dll", "crack", "crack.exe", "steam_api64_o.dll", "steamclient_loader.dll",
"CODEX", "Goldberg", "REVOLT", "SKIDROW", "PROPHET", "CPY", "PLAZA", "FLT", "FLT.dll", "HOODLUM",
"EMPRESS", "VALVEEMPRESS", "DARKSiDERS", "RAZOR1911", "TENOKE", "DOGE", "BAT", "P2P", "nosTEAM", "FCKDRM",
"unarc.dll", "uninstall.exe", "setup.exe", "INSTALLER", "steam_api64.cdx.dll", "Launcher.exe", "Redist", "RLD!", "fix.exe", "crackfix",
"ReadMe.txt", "README.nfo"
};
public static string DetectStorefront()
{
string dir = Directory.GetCurrentDirectory();
string text = "Unknown";
if (File.Exists(Path.Combine(dir, "steam_api.dll")) || File.Exists(Path.Combine(dir, "steam_api64.dll")) || File.Exists(Path.Combine(dir, "steam_appid.txt")) || Directory.Exists(Path.Combine(dir, "steam_settings")))
{
text = "Steam";
}
else if (Directory.GetFiles(dir, "goggame-*.info").Any() || File.Exists(Path.Combine(dir, "galaxy.dll")))
{
text = "GOG";
}
else if (File.Exists(Path.Combine(dir, "EOSSDK-Win64-Shipping.dll")) || File.Exists(Path.Combine(dir, "EpicOnlineServices.dll")) || Directory.Exists(Path.Combine(dir, ".egstore")))
{
text = "Epic";
}
else if (IsProcessRunning("steam"))
{
text = "Steam (process only)";
}
else if (IsProcessRunning("GalaxyClient"))
{
text = "GOG (process only)";
}
else if (IsProcessRunning("EpicGamesLauncher"))
{
text = "Epic (process only)";
}
if (PiracyFiles.Any((string pirate) => File.Exists(Path.Combine(dir, pirate)) || Directory.Exists(Path.Combine(dir, pirate))))
{
text += " + Possible Pirated/Cracked Files Found!";
}
return text;
}
private static bool IsProcessRunning(string name)
{
return Process.GetProcessesByName(name).Length != 0;
}
}
[CompilerGenerated]
private sealed class <FilterEnumerator>d__17 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public IEnumerator original;
public Type[] typesToRemove;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <FilterEnumerator>d__17(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
break;
}
while (original.MoveNext())
{
object current = original.Current;
if (current != null && !ArrayExtensions.Contains<Type>(typesToRemove, current.GetType()))
{
<>2__current = current;
<>1__state = 1;
return true;
}
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
internal static List<Follower> AllFollowers => FollowerManager.Followers.SelectMany((KeyValuePair<FollowerLocation, List<Follower>> followerList) => followerList.Value).ToList();
public static void PrintModLoaded(string plugin, ManualLogSource logger)
{
//IL_002a: 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_0089: Unknown result type (might be due to invalid IL or missing references)
string text = Application.version.Replace("\r", "").Replace("\n", "");
string buildGUID = Application.buildGUID;
Platform current = PlatformHelper.Current;
string text2 = StorefrontDetector.DetectStorefront();
logger.LogInfo((object)"==========================================");
logger.LogInfo((object)(" Plugin Loaded: " + plugin));
logger.LogInfo((object)(" Version : " + text + " (BuildGUID: " + buildGUID + ")"));
logger.LogInfo((object)$" Platform : {current}");
logger.LogInfo((object)(" Storefront: " + text2));
logger.LogInfo((object)"==========================================");
}
private static FollowerTask_ClearRubble GetRubbleTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_Rubble item in StructureManager.GetAllStructuresOfType<Structures_Rubble>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_ClearRubble)(object)((obj is FollowerTask_ClearRubble) ? obj : null);
}
private static FollowerTask_Janitor GetJanitorTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_JanitorStation item in StructureManager.GetAllStructuresOfType<Structures_JanitorStation>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Janitor)(object)((obj is FollowerTask_Janitor) ? obj : null);
}
private static FollowerTask_Refinery GetRefineryTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_Refinery item in StructureManager.GetAllStructuresOfType<Structures_Refinery>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Refinery)(object)((obj is FollowerTask_Refinery) ? obj : null);
}
private static FollowerTask_Undertaker GetMorgueTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_Morgue item in StructureManager.GetAllStructuresOfType<Structures_Morgue>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Undertaker)(object)((obj is FollowerTask_Undertaker) ? obj : null);
}
private static void StartTask(FollowerBrain brain, FollowerTask task)
{
brain.CompleteCurrentTask();
brain.HardSwapToTask(task);
}
private static void StartTaskFromCommand(FollowerBrain brain, FollowerCommands command)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Expected I4, but got Unknown
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Expected O, but got Unknown
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
switch ((int)command)
{
case 14:
StartTask(brain, (FollowerTask)new FollowerTask_ChopTrees());
break;
case 17:
StartTask(brain, (FollowerTask)(object)GetRubbleTask());
break;
case 27:
StartTask(brain, (FollowerTask)(object)GetPrayTask());
break;
case 47:
StartTask(brain, (FollowerTask)(object)GetFarmTask());
break;
case 28:
StartTask(brain, (FollowerTask)(object)GetBuildTask());
break;
case 30:
StartTask(brain, (FollowerTask)(object)GetKitchenTask());
break;
case 58:
StartTask(brain, (FollowerTask)(object)GetJanitorTask());
break;
case 64:
StartTask(brain, (FollowerTask)(object)GetRefineryTask());
break;
case 81:
StartTask(brain, (FollowerTask)(object)GetMorgueTask());
break;
case 88:
StartTask(brain, (FollowerTask)(object)GetBrewTask());
break;
default:
StartTask(brain, GetRandomTask(brain));
throw new ArgumentOutOfRangeException("command", command, null);
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 15:
case 16:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 29:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57:
case 59:
case 60:
case 61:
case 62:
case 63:
case 65:
case 66:
case 67:
case 68:
case 69:
case 70:
case 71:
case 72:
case 73:
case 74:
case 75:
case 76:
case 77:
case 78:
case 79:
case 80:
case 82:
case 83:
case 84:
case 85:
case 86:
case 87:
case 89:
case 90:
case 91:
case 92:
case 93:
case 94:
case 95:
case 96:
case 97:
case 98:
case 99:
case 100:
case 101:
case 102:
case 103:
case 104:
break;
}
}
private static FollowerTask_Cook GetKitchenTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_Kitchen item in StructureManager.GetAllStructuresOfType<Structures_Kitchen>())
{
((Structures_CookingFire)item).GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Cook)(object)((obj is FollowerTask_Cook) ? obj : null);
}
private static FollowerTask GetRandomTask(FollowerBrain brain)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return FollowerBrain.GetDesiredTask_Work(brain.Location).FirstOrDefault();
}
private static FollowerTask_Brew GetBrewTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_Pub item in StructureManager.GetAllStructuresOfType<Structures_Pub>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Brew)(object)((obj is FollowerTask_Brew) ? obj : null);
}
private static FollowerTask_Farm GetFarmTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_FarmerStation item in StructureManager.GetAllStructuresOfType<Structures_FarmerStation>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Farm)(object)((obj is FollowerTask_Farm) ? obj : null);
}
public static bool IsMultiplierActive(float value)
{
return !Mathf.Approximately(value, 1f);
}
private static FollowerTask_Pray GetPrayTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_Shrine item in StructureManager.GetAllStructuresOfType<Structures_Shrine>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Pray)(object)((obj is FollowerTask_Pray) ? obj : null);
}
private static FollowerTask_Build GetBuildTask()
{
SortedList<float, FollowerTask> sortedList = new SortedList<float, FollowerTask>();
foreach (Structures_BuildSite item in StructureManager.GetAllStructuresOfType<Structures_BuildSite>())
{
item.GetAvailableTasks((ScheduledActivity)0, sortedList);
}
FollowerTask? obj = sortedList.Values.FirstOrDefault();
return (FollowerTask_Build)(object)((obj is FollowerTask_Build) ? obj : null);
}
[IteratorStateMachine(typeof(<FilterEnumerator>d__17))]
public static IEnumerator FilterEnumerator(IEnumerator original, Type[] typesToRemove)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <FilterEnumerator>d__17(0)
{
original = original,
typesToRemove = typesToRemove
};
}
}
}