using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalAchievements;
using LethalModDataLib.Attributes;
using TerminalApi;
using TerminalApi.Classes;
using UnityEngine;
using UnityEngine.UI;
using conpancka.Utils;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LethalAchievements")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalAchievements")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("F59232DD-6955-4551-9CB1-CFB2A5ADBB82")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
public class AchievementPopupUI : MonoBehaviour
{
public Text nameText;
public Text descriptionText;
public Image iconImage;
public GameObject iconError;
public float fadeDuration = 2f;
public float stayDuration = 5f;
public AudioSource audioSource;
public void SetDetails(string name, string description, Sprite icon)
{
nameText.text = name;
descriptionText.text = description;
if ((Object)(object)icon != (Object)null)
{
iconImage.sprite = icon;
iconError.SetActive(false);
}
else
{
((Behaviour)iconImage).enabled = false;
iconError.SetActive(true);
}
if (Plugin.instance.soundOn.Value)
{
audioSource.Play();
}
((MonoBehaviour)this).StartCoroutine(ShowAndFadeOut());
}
private IEnumerator ShowAndFadeOut()
{
yield return (object)new WaitForSeconds(stayDuration);
yield return ((MonoBehaviour)this).StartCoroutine(FadeOut());
}
private IEnumerator FadeOut()
{
CanvasGroup canvasGroup = ((Component)this).GetComponent<CanvasGroup>();
if ((Object)(object)canvasGroup == (Object)null)
{
canvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>();
}
float startAlpha = canvasGroup.alpha;
float timeElapsed = 0f;
while (timeElapsed < fadeDuration)
{
timeElapsed += Time.deltaTime;
canvasGroup.alpha = Mathf.Lerp(startAlpha, 0f, timeElapsed / fadeDuration);
yield return null;
}
canvasGroup.alpha = 0f;
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
namespace conpancka.Utils
{
public static class AssetUtils
{
public static AssetBundle LoadAssetBundleFromEmbeddedResources(string bundleName)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string text = null;
try
{
text = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(bundleName));
}
catch (Exception)
{
}
if (text == null)
{
Debug.LogError((object)("AssetBundle " + bundleName + " not found in assembly manifest"));
return null;
}
using Stream stream = executingAssembly.GetManifestResourceStream(text);
return AssetBundle.LoadFromStream(stream);
}
public static Sprite LoadSpriteFromEmbeddedResources(string resourceName)
{
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Expected O, but got Unknown
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string text = null;
try
{
text = executingAssembly.GetManifestResourceNames().SingleOrDefault((string str) => str.EndsWith(resourceName, StringComparison.OrdinalIgnoreCase));
}
catch (Exception ex)
{
Debug.LogError((object)("Exception finding resource: " + ex.Message));
}
if (text == null)
{
Debug.LogError((object)("Resource '" + resourceName + "' not found in assembly manifest"));
return null;
}
byte[] array;
using (Stream stream = executingAssembly.GetManifestResourceStream(text))
{
if (stream == null)
{
Debug.LogError((object)("Stream for resource '" + resourceName + "' is null."));
return null;
}
using BinaryReader binaryReader = new BinaryReader(stream);
array = binaryReader.ReadBytes((int)stream.Length);
}
Texture2D val = new Texture2D(2, 2);
if (ImageConversion.LoadImage(val, array))
{
return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
}
Debug.LogError((object)"Failed to load texture from PNG data.");
return null;
}
}
}
namespace LethalAchievements
{
public class AchievementManager
{
private static AchievementManager instance;
[ModData(/*Could not decode attribute arguments.*/)]
public static int completion = 0;
[ModData(/*Could not decode attribute arguments.*/)]
private static bool comedyGoldUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string comedyGoldText = "Locked";
[ModData(/*Could not decode attribute arguments.*/)]
private static bool notTheBeesUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string notTheBeesText = "Locked";
[ModData(/*Could not decode attribute arguments.*/)]
private static bool employeeOfTheMonthUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string employeeOfTheMonthText = "Locked";
[ModData(/*Could not decode attribute arguments.*/)]
private static bool targetAcquiredUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string targetAcquiredText = "Locked";
[ModData(/*Could not decode attribute arguments.*/)]
private static bool thisIsMyBoomstickUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string thisIsMyBoomstickText = "Locked";
[ModData(/*Could not decode attribute arguments.*/)]
private static bool pestControlUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string pestControlText = "Locked";
[ModData(/*Could not decode attribute arguments.*/)]
private static bool dontBlinkUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string dontBlinkText = "Locked";
[ModData(/*Could not decode attribute arguments.*/)]
private static bool youMonsterUnlocked;
[ModData(/*Could not decode attribute arguments.*/)]
public static string youMonsterText = "Locked";
public static void Initialize()
{
if (instance == null)
{
instance = new AchievementManager();
}
}
public static void ComedyGold()
{
if (!comedyGoldUnlocked)
{
string name = "Comedy Gold";
string description = "Find a mask";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("ComedyGold.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
comedyGoldUnlocked = true;
comedyGoldText = "Unlocked";
completion++;
}
}
public static void NotTheBees()
{
if (!notTheBeesUnlocked)
{
string name = "Not The Bees!";
string description = "Successfully complete a hive run";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("NotTheBees.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
notTheBeesUnlocked = true;
notTheBeesText = "Unlocked";
completion++;
}
}
public static void EmployeeOfTheMonth()
{
if (!employeeOfTheMonthUnlocked)
{
string name = "Employee Of The Month";
string description = "Complete your first quota";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("EmployeeOfTheMonth.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
employeeOfTheMonthUnlocked = true;
employeeOfTheMonthText = "Unlocked";
completion++;
}
}
public static void TargetAcquired()
{
if (!targetAcquiredUnlocked)
{
string name = "Target Acquired";
string description = "Get killed by a turret";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("TargetAcquired.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
targetAcquiredUnlocked = true;
targetAcquiredText = "Unlocked";
completion++;
}
}
public static void ThisIsMyBoomstick()
{
if (!thisIsMyBoomstickUnlocked)
{
string name = "This, Is My Boomstick!";
string description = "Fire a Nutcracker's shotgun";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("ThisIsMyBoomstick.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
thisIsMyBoomstickUnlocked = true;
thisIsMyBoomstickText = "Unlocked";
completion++;
}
}
public static void PestControl()
{
if (!pestControlUnlocked)
{
string name = "Pest Control";
string description = "Kill a hoarding bug";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("PestControl.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
pestControlUnlocked = true;
pestControlText = "Unlocked";
completion++;
}
}
public static void DontBlink()
{
if (!dontBlinkUnlocked)
{
string name = "Don't Blink";
string description = "Spot a Coilhead";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("DontBlink.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
dontBlinkUnlocked = true;
dontBlinkText = "Unlocked";
completion++;
}
}
public static void YouMonster()
{
if (!youMonsterUnlocked)
{
string name = "You Monster!";
string description = "Hit another crewmate with a shovel";
Sprite icon = AssetUtils.LoadSpriteFromEmbeddedResources("YouMonster.png");
Plugin.instance.ShowAchievementPopup(name, description, icon);
youMonsterUnlocked = true;
youMonsterText = "Unlocked";
completion++;
}
}
}
[BepInPlugin("conpancka.LethalAchievements", "Lethal Achievements", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private const string modGUID = "conpancka.LethalAchievements";
private const string modName = "Lethal Achievements";
private const string modVersion = "1.0.0";
private readonly Harmony harmony = new Harmony("conpancka.LethalAchievements");
public static Plugin instance;
internal static ManualLogSource mls;
private const string assetBundleName = "achievementpopupbundle";
private const string prefabName = "AchievementPopup";
private AssetBundle assetBundle;
private GameObject achievementPopupPrefab;
private ConfigEntry<float> notifScale;
public ConfigEntry<bool> soundOn;
private void Awake()
{
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Expected O, but got Unknown
if ((Object)(object)instance == (Object)null)
{
instance = this;
}
AchievementManager.Initialize();
mls = Logger.CreateLogSource("conpancka.LethalAchievements");
mls.LogInfo((object)"Loading Asset Bundle...");
assetBundle = AssetUtils.LoadAssetBundleFromEmbeddedResources("achievementpopupbundle");
achievementPopupPrefab = assetBundle.LoadAsset<GameObject>("AchievementPopup");
notifScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "NotificationScale", 0.4f, "The scale of the notification popup on screen");
soundOn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "NotificationSoundOn", true, "Set to true if you want it to play sound when you get an achievement, or set to false if you don't want the sound");
TerminalApi.AddCommand("Achievements", new CommandInfo
{
DisplayTextSupplier = () => "ACHIEVEMENT LIST\n\nView your locked and unlocked achievements\n\nAchievement Completion: " + Percentage() + "%\n____________________________\n\n\nNot The Bees!: " + AchievementManager.notTheBeesText + "\nTarget Acquired: " + AchievementManager.targetAcquiredText + "\nComedy Gold: " + AchievementManager.comedyGoldText + "\nEmployee Of The Month: " + AchievementManager.employeeOfTheMonthText + "\nPest Control: " + AchievementManager.pestControlText + "\nThis, Is My Boomstick!: " + AchievementManager.thisIsMyBoomstickText + "\nDon't Blink: " + AchievementManager.dontBlinkText + "\nYou Monster!: " + AchievementManager.youMonsterText + "\n\n",
Description = "To view your unlocked achievements.",
Category = "Other"
}, (string)null, true);
harmony.PatchAll(Assembly.GetExecutingAssembly());
mls.LogInfo((object)"Lethal Achievements version 1.0.0 has been loaded!");
}
public void ShowAchievementPopup(string name, string description, Sprite icon)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
GameObject val = GameObject.Find("/Systems/UI/Canvas");
GameObject obj = Object.Instantiate<GameObject>(achievementPopupPrefab, val.transform);
obj.transform.localScale = Vector3.one * notifScale.Value;
obj.GetComponent<AchievementPopupUI>().SetDetails(name, description, icon);
}
private static string Percentage()
{
return ((int)(0.5f + 100f * (float)AchievementManager.completion / 8f)).ToString();
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "LethalAchievements";
public const string PLUGIN_NAME = "";
public const string PLUGIN_VERSION = "1.0.0.0";
}
}
namespace LethalAchievements.Patches
{
[HarmonyPatch(typeof(SpringManAI))]
internal class DontBlink
{
[HarmonyPostfix]
[HarmonyPatch("Update")]
private static void DontBlinkPatch(SpringManAI __instance)
{
FieldInfo field = typeof(SpringManAI).GetField("hasStopped", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null && (bool)field.GetValue(__instance))
{
AchievementManager.DontBlink();
}
}
}
[HarmonyPatch(typeof(TimeOfDay))]
internal class EmployeeOfTheMonth
{
[HarmonyPostfix]
[HarmonyPatch("SetNewProfitQuota")]
private static void EmployeeOfTheMonthPatch()
{
AchievementManager.EmployeeOfTheMonth();
}
}
[HarmonyPatch(typeof(GrabbableObject))]
internal class NotTheBees
{
[HarmonyPostfix]
[HarmonyPatch("DiscardItem")]
private static void NotTheBeesPatch(GrabbableObject __instance)
{
if (__instance.itemProperties.itemName == "Hive" && __instance.isInShipRoom)
{
AchievementManager.NotTheBees();
}
}
}
[HarmonyPatch(typeof(HoarderBugAI))]
internal class PestControl
{
[HarmonyPostfix]
[HarmonyPatch("KillEnemy")]
private static void PestControlPatch()
{
AchievementManager.PestControl();
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class TargetAcquired
{
[HarmonyPostfix]
[HarmonyPatch("KillPlayer")]
private static void TargetAcquiredPatch(Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation, Vector3 positionOffset)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
if ((int)causeOfDeath == 7)
{
AchievementManager.TargetAcquired();
}
}
}
[HarmonyPatch(typeof(ShotgunItem))]
internal class ThisIsMyBoomstick
{
[HarmonyPostfix]
[HarmonyPatch("ShootGun")]
private static void ThisIsMyBoomstickPatch()
{
AchievementManager.ThisIsMyBoomstick();
}
}
[HarmonyPatch(typeof(Shovel))]
internal class YouMonster
{
[HarmonyPostfix]
[HarmonyPatch("HitShovel")]
private static void YouMonsterPatch()
{
AchievementManager.YouMonster();
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class ComedyGold
{
[HarmonyPostfix]
[HarmonyPatch("GrabObject")]
private static void ComedyGoldPatch(PlayerControllerB __instance)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerControllerB), "currentlyGrabbingObject");
if (!(fieldInfo == null))
{
object? value = fieldInfo.GetValue(__instance);
GrabbableObject val = (GrabbableObject)((value is GrabbableObject) ? value : null);
if (!((Object)(object)val == (Object)null) && (val.itemProperties.itemName == "Comedy" || val.itemProperties.itemName == "Tragedy"))
{
AchievementManager.ComedyGold();
}
}
}
}
}