using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using GrubAdoption.Assets;
using GrubAdoption.Rescuing;
using GrubAdoption.Stats;
using GrubAdoption.Utils;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.anonymousfroggo.grubadoption")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.5.0")]
[assembly: AssemblyInformationalVersion("0.2.5+5a0d0a84338f35dc2b896cf1bf4a589f73c05110")]
[assembly: AssemblyProduct("Grub Adoption")]
[assembly: AssemblyTitle("com.anonymousfroggo.grubadoption")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 GrubAdoption
{
[BepInPlugin("com.anonymousfroggo.grubadoption", "Grub Adoption", "0.2.5")]
public class Plugin : BaseUnityPlugin
{
private string assemblyPath;
private bool initialized;
public static Plugin Instance { get; private set; }
private void Awake()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
new Harmony("com.anonymousfroggo.grubadoption").PatchAll();
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
switch (((Scene)(ref scene)).name)
{
case "Intro":
Initialize();
break;
case "Game-Main":
case "Playground":
OnGameLoaded(scene);
break;
}
}
private async void Initialize()
{
if (!initialized)
{
Log.Initialize(((BaseUnityPlugin)this).Logger);
assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
await GrubAdoptionAssets.Initialize(assemblyPath);
initialized = true;
}
}
private void OnGameLoaded(Scene scene)
{
}
public static GameObject FindGameManagerGameObject(Scene scene)
{
GameObject val = (from gameObject in ((Scene)(ref scene)).GetRootGameObjects()
where ((Object)gameObject).name == "GameManager"
select gameObject).FirstOrDefault();
if ((Object)(object)val == (Object)null)
{
Log.Error("Finding GameManager failed");
return null;
}
return val;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.anonymousfroggo.grubadoption";
public const string PLUGIN_NAME = "Grub Adoption";
public const string PLUGIN_VERSION = "0.2.5";
}
}
namespace GrubAdoption.Utils
{
public static class AssetUtils
{
public const string BASE_DATABASE = "basedatabase";
public static GameObject GetAsset(string name)
{
return CL_AssetManager.GetAssetGameObject(name, "basedatabase");
}
public static Item GetItem(string itemName)
{
return GetAsset(itemName).GetComponent<Item_Object>().itemData;
}
}
public class DebugHelper : MonoBehaviour
{
public static void Initialize(Scene scene)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = Plugin.FindGameManagerGameObject(scene);
if (obj != null)
{
obj.AddComponent<DebugHelper>();
}
}
private void Start()
{
CommandConsole.AddCommand("grubsstored", (Action<string[]>)GrubsStoredCommand, true);
CommandConsole.AddCommand("liststats", (Action<string[]>)ListStatsCommand, true);
CommandConsole.AddCommand("win", (Action<string[]>)WinCommand, true);
}
private static void GrubsStoredCommand(string[] args)
{
CommandConsole.Log(GrubRescueStation.GetGrubsStored().ToString());
}
private static void ListStatsCommand(string[] args)
{
StatUtils.StatSource result;
if (args.Length == 0)
{
PrintStatsList(StatUtils.StatSource.global);
PrintStatsList(StatUtils.StatSource.gamemode);
PrintStatsList(StatUtils.StatSource.session);
}
else if (!Enum.TryParse<StatUtils.StatSource>(args[0], ignoreCase: true, out result))
{
CommandConsole.LogError("Not a valid stat source: " + args[0]);
}
else
{
PrintStatsList(result);
}
static void PrintStatsList(StatUtils.StatSource source)
{
List<Statistic> list = new List<Statistic>(StatUtils.GetStats(source).statistics);
list.Sort((Statistic x, Statistic y) => x.id.CompareTo(y.id));
foreach (Statistic item in list)
{
_ = item;
}
}
}
private static void WinCommand(string[] args)
{
CL_GameManager.gMan.Win();
}
}
public static class InventoryUtils
{
public static int TotalItemCount(string itemName)
{
return BagItemCount(itemName) + HandItemCount(itemName);
}
public static int BagItemCount(string itemName)
{
return ENT_Player.GetInventory().bagItems.Count((Item bagItem) => bagItem.itemName.Equals(itemName));
}
public static int HandItemCount(string itemName)
{
return ENT_Player.GetInventory().itemHands.Count((ItemHand itemHand) => itemHand.currentItem != null && itemHand.currentItem.itemName.Equals(itemName));
}
public static void LoadItemIntoBag(Item item)
{
//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_0027: 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)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: 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_004d: Unknown result type (might be due to invalid IL or missing references)
Item clone = item.GetClone((Item)null);
clone.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f;
clone.bagRotation = Quaternion.LookRotation(clone.upDirection);
Inventory.instance.AddItemToInventoryScreen(clone.bagPosition, clone, true, true, true);
clone.inventory = Inventory.instance;
}
}
public static class Log
{
private static ManualLogSource log;
internal static void Initialize(ManualLogSource log)
{
Log.log = log;
}
public static void Info(object msg)
{
ManualLogSource obj = log;
if (obj != null)
{
obj.LogInfo(msg);
}
}
public static void Warn(object msg)
{
ManualLogSource obj = log;
if (obj != null)
{
obj.LogWarning(msg);
}
}
public static void Error(object msg)
{
ManualLogSource obj = log;
if (obj != null)
{
obj.LogError(msg);
}
}
public static void Debug(object msg)
{
ManualLogSource obj = log;
if (obj != null)
{
obj.LogDebug(msg);
}
}
}
public static class Names
{
public static class Denizens
{
public const string GRUB = "Denizen_SlugGrub";
}
public static class Gamemodes
{
public const string CAMPAIGN = "GM_Campaign";
public const string PLAYGROUND = "GM_Playground";
}
public static class Items
{
public const string GRUB = "SlugGrub";
}
public static class Scenes
{
public const string INTRO = "Intro";
public const string MAIN_MENU = "Main-Menu";
public const string GAME_MAIN = "Game-Main";
public const string PLAYGROUND = "Playground";
}
public static class Stats
{
}
public static class Ui
{
public const string SCORE_PANEL_STANDARD_PREFIX = "ScorePanel_Standard";
public const string SCORE_SCREEN_SESSION_STAT_PREFIX = "stat:";
public const string SCORE_SCREEN_GAMEMODE_STAT_PREFIX = "stat:";
public const string GAMEMODE_STAT_PREFIX = "stat-";
public const string LOGBOOK_STAT_PREFIX = "stat-";
}
public const string GAME_MANAGER = "GameManager";
public static string Instantiated(string name)
{
return name + "(Clone)";
}
}
public static class Paths
{
}
public static class StatUtils
{
public enum StatSource
{
session,
gamemode,
global
}
public const string STAT_PICKUP_ITEM_PREFIX = "pickup-item-";
public const string STAT_ITEMS_USED = "items-used";
public const string DEFAULT_TEXT_REDACTED = "[REDACTED]";
public static string GetText(CustomStat stat, StatSource statSource)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected I4, but got Unknown
//IL_0061: 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)
GameStats val = (GameStats)((int)statSource switch
{
2 => StatManager.sessionStats,
0 => StatManager.saveData.GetGameMode(CL_GameManager.GetGamemodeName(true, false)).stats,
3 => StatManager.saveData.gameStats,
_ => null,
});
if (!val.HasStatistic(stat.GetId()))
{
return stat.GetDefaultText(statSource);
}
return stat.GetTextPrefix(statSource) + val.GetStatistic(stat.GetId()).GetString();
}
public static bool HasStat(string id)
{
if (!StatManager.saveData.gameStats.HasStatistic(id))
{
return StatManager.sessionStats.HasStatistic(id);
}
return true;
}
public static bool HasPickedUpItem(string itemName)
{
return HasStat("pickup-item-" + itemName);
}
public static object GetValueOrDefault(string id, object defaultValue, StatSource source)
{
Statistic stat = GetStat(id, source);
return ((stat != null) ? stat.GetValue() : null) ?? defaultValue;
}
public static Statistic GetStat(string id, StatSource source)
{
GameStats stats = GetStats(source);
if (stats == null)
{
return null;
}
return stats.GetStatistic(id);
}
public static GameStats GetStats(StatSource source)
{
return (GameStats)(source switch
{
StatSource.session => StatManager.sessionStats,
StatSource.gamemode => StatManager.saveData.GetGameMode(CL_GameManager.GetGamemodeName(true, false))?.stats,
StatSource.global => StatManager.saveData.gameStats,
_ => null,
});
}
}
public static class UiUtils
{
public static void Destroy(Transform child)
{
Object.Destroy((Object)(object)((Component)child).gameObject);
}
public static void DestroyChild(string childName, Transform parent)
{
Transform val = parent.Find(childName);
if ((Object)(object)val == (Object)null)
{
Log.Error("Child " + childName + " of " + ((Object)parent).name + " not found");
}
else
{
Destroy(val);
}
}
}
}
namespace GrubAdoption.Stats
{
public abstract class CustomStat(string id, object initialValue, DataType dataType, ModType modType, DisplayType displayType, ModType globalModType)
{
private readonly string id = id;
protected object value = initialValue;
private readonly DataType type = dataType;
private readonly ModType modType = modType;
private readonly DisplayType displayType = displayType;
private readonly ModType globalModType = globalModType;
public void EndGameStatUpdate(bool win)
{
if (CalculateValueOnEndGame(win))
{
WriteToSessionStats();
}
}
protected virtual bool CalculateValueOnEndGame(bool win)
{
return false;
}
private void WriteToSessionStats()
{
//IL_0012: 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_001e: 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)
StatManager.sessionStats.UpdateStatistic(id, initialValue, dataType, modType, displayType, globalModType);
}
public string GetId()
{
return id;
}
public abstract string GetDefaultText(StatSource statSource);
public abstract string GetTextPrefix(StatSource statSource);
public abstract bool ShouldAddToScoreScreenSession(bool win);
public abstract bool ShouldAddToScoreScreenGamemode(bool win);
public abstract bool ShouldAddToGamemode(M_Gamemode gamemode);
public abstract bool ShouldAddToLogbook();
public virtual int GetScoreScreenSessionIndex()
{
return 0;
}
public virtual int GetScoreScreenGamemodeIndex()
{
return 0;
}
public virtual int GetGamemodeIndex()
{
return 0;
}
public virtual int GetLogbookIndex()
{
return 0;
}
}
[HarmonyPatch]
public class CustomStatManager
{
public enum StatSource
{
gamemode = 0,
session = 2,
global = 3
}
private static readonly CustomStatManager instance = new CustomStatManager();
private readonly CustomStat[] customStats = new CustomStat[2]
{
new GrubsAdopted(),
new MaxGrubsAdopted()
};
public static bool Win { get; set; }
[HarmonyPatch(typeof(CL_GameManager), "EndGameStatUpdate")]
[HarmonyPostfix]
public static void EndGameStatUpdate(bool win)
{
Win = win;
CustomStat[] array = instance.customStats;
for (int i = 0; i < array.Length; i++)
{
array[i].EndGameStatUpdate(Win);
}
GrubStats.UpdateGrubScore();
}
[HarmonyPatch(typeof(UI_ScoreScreen), "ShowScreen")]
[HarmonyPostfix]
public static void AddStatsToScoreScreen(UI_ScoreScreen __instance)
{
if (!((Object)((Component)__instance).gameObject).name.StartsWith("ScorePanel_Standard"))
{
return;
}
Transform parent = ((Component)__instance).gameObject.transform.Find("Score Screen Root/Session Page/Board/Stats/SessionStats/Game Stats Simplified");
Transform parent2 = ((Component)__instance).gameObject.transform.Find("Score Screen Root/Session Page/Board/Stats/Best Stats/Top Score");
CustomStat[] array = instance.customStats;
foreach (CustomStat customStat in array)
{
if (customStat.ShouldAddToScoreScreenSession(Win))
{
Transform obj = InstantiateStatText(customStat, parent, "stat:", 4);
obj.SetSiblingIndex(customStat.GetScoreScreenSessionIndex());
((Component)((Component)obj).GetComponent<UT_StatText>()).GetComponent<TMP_Text>().text = StatUtils.GetText(customStat, (StatSource)2);
}
if (customStat.ShouldAddToScoreScreenGamemode(Win))
{
Transform obj2 = InstantiateStatText(customStat, parent2, "stat:", 3);
obj2.SetSiblingIndex(customStat.GetScoreScreenGamemodeIndex());
((Component)((Component)obj2).GetComponent<UT_StatText>()).GetComponent<TMP_Text>().text = StatUtils.GetText(customStat, (StatSource)0);
}
}
}
[HarmonyPatch(typeof(UI_GamemodeScreen), "Initialize")]
[HarmonyPostfix]
public static void AddStatsToGamemode(UI_GamemodeScreen __instance, M_Gamemode mode)
{
Transform val = ((Component)__instance).gameObject.transform.Find("Gamemode_Panel_Base_Campaign(Clone)/Pages/Gamemode_Info_Screen/Mode Page/Board/Stats/Stats/Scoregrid-Extra");
if ((Object)(object)val == (Object)null)
{
return;
}
CustomStat[] array = instance.customStats;
foreach (CustomStat customStat in array)
{
Transform val2 = val.Find("stat-" + customStat.GetId());
if ((Object)(object)val2 != (Object)null)
{
UiUtils.Destroy(val2);
}
if (customStat.ShouldAddToGamemode(mode))
{
val2 = InstantiateStatText(customStat, val, "stat-", 1);
val2.SetSiblingIndex(customStat.GetGamemodeIndex());
((Component)val2).GetComponent<UT_StatText>().Refresh();
}
}
}
[HarmonyPatch(typeof(UI_MenuScreen), "Initialize")]
[HarmonyPostfix]
public static void AddStatsToLogbook(UI_MenuScreen __instance)
{
if (!((Object)__instance).name.Equals("Logbook"))
{
return;
}
Transform parent = ((Component)__instance).gameObject.transform.Find("Stat Page/Board/Stats/Stats/Scoregrid-Extra");
UiUtils.DestroyChild("Break-Roaches.02", parent);
UiUtils.DestroyChild("Break-Roaches", parent);
CustomStat[] array = instance.customStats;
foreach (CustomStat customStat in array)
{
if (customStat.ShouldAddToLogbook())
{
Transform obj = InstantiateStatText(customStat, parent, "stat-", 1);
obj.SetSiblingIndex(customStat.GetLogbookIndex());
((Component)obj).GetComponent<UT_StatText>().Refresh();
}
}
}
private static Transform InstantiateStatText(CustomStat stat, Transform parent, string uiNamePrefix, int instantiationIndex)
{
//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)
Transform transform = Object.Instantiate<GameObject>(((Component)parent.GetChild(instantiationIndex)).gameObject, parent).transform;
((Object)transform).name = uiNamePrefix + stat.GetId();
UT_StatText component = ((Component)transform).GetComponent<UT_StatText>();
component.defaultText = stat.GetDefaultText(component.source);
component.textPrefix = stat.GetTextPrefix(component.source);
((Object)component).name = uiNamePrefix + stat.GetId();
component.statistic = stat.GetId();
return transform;
}
}
public class GrubsAdopted : CustomStat
{
public const string ID = "grubs-adopted";
public const string DEFAULT_TEXT_NO_GRUBS = "Don't you care about Grubs? :(";
public const string DEFAULT_TEXT_DEATH_WITH_GRUB = "You left your Grub alone T.T";
public const string DEFAULT_TEXT_DEATH_WITH_GRUBS = "You left your Grubs alone T.T";
public const string TEXT_PREFIX_SESSION = "Grubs Adopted: ";
public const string TEXT_PREFIX_GLOBAL = "Total Grubs Adopted: ";
public GrubsAdopted()
: base("grubs-adopted", 0, (DataType)0, (ModType)1, (DisplayType)0, (ModType)1)
{
}
protected override bool CalculateValueOnEndGame(bool win)
{
if (!win)
{
return false;
}
if (GrubStats.GetRescuedGrubsCount() == 0)
{
return false;
}
initialValue = GrubStats.GetRescuedGrubsCount();
return true;
}
public override string GetDefaultText(StatSource statSource)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
if (!StatUtils.HasPickedUpItem("SlugGrub"))
{
return "[REDACTED]";
}
if ((int)statSource == 2)
{
return (GrubRescueStation.GetGrubsStored() + InventoryUtils.TotalItemCount("SlugGrub")) switch
{
0 => "Don't you care about Grubs? :(",
1 => "You left your Grub alone T.T",
_ => "You left your Grubs alone T.T",
};
}
return GetTextPrefix(statSource) + 0;
}
public override string GetTextPrefix(StatSource statSource)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
if ((int)statSource != 2)
{
return "Total Grubs Adopted: ";
}
return "Grubs Adopted: ";
}
public override bool ShouldAddToScoreScreenSession(bool win)
{
if (ShouldAddToGamemode(CL_GameManager.gamemode))
{
return StatUtils.HasPickedUpItem("SlugGrub");
}
return false;
}
public override bool ShouldAddToScoreScreenGamemode(bool win)
{
if (ShouldAddToGamemode(CL_GameManager.gamemode))
{
return StatUtils.HasPickedUpItem("SlugGrub");
}
return false;
}
public override bool ShouldAddToGamemode(M_Gamemode gamemode)
{
if (!((Object)gamemode).name.Equals("GM_Campaign"))
{
return ((Object)gamemode).name.Equals("GM_Playground");
}
return true;
}
public override bool ShouldAddToLogbook()
{
return true;
}
public override int GetScoreScreenSessionIndex()
{
return 7;
}
public override int GetScoreScreenGamemodeIndex()
{
return 7;
}
public override int GetGamemodeIndex()
{
return 14;
}
public override int GetLogbookIndex()
{
return 13;
}
}
public static class GrubStats
{
public const string ID_GRUB_SCORE = "grub-score";
public const string ID_GRUBS_ADOPTED = "grubs-adopted";
public const string ID_MAX_GRUBS_ADOPTED = "max-grubs-adopted";
public static float winScoreMultiplier = 5f;
public static void UpdateGrubsAdopted()
{
}
public static void UpdateGrubScore()
{
if (CL_GameManager.gMan.GetGameTime() != 0f)
{
float playerBestTravelDistance = CL_GameManager.gMan.GetPlayerBestTravelDistance();
int rescuedGrubsCount = GetRescuedGrubsCount();
float num = CL_GameManager.gMan.GetGameTime() / 60f;
float num2 = playerBestTravelDistance * (float)rescuedGrubsCount / num;
if (CustomStatManager.Win)
{
num2 *= winScoreMultiplier;
}
num2 = (float)Math.Round(num2, 2, MidpointRounding.AwayFromZero);
Log.Info($"Grub Score: {num2}");
Log.Info($" = {(int)playerBestTravelDistance} Meters (Distance)" + $" * {rescuedGrubsCount} (#Grubs that made it out)" + $" / {(float)Math.Round(num, 2, MidpointRounding.AwayFromZero)} Minutes (Run Time)");
if (CustomStatManager.Win)
{
Log.Info(" * 5 (Because you escaped)");
}
Statistic stat = StatUtils.GetStat("grub-score", StatUtils.StatSource.gamemode);
string text = ((stat != null) ? stat.GetString() : null);
Log.Info("Previous Best: " + (string.IsNullOrEmpty(text) ? "N/A" : text));
StatManager.sessionStats.UpdateStatistic("grub-score", (object)num2, (DataType)2, (ModType)0, (DisplayType)0, (ModType)2);
}
}
public static int GetRescuedGrubsCount()
{
int num = GrubRescueStation.GetGrubsStored();
if (CustomStatManager.Win)
{
num += InventoryUtils.TotalItemCount("SlugGrub");
}
return num;
}
}
public class MaxGrubsAdopted : CustomStat
{
public MaxGrubsAdopted()
: base("max-grubs-adopted", 0, (DataType)0, (ModType)2, (DisplayType)0, (ModType)2)
{
}
protected override bool CalculateValueOnEndGame(bool win)
{
if (!win)
{
return false;
}
if (GrubStats.GetRescuedGrubsCount() == 0)
{
return false;
}
initialValue = GrubStats.GetRescuedGrubsCount();
return true;
}
public override string GetDefaultText(StatSource statSource)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
if (!StatUtils.HasPickedUpItem("SlugGrub"))
{
return "[REDACTED]";
}
return GetTextPrefix(statSource) + 0;
}
public override string GetTextPrefix(StatSource statSource)
{
return "Most Adopted in a Run: ";
}
public override bool ShouldAddToScoreScreenSession(bool win)
{
return false;
}
public override bool ShouldAddToScoreScreenGamemode(bool win)
{
if (ShouldAddToGamemode(CL_GameManager.gamemode))
{
return StatUtils.HasPickedUpItem("SlugGrub");
}
return false;
}
public override bool ShouldAddToGamemode(M_Gamemode gamemode)
{
if (!((Object)gamemode).name.Equals("GM_Campaign"))
{
return ((Object)gamemode).name.Equals("GM_Playground");
}
return true;
}
public override bool ShouldAddToLogbook()
{
return true;
}
public override int GetScoreScreenGamemodeIndex()
{
return 8;
}
public override int GetGamemodeIndex()
{
return 15;
}
public override int GetLogbookIndex()
{
return 14;
}
}
public class StatRequirement : MonoBehaviour
{
public enum OverrideMode
{
replace,
and,
or
}
public string id;
public int fromInt = int.MinValue;
public int toInt = int.MaxValue;
public string matchString;
public float fromFloat = float.NegativeInfinity;
public float toFloat = float.PositiveInfinity;
public StatUtils.StatSource source;
public OverrideMode overrideMode;
public bool metWhenUndefined;
private void Start()
{
GameObject gameObject = ((Component)this).gameObject;
gameObject.SetActive(overrideMode switch
{
OverrideMode.replace => IsMet(),
OverrideMode.and => ((Component)this).gameObject.activeInHierarchy && IsMet(),
OverrideMode.or => ((Component)this).gameObject.activeInHierarchy || IsMet(),
_ => ((Component)this).gameObject.activeInHierarchy,
});
}
private bool IsMet()
{
//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_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected I4, but got Unknown
Statistic stat = StatUtils.GetStat(id, source);
if (stat == null)
{
return metWhenUndefined;
}
object value = stat.GetValue();
DataType type = stat.type;
return (int)type switch
{
0 => fromInt <= (int)value && (int)value <= toInt,
1 => (string)value == matchString,
2 => fromFloat <= (float)value && (float)value <= toFloat,
_ => false,
};
}
}
}
namespace GrubAdoption.Rescuing
{
public class GrubDispenser : MonoBehaviour, Clickable
{
public float delayRangeDispenseGrub = 0.8f;
private UT_AudioClipHandler clipHandler;
private void Start()
{
clipHandler = ((Component)this).GetComponent<UT_AudioClipHandler>();
}
void Clickable.Interact(InteractionInfo info)
{
clipHandler.PlaySound("grub-dispensing:boop");
int grubsStored = GrubRescueStation.GetGrubsStored();
Log.Info($"Dispensing grubs: {grubsStored}");
Item grubItem;
if (grubsStored != 0)
{
grubItem = AssetUtils.GetItem("Denizen_SlugGrub");
for (int i = 0; i < grubsStored; i++)
{
((MonoBehaviour)this).StartCoroutine(AddGrubToBag());
}
GrubRescueStation.ResetGrubsStored();
}
IEnumerator AddGrubToBag()
{
yield return (object)new WaitForSeconds(Random.value * delayRangeDispenseGrub);
InventoryUtils.LoadItemIntoBag(grubItem);
clipHandler.PlaySound("grub-dispensing:dispense-grub");
}
}
bool Clickable.CanInteract(Interaction interaction)
{
return true;
}
public ObjectTagger GetTagger()
{
return ((Component)this).gameObject.GetComponent<ObjectTagger>();
}
public GameObject GetGameObject()
{
return ((Component)this).gameObject;
}
}
public class GrubRescueStation : MonoBehaviour
{
public const string FLAG_GRUBS_STORED = "grubs-stored";
public float delayRangeExitInventory = 0.1f;
public float delayEnterStation = 0.15f;
private UT_AudioClipHandler clipHandler;
private void Start()
{
clipHandler = ((Component)this).GetComponent<UT_AudioClipHandler>();
}
public void InsertGrub()
{
((MonoBehaviour)this).StartCoroutine(PlaySounds());
SetGrubsStored(GetGrubsStored() + 1);
Log.Info($"Grub inserted (stored: {GetGrubsStored()})");
IEnumerator PlaySounds()
{
if (clipHandler.GetGroup("grub-rescuing").GetSet("exit-inventory").aud.isPlaying)
{
yield return (object)new WaitForSeconds(delayRangeExitInventory);
}
clipHandler.PlaySound("grub-rescuing:exit-inventory");
yield return (object)new WaitForSeconds(delayEnterStation);
clipHandler.PlaySound("grub-rescuing:enter-station");
}
}
public static int GetGrubsStored()
{
SessionFlag gameFlag = CL_GameManager.GetGameFlag("grubs-stored");
if (gameFlag == null || gameFlag.data == null)
{
return 0;
}
return int.Parse(gameFlag.data);
}
public static void ResetGrubsStored()
{
SetGrubsStored(0);
}
private static void SetGrubsStored(int amount)
{
CL_GameManager.SetGameFlag("grubs-stored", true, amount.ToString(), false, false);
}
}
public class GrubSlot : MonoBehaviour, Clickable
{
private const string INTERACTOR_TAG = "GrubSlot";
private GrubRescueStation rescueStation;
private void Start()
{
rescueStation = ((Component)this).GetComponentInParent<GrubRescueStation>();
if ((int)StatUtils.GetValueOrDefault("grubs-adopted", 0, StatUtils.StatSource.global) <= 0)
{
GetTagger().tags.Remove("GrubSlot");
}
}
void Clickable.Interact(InteractionInfo info)
{
rescueStation.InsertGrub();
}
bool Clickable.CanInteract(Interaction interaction)
{
return interaction.curhand.inventoryHand.currentItem?.itemName == "SlugGrub";
}
public ObjectTagger GetTagger()
{
return ((Component)this).gameObject.GetComponent<ObjectTagger>();
}
public GameObject GetGameObject()
{
return ((Component)this).gameObject;
}
}
[HarmonyPatch]
public static class GrubUsagePrevention
{
private static bool grubUsageDisabled = false;
private static readonly Dictionary<int, Clickable> interactionClickables = new Dictionary<int, Clickable>
{
{ 0, null },
{ 1, null }
};
[HarmonyPatch(typeof(HandItem_Buff), "Use")]
[HarmonyPrefix]
public static bool PreventGrubUse(HandItem_Buff __instance)
{
Clickable interactorClickable = GetInteractorClickable(((Hand_Base)__instance).hand.id);
if (((HandItem)__instance).item.itemName != "SlugGrub")
{
return true;
}
if (grubUsageDisabled || interactorClickable is GrubSlot || interactorClickable is GrubDispenser)
{
return false;
}
return true;
}
[HarmonyPatch(typeof(Item_InteractionModule), "CanInteractWithInteractable")]
[HarmonyPostfix]
public static void SetInteractorClickables(Interaction interaction)
{
interactionClickables[interaction.curhand.id] = interaction.clickable;
}
[HarmonyPatch(typeof(Inventory), "Update")]
[HarmonyPostfix]
public static void ResetInteractorClickables()
{
interactionClickables[0] = null;
interactionClickables[1] = null;
}
public static Clickable GetInteractorClickable(int handId)
{
if (!interactionClickables.ContainsKey(handId))
{
return null;
}
return interactionClickables[handId];
}
}
}
namespace GrubAdoption.Assets
{
[HarmonyPatch]
public static class GrubAdoptionAssets
{
private static readonly string ASSET_BUNDLE_FILE = "grub-adoption.assets";
private static AssetBundle assetBundle;
public static GameObject LevelModifications_Campaign { get; private set; }
public static Sprite GrubInteractionSprite { get; private set; }
public static Item_InteractionModule GrubInteractor { get; private set; }
public static GameObject LevelModifications_Debug { get; private set; }
public static async Task Initialize(string assemblyPath)
{
string assetBundlePath = Path.Combine(assemblyPath, ASSET_BUNDLE_FILE);
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(assetBundlePath);
if (request == null)
{
Log.Error("Failed to load asset bundle: " + assetBundlePath);
return;
}
while (!((AsyncOperation)request).isDone)
{
await Task.Yield();
}
assetBundle = request.assetBundle;
if (assetBundle == null)
{
Log.Error("Failed to load asset bundle: " + assetBundlePath);
return;
}
Log.Info("Successfully loaded asset bundle");
InitializeLevelModifications();
InitializeGrubInteractor();
}
private static void InitializeLevelModifications()
{
LevelModificationLoader levelModificationLoader = new LevelModificationLoader((M_Gamemode gamemode) => ((Object)gamemode).name == "GM_Campaign" && !gamemode.IsIronKnuckle());
LevelModifications_Campaign = assetBundle.LoadAsset<GameObject>("LevelModifications_Campaign");
if ((Object)(object)LevelModifications_Campaign == (Object)null)
{
LoadError("LevelModifications_Campaign");
}
else
{
levelModificationLoader.RegisterModificationsFromChildren(LevelModifications_Campaign);
}
}
private static void InitializeGrubInteractor()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
GrubInteractionSprite = assetBundle.LoadAsset<Sprite>("GrubInteractionSprite");
if ((Object)(object)GrubInteractionSprite == (Object)null)
{
LoadError("GrubInteractionSprite");
return;
}
GrubInteractor = new Item_InteractionModule();
GrubInteractor.interactorName = "Grub";
GrubInteractor.interactionTag = "GrubSlot";
GrubInteractor.interactionSprite = GrubInteractionSprite;
GrubInteractor.interactionType = (InteractionType)1;
}
[HarmonyPatch(typeof(Item), "InitializeInHand")]
[HarmonyPostfix]
public static void TrySetInteractor(Item __instance)
{
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
if (GrubInteractor == null)
{
LoadError("GrubInteractor");
}
else
{
if (__instance.itemName != "SlugGrub")
{
return;
}
HandItem handItem = __instance.GetHandItem();
if (handItem.interactionModules != null && handItem.interactionModules.Contains(GrubInteractor))
{
Log.Info("This Grub already has a GrubInteractor in its interactionModules");
return;
}
if (handItem.HasInteractor())
{
handItem.interactionModules.Add(GrubInteractor);
Log.Info("Added GrubInteractor to interactionModules");
}
else
{
handItem.interactionModules = new List<Item_InteractionModule>(1) { GrubInteractor };
Log.Info("Set interactionModules to [GrubInteractor]");
}
__instance.interactType = (InteractType)2;
}
}
private static void LoadError(string assetName)
{
Log.Error("Loading " + assetName + " failed");
}
}
public class LevelModification
{
private const string ASSET_PREFIX = "LM_";
private readonly GameObject asset;
private readonly LevelModificationLoader loader;
public string Level { get; }
public LevelModification(GameObject asset, LevelModificationLoader loader)
{
this.asset = asset;
this.loader = loader;
string name = ((Object)asset).name;
if (!name.StartsWith("LM_"))
{
Log.Error("Error while loading LevelModification " + name + ": Name must match pattern LM_<level name>");
}
else
{
Level = name.Substring("LM_".Length);
}
}
public void InjectInto(GameObject levelObject)
{
Log.Info("Injecting a LevelModification into " + Level);
InjectRecursive(asset.transform, levelObject.transform);
}
private void InjectRecursive(Transform assetNode, Transform levelObjectNode)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
foreach (Transform item in assetNode)
{
Transform val = item;
Transform val2 = levelObjectNode.Find(((Object)val).name);
if ((Object)(object)val2 != (Object)null)
{
InjectRecursive(val, val2);
continue;
}
Log.Info("Injecting " + ((Object)val).name + " at " + ((Object)levelObjectNode).name);
((Object)Object.Instantiate<Transform>(val, levelObjectNode)).name = loader.GetScopedName(((Object)val).name);
}
}
}
[HarmonyPatch]
public class LevelModificationLoader
{
private static readonly List<LevelModificationLoader> loaders = new List<LevelModificationLoader>();
private readonly Func<M_Gamemode, bool> LoadInGamemode;
private readonly Dictionary<string, LevelModification> modificationsDict = new Dictionary<string, LevelModification>();
public LevelModificationLoader(Func<M_Gamemode, bool> LoadInGamemode = null)
{
this.LoadInGamemode = LoadInGamemode ?? ((Func<M_Gamemode, bool>)((M_Gamemode _) => true));
loaders.Add(this);
}
public void RegisterModification(GameObject modificationAsset)
{
LevelModification levelModification = new LevelModification(modificationAsset, this);
modificationsDict.Add(levelModification.Level, levelModification);
Log.Info("Registered LevelModification for " + levelModification.Level);
}
public void RegisterModificationsFromChildren(GameObject parent)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
foreach (Transform item in parent.transform)
{
Transform val = item;
RegisterModification(((Component)val).gameObject);
}
}
public string GetScopedName(string name)
{
return name + " (com.anonymousfroggo.grubadoption)";
}
[HarmonyPatch(typeof(M_Level), "Awake")]
[HarmonyPostfix]
public static void InjectLevelModifications(M_Level __instance)
{
foreach (LevelModificationLoader item in loaders.Where((LevelModificationLoader loader) => loader.LoadInGamemode(CL_GameManager.gamemode) && loader.modificationsDict.ContainsKey(__instance.levelName)))
{
item.modificationsDict[__instance.levelName].InjectInto(((Component)__instance).gameObject);
}
}
}
}