using System;
using System.Collections.Generic;
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 System.Security;
using System.Security.Permissions;
using AtlasLib.Pages;
using AtlasLib.Style;
using AtlasLib.Utils;
using AtlasLib.Weapons;
using BepInEx;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AtlasLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AtlasLib")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("cf4a38ab-c781-4066-83d2-47a9f5713d5c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace AtlasLib
{
[BepInPlugin("waffle.ultrakill.atlas", "AtlasLib", "2.0.0")]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "waffle.ultrakill.atlas";
public const string Name = "AtlasLib";
public const string Version = "2.0.0";
public static readonly Harmony Harmony = new Harmony("waffle.ultrakill.atlas");
private void Start()
{
PageRegistry.Initialize();
WeaponRegistry.Initialize();
StyleRegistry.Initialize();
SceneManager.sceneLoaded += delegate
{
if (PatchThis.HasntPatched)
{
PatchThis.PatchAll();
}
};
}
private void OnDestroy()
{
WeaponRegistry.SaveData();
}
}
}
namespace AtlasLib.Weapons
{
public class BasicWeapon : Weapon
{
private WeaponInfo _info;
public override WeaponInfo Info => _info;
public BasicWeapon(WeaponInfo info)
{
_info = info;
}
}
public static class WeaponRegistry
{
private static string SavePath = Path.Combine(PathUtils.ModPath(), "save{0}");
private static Dictionary<string, int> WeaponOwnership = new Dictionary<string, int>();
public static List<Weapon> Weapons = new List<Weapon>();
public static List<Weapon> Guns = new List<Weapon>();
public static List<Weapon> Fists = new List<Weapon>();
private static string CurrentSave => string.Format(SavePath, GameProgressSaver.currentSlot);
internal static void Initialize()
{
Plugin.Harmony.PatchAll(typeof(WeaponRegistry));
LoadData();
}
public static void LoadData()
{
WeaponOwnership.Clear();
if (!File.Exists(CurrentSave))
{
return;
}
foreach (string item in File.ReadLines(CurrentSave))
{
string[] array = item.Split(new char[1] { '~' });
WeaponOwnership.Add(array[0], int.Parse(array[1]));
}
}
public static void SaveData()
{
using StreamWriter streamWriter = File.CreateText(CurrentSave);
foreach (KeyValuePair<string, int> item in WeaponOwnership)
{
streamWriter.WriteLine($"{item.Key}~{item.Value}");
}
}
public static bool CheckOwnership(string id)
{
if (id.StartsWith("weapon."))
{
throw new Exception("Id starts with 'weapon.'. Don't do that, it gets added automatically");
}
id = "weapon." + id;
if (!WeaponOwnership.ContainsKey(id))
{
WeaponOwnership.Add(id, 0);
}
return WeaponOwnership[id] == 1;
}
public static void Register(Weapon weapon)
{
if (weapon.Info.WeaponType == WeaponType.Gun)
{
Guns.Add(weapon);
}
else
{
Fists.Add(weapon);
}
Weapons.Add(weapon);
}
[HarmonyPatch(typeof(GameProgressSaver), "SetSlot")]
[HarmonyPrefix]
private static void SaveOnSlotChange()
{
SaveData();
}
[HarmonyPatch(typeof(GameProgressSaver), "SetSlot")]
[HarmonyPostfix]
private static void LoadOnSlotChange()
{
LoadData();
}
[HarmonyPatch(typeof(GunSetter), "ResetWeapons")]
[HarmonyPostfix]
private static void GiveGuns(GunSetter __instance)
{
Guns = Guns.OrderBy((Weapon gun) => gun.Info.OrderInSlot).ToList();
foreach (Weapon gun in Guns)
{
if (gun.Selection != 0)
{
List<List<GameObject>> list = new List<List<GameObject>>
{
__instance.gunc.slot1,
__instance.gunc.slot2,
__instance.gunc.slot3,
__instance.gunc.slot4,
__instance.gunc.slot5,
__instance.gunc.slot6
};
GameObject val = gun.Create(((Component)__instance).transform);
list[gun.Info.Slot].Add(val);
val.SetActive(false);
}
}
}
[HarmonyPatch(typeof(FistControl), "ResetFists")]
[HarmonyPostfix]
private static void GiveFists(FistControl __instance)
{
Fists = Fists.OrderBy((Weapon gun) => gun.Info.OrderInSlot).ToList();
foreach (Weapon fist in Fists)
{
if (fist.Selection != 0 && fist.Owned)
{
GameObject val = fist.Create(((Component)__instance).transform);
val.SetActive(false);
MonoSingleton<FistControl>.Instance.spawnedArms.Add(val);
MonoSingleton<FistControl>.Instance.spawnedArmNums.Add(fist.Info.Slot);
}
}
}
[HarmonyPatch(typeof(GameProgressSaver), "CheckGear")]
[HarmonyPrefix]
private static bool CheckGearForCustoms(ref int __result, string gear)
{
foreach (Weapon weapon in Weapons)
{
if (weapon.Info?.Id == gear)
{
__result = WeaponOwnership["weapon." + weapon.Info.Id];
return false;
}
}
return true;
}
[HarmonyPatch(typeof(GameProgressSaver), "AddGear")]
[HarmonyPrefix]
private static bool AddGearForCustoms(string gear)
{
foreach (Weapon weapon in Weapons)
{
if (weapon.Info.Id == gear)
{
WeaponOwnership["weapon." + weapon.Info.Id] = 1;
return false;
}
}
return true;
}
}
public abstract class Weapon
{
public abstract WeaponInfo Info { get; }
public virtual WeaponSelection Selection => Owned ? ((WeaponSelection)MonoSingleton<PrefsManager>.Instance.GetInt("weapon." + Info.Id, 0)) : WeaponSelection.Disabled;
public virtual bool Owned => WeaponRegistry.CheckOwnership(Info.Id);
public virtual GameObject Create(Transform parent)
{
GameObject val = Object.Instantiate<GameObject>(Info.WeaponObjects[(int)(Selection - 1)], parent);
if (Info.UseFreshness)
{
MonoSingleton<StyleHUD>.Instance.weaponFreshness.Add(val, 10f);
}
return val;
}
}
[CreateAssetMenu(menuName = "AtlasLib/Weapon Info")]
public class WeaponInfo : ScriptableObject
{
public GameObject[] WeaponObjects = (GameObject[])(object)new GameObject[1];
public WeaponType WeaponType = WeaponType.Gun;
[Space(10f)]
public string Id = "rev0";
public int Slot = 0;
public int OrderInSlot;
public bool UseFreshness = true;
public WeaponInfo(GameObject[] weaponObjects, string id, int slot, WeaponType weaponType = WeaponType.Gun, int orderInSlot = 0, bool useFreshness = true)
{
WeaponObjects = weaponObjects;
Id = id;
Slot = slot;
WeaponType = weaponType;
OrderInSlot = orderInSlot;
UseFreshness = useFreshness;
}
}
public enum WeaponSelection
{
Disabled,
Standard,
Alternate
}
public enum WeaponType
{
Gun,
Fist
}
}
namespace AtlasLib.Utils
{
public class CoroutineRunner : MonoBehaviour
{
private static CoroutineRunner _instance;
public static CoroutineRunner Instance
{
get
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_instance == (Object)null)
{
_instance = new GameObject("WW Coroutines").AddComponent<CoroutineRunner>();
Object.DontDestroyOnLoad((Object)(object)((Component)_instance).gameObject);
}
return _instance;
}
}
}
public static class Inputs
{
public static bool FirePressed => MonoSingleton<InputManager>.Instance.InputSource.Fire1.WasPerformedThisFrame;
public static bool FireHeld => MonoSingleton<InputManager>.Instance.InputSource.Fire1.IsPressed;
public static bool FireReleased => MonoSingleton<InputManager>.Instance.InputSource.Fire1.WasCanceledThisFrame;
public static bool AltFirePressed => MonoSingleton<InputManager>.Instance.InputSource.Fire2.WasPerformedThisFrame;
public static bool AltFireHeld => MonoSingleton<InputManager>.Instance.InputSource.Fire2.IsPressed;
public static bool AltFireReleased => MonoSingleton<InputManager>.Instance.InputSource.Fire2.WasCanceledThisFrame;
public static bool PunchPressed => MonoSingleton<InputManager>.Instance.InputSource.Punch.WasPerformedThisFrame;
public static bool PunchHeld => MonoSingleton<InputManager>.Instance.InputSource.Punch.IsPressed;
public static bool PunchReleased => MonoSingleton<InputManager>.Instance.InputSource.Punch.WasCanceledThisFrame;
}
public class PatchThis : Attribute
{
public static Dictionary<Type, PatchThis> AllPatches = new Dictionary<Type, PatchThis>();
public static bool HasntPatched = true;
private Harmony _harmony;
public readonly string Name;
public static void AddPatches()
{
foreach (Type item in from t in Assembly.GetCallingAssembly().GetTypes()
where t.GetCustomAttribute<PatchThis>() != null
select t)
{
Debug.Log((object)("Adding patch " + item.Name + "..."));
AllPatches.Add(item, item.GetCustomAttribute<PatchThis>());
}
}
public static void PatchAll()
{
HasntPatched = false;
foreach (KeyValuePair<Type, PatchThis> allPatch in AllPatches)
{
PatchThis value = allPatch.Value;
Debug.Log((object)("Patching " + allPatch.Key.Name + "..."));
value._harmony.PatchAll(allPatch.Key);
}
}
public PatchThis(string harmonyName)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
_harmony = new Harmony(harmonyName);
Name = harmonyName;
}
}
public static class PathUtils
{
public static string GameDirectory()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
string text = Application.dataPath;
if ((int)Application.platform == 1)
{
text = Utility.ParentDirectory(text, 2);
}
else if ((int)Application.platform == 2)
{
text = Utility.ParentDirectory(text, 1);
}
return text;
}
public static string ModDirectory()
{
return Path.Combine(GameDirectory(), "BepInEx", "plugins");
}
public static string ModPath()
{
return Assembly.GetCallingAssembly().Location.Substring(0, Assembly.GetCallingAssembly().Location.LastIndexOf(Path.DirectorySeparatorChar));
}
}
public static class UnityUtils
{
public static GameObject GetChild(this GameObject from, string name)
{
Transform obj = from.transform.Find(name);
return ((obj != null) ? ((Component)obj).gameObject : null) ?? null;
}
public static List<GameObject> FindSceneObjects(string sceneName)
{
//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)
List<GameObject> list = new List<GameObject>();
GameObject[] array = Object.FindObjectsOfType<GameObject>();
foreach (GameObject val in array)
{
Scene scene = val.scene;
if (((Scene)(ref scene)).name == sceneName)
{
list.Add(val);
}
}
return list;
}
public static List<GameObject> ChildrenList(this GameObject from)
{
List<GameObject> list = new List<GameObject>();
for (int i = 0; i < from.transform.childCount; i++)
{
list.Add(((Component)from.transform.GetChild(i)).gameObject);
}
return list;
}
public static bool Contains(this LayerMask mask, int layer)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
return LayerMask.op_Implicit(mask) == (LayerMask.op_Implicit(mask) | (1 << layer));
}
}
}
namespace AtlasLib.Style
{
public class Style
{
public readonly string Id;
public readonly string Name;
public readonly Color Colour = StyleColours.White;
public readonly float FreshnessDecayMultiplier = 1f;
public string FullString
{
get
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: 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)
if (Colour != StyleColours.White)
{
return "<color=" + ColorUtility.ToHtmlStringRGB(Colour) + ">" + Name + "</color>";
}
return Name;
}
}
public Style(string id, string name, float freshnessDecayMultiplier = 1f)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Id = id;
Name = name;
FreshnessDecayMultiplier = freshnessDecayMultiplier;
}
public Style(string id, string name, Color colour)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
Id = id;
Name = name;
Colour = colour;
}
public Style(string id, string name, float freshnessDecayMultiplier, Color colour)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: 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)
Id = id;
Name = name;
Colour = colour;
FreshnessDecayMultiplier = freshnessDecayMultiplier;
}
}
public static class StyleColours
{
public static Color Cyan => Color.cyan;
public static Color Gray => Color.grey;
public static Color Green => Color.green;
public static Color Orange => new Color(1f, 0.5f, 0f);
public static Color White => Color.white;
}
public static class StyleRegistry
{
private static List<Style> _styles = new List<Style>();
public static void Initialize()
{
Plugin.Harmony.PatchAll(typeof(StyleRegistry));
}
public static void Register(Style style)
{
_styles.Add(style);
}
[HarmonyPatch(typeof(StyleHUD), "Start")]
[HarmonyPostfix]
private static void AddCustomStyles(StyleHUD __instance)
{
foreach (Style style in _styles)
{
if (style.FreshnessDecayMultiplier != 1f)
{
__instance.freshnessDecayMultiplierDict.Add(style.Id, style.FreshnessDecayMultiplier);
}
__instance.RegisterStyleItem(style.Id, style.FullString);
}
}
}
}
namespace AtlasLib.Pages
{
internal class DefaultWeaponPage : Page
{
private static string[] _page1Content = new string[12]
{
"RevolverButton", "ShotgunButton", "NailgunButton", "RailcannonButton", "RocketLauncherButton", "ArmButton", "RevolverWindow", "ShotgunWindow", "NailgunWindow", "RailcannonWindow",
"RocketLauncherWindow", "ArmWindow"
};
public override void CreatePage(Transform parent)
{
base.CreatePage(parent);
string[] page1Content = _page1Content;
foreach (string name in page1Content)
{
Objects.Add(((Component)parent).gameObject.GetChild(name));
}
}
}
public abstract class Page
{
protected List<GameObject> Objects = new List<GameObject>();
private Dictionary<GameObject, bool> _state = new Dictionary<GameObject, bool>();
public virtual void CreatePage(Transform parent)
{
Objects.Clear();
_state.Clear();
}
public virtual void EnablePage()
{
foreach (GameObject @object in Objects)
{
@object.SetActive(_state[@object]);
}
}
public virtual void DisablePage()
{
foreach (GameObject @object in Objects)
{
_state[@object] = @object.activeSelf;
@object.SetActive(false);
}
}
}
public static class PageRegistry
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static UnityAction <>9__13_0;
public static UnityAction <>9__13_1;
internal void <ShopStart>b__13_0()
{
ButtonScroll(isLeft: true);
}
internal void <ShopStart>b__13_1()
{
ButtonScroll(isLeft: false);
}
}
private static GameObject _leftScrollButton;
private static GameObject _rightScrollButton;
public static int CurrentPage { get; private set; }
public static List<Page> Pages { get; } = new List<Page>();
internal static void Initialize()
{
Pages.Add(new DefaultWeaponPage());
Plugin.Harmony.PatchAll(typeof(PageRegistry));
}
public static void Register(Page page, int at = -1)
{
if (at == -1)
{
Pages.Add(page);
}
else
{
Pages.Insert(at, page);
}
}
public static void RefreshPages(int changedBy)
{
if (Pages.Count == 0)
{
_leftScrollButton.SetActive(false);
_leftScrollButton.SetActive(true);
return;
}
Pages[CurrentPage].EnablePage();
if (changedBy != 0)
{
Pages[CurrentPage - changedBy].DisablePage();
}
}
public static void ButtonScroll(bool isLeft)
{
if (isLeft)
{
if (CurrentPage > 0)
{
CurrentPage--;
RefreshPages(-1);
}
}
else if (CurrentPage < Pages.Count - 1)
{
CurrentPage++;
RefreshPages(1);
}
}
[HarmonyPatch(typeof(ShopZone), "Start")]
[HarmonyPostfix]
private static void ShopStart(ShopZone __instance)
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Expected O, but got Unknown
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Expected O, but got Unknown
if (!((Object)(object)((Component)__instance).gameObject.GetChild("Canvas")?.GetChild("Weapons") != (Object)null))
{
return;
}
GameObject child = ((Component)__instance).gameObject.GetChild("Canvas/Weapons/BackButton (1)");
ShopButton component = child.GetComponent<ShopButton>();
component.toActivate = Array.Empty<GameObject>();
component.toDeactivate = Array.Empty<GameObject>();
_leftScrollButton = Object.Instantiate<GameObject>(child, child.transform.parent);
RectTransform component2 = _leftScrollButton.GetComponent<RectTransform>();
component2.sizeDelta -= new Vector2(component2.sizeDelta.x / 2f, 0f);
_leftScrollButton.transform.localPosition = new Vector3(-220f, -145f, -45f);
_rightScrollButton = Object.Instantiate<GameObject>(_leftScrollButton, child.transform.parent);
_rightScrollButton.transform.localPosition = new Vector3(-140f, -145f, -45f);
_leftScrollButton.GetComponentInChildren<TMP_Text>().text = "<<";
((Transform)_leftScrollButton.GetComponent<RectTransform>()).SetAsFirstSibling();
ButtonClickedEvent onClick = _leftScrollButton.GetComponentInChildren<Button>().onClick;
object obj = <>c.<>9__13_0;
if (obj == null)
{
UnityAction val = delegate
{
ButtonScroll(isLeft: true);
};
<>c.<>9__13_0 = val;
obj = (object)val;
}
((UnityEvent)onClick).AddListener((UnityAction)obj);
_rightScrollButton.GetComponentInChildren<TMP_Text>().text = ">>";
((Transform)_rightScrollButton.GetComponent<RectTransform>()).SetAsFirstSibling();
ButtonClickedEvent onClick2 = _rightScrollButton.GetComponentInChildren<Button>().onClick;
object obj2 = <>c.<>9__13_1;
if (obj2 == null)
{
UnityAction val2 = delegate
{
ButtonScroll(isLeft: false);
};
<>c.<>9__13_1 = val2;
obj2 = (object)val2;
}
((UnityEvent)onClick2).AddListener((UnityAction)obj2);
CurrentPage = 0;
foreach (Page page in Pages)
{
page.CreatePage(((Component)__instance).gameObject.GetChild("Canvas/Weapons").transform);
if (page.GetType() != typeof(DefaultWeaponPage))
{
page.DisablePage();
}
}
}
[HarmonyPatch(typeof(ShopZone), "TurnOn")]
[HarmonyPostfix]
private static void RefreshOnEntrance()
{
RefreshPages(0);
}
}
}