Decompiled source of UESDrifter v1.0.2

plugins/UESDrifter.dll

Decompiled 2 hours ago
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 BepInEx;
using EntityStates;
using EntityStates.Drone;
using HarmonyLib;
using JetBrains.Annotations;
using RoR2;
using RoR2.ContentManagement;
using RoR2.Modding;
using RoR2.Networking;
using RoR2.Skills;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
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: AssemblyVersion("0.0.0.0")]
namespace DrifterUES;

public sealed class DeferredFabricatorSkillDef : DrifterSkillDef
{
	public override bool IsReady([NotNull] GenericSkill skillSlot)
	{
		return FabricationService.HasAvailableFabricationRecipe() && ((DrifterSkillDef)this).IsReady(skillSlot);
	}

	public override bool CanExecute([NotNull] GenericSkill skillSlot)
	{
		return FabricationService.HasAvailableFabricationRecipe() && ((DrifterSkillDef)this).CanExecute(skillSlot);
	}

	public override void OnExecute([NotNull] GenericSkill skillSlot)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		skillSlot.stateMachine.SetInterruptState(((SkillDef)this).InstantiateNextState(skillSlot), ((SkillDef)this).interruptPriority);
		if (((SkillDef)this).cancelSprintingOnActivation)
		{
			skillSlot.characterBody.isSprinting = false;
		}
		if (((SkillDef)this).resetCooldownTimerOnUse)
		{
			skillSlot.rechargeStopwatch = 0f;
		}
		CharacterBody characterBody = skillSlot.characterBody;
		if (characterBody != null)
		{
			characterBody.OnSkillActivated(skillSlot);
		}
	}
}
internal static class FabricationMenu
{
	internal enum Mode
	{
		Fabricator,
		Nanobot
	}

	private static GameObject activeMenuRoot;

	private static bool menuOpening;

	internal static bool IsOpen => Object.op_Implicit((Object)(object)activeMenuRoot);

	internal static void Open(Mode mode, CharacterBody owner)
	{
		if (!((Object)(object)owner == (Object)null) && owner.hasEffectiveAuthority && !menuOpening && !Object.op_Implicit((Object)(object)activeMenuRoot))
		{
			menuOpening = true;
			((MonoBehaviour)Plugin.Instance).StartCoroutine(OpenWhenUiReady(mode, owner));
		}
	}

	private static IEnumerator OpenWhenUiReady(Mode mode, CharacterBody owner)
	{
		LocalUser user = null;
		HUD hud = null;
		for (int frame = 0; frame < 30; frame++)
		{
			if ((Object)(object)owner == (Object)null || !owner.hasEffectiveAuthority)
			{
				menuOpening = false;
				yield break;
			}
			user = ((IEnumerable<LocalUser>)LocalUserManager.readOnlyLocalUsersList).FirstOrDefault((Func<LocalUser, bool>)((LocalUser candidate) => (Object)(object)candidate.cachedBody == (Object)(object)owner));
			hud = ((IEnumerable<HUD>)HUD.readOnlyInstanceList).FirstOrDefault((Func<HUD, bool>)((HUD candidate) => candidate.localUserViewer == user));
			if (user != null && (Object)(object)user.eventSystem != (Object)null && (Object)(object)hud != (Object)null)
			{
				break;
			}
			yield return null;
		}
		menuOpening = false;
		if (user != null && !((Object)(object)user.eventSystem == (Object)null) && !((Object)(object)hud == (Object)null) && !Object.op_Implicit((Object)(object)activeMenuRoot))
		{
			GameObject root = (activeMenuRoot = CreateMenuRoot(user, hud, (mode == Mode.Fabricator) ? "UES FABRICATOR" : "NANOBOT UPGRADES"));
			PauseManager.ClosePauseScreen(true);
			if (mode == Mode.Fabricator)
			{
				ConfigureFabricator(root, owner);
			}
			else
			{
				ConfigureNanobots(root, owner);
			}
			AddResourceSummary(root, owner);
		}
	}

	private static GameObject CreateMenuRoot(LocalUser user, HUD hud, string title)
	{
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: 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)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_032c: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		//IL_034a: Unknown result type (might be due to invalid IL or missing references)
		//IL_034f: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0382: Unknown result type (might be due to invalid IL or missing references)
		//IL_038c: Expected O, but got Unknown
		//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cd: Expected O, but got Unknown
		//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Expected O, but got Unknown
		GameObject val = new GameObject("UESDrifterSelectionMenu", new Type[7]
		{
			typeof(RectTransform),
			typeof(Canvas),
			typeof(CanvasScaler),
			typeof(GraphicRaycaster),
			typeof(MPEventSystemProvider),
			typeof(MPEventSystemLocator),
			typeof(CursorOpener)
		});
		Canvas component = val.GetComponent<Canvas>();
		component.renderMode = (RenderMode)0;
		component.sortingOrder = 100;
		val.GetComponent<CanvasScaler>().uiScaleMode = (ScaleMode)1;
		val.GetComponent<CanvasScaler>().referenceResolution = new Vector2(1920f, 1080f);
		val.GetComponent<MPEventSystemProvider>().eventSystem = user.eventSystem;
		val.GetComponent<CursorOpener>().forceCursorForGamePad = true;
		Image val2 = val.AddComponent<Image>();
		((Graphic)val2).color = new Color(0f, 0.02f, 0.05f, 0.88f);
		Transform val3 = CreateChild(val.transform, "Panel", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(860f, 760f));
		Image val4 = ((Component)val3).gameObject.AddComponent<Image>();
		((Graphic)val4).color = new Color(0.06f, 0.11f, 0.16f, 0.98f);
		CreateText(val3, "Title", title, 32f, (TextAlignmentOptions)514, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -38f), new Vector2(-40f, 52f), hud);
		CreateText(val3, "Hint", "Select a target. Costs are charged only after server confirmation.", 17f, (TextAlignmentOptions)514, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -76f), new Vector2(-40f, 28f), hud);
		CreateCloseButton(val3, hud, val);
		Transform val5 = CreateChild(val3, "SelectionScroll", new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, -70f), new Vector2(-44f, -166f));
		ScrollRect val6 = ((Component)val5).gameObject.AddComponent<ScrollRect>();
		Transform val7 = CreateChild(val5, "Viewport", Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, Vector2.zero);
		((Graphic)((Component)val7).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.18f);
		((Component)val7).gameObject.AddComponent<Mask>().showMaskGraphic = true;
		Transform val8 = CreateChild(val7, "Content", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), Vector2.zero, new Vector2(0f, 0f));
		VerticalLayoutGroup val9 = ((Component)val8).gameObject.AddComponent<VerticalLayoutGroup>();
		((LayoutGroup)val9).padding = new RectOffset(14, 14, 14, 14);
		((HorizontalOrVerticalLayoutGroup)val9).spacing = 8f;
		((HorizontalOrVerticalLayoutGroup)val9).childControlHeight = true;
		((HorizontalOrVerticalLayoutGroup)val9).childForceExpandHeight = false;
		((Component)val8).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
		val6.viewport = (RectTransform)val7;
		val6.content = (RectTransform)val8;
		val6.horizontal = false;
		val6.vertical = true;
		val6.scrollSensitivity = 30f;
		return val;
	}

	private static void ConfigureFabricator(GameObject root, CharacterBody owner)
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		Transform parent = root.transform.Find("Panel/SelectionScroll/Viewport/Content");
		JunkController component = ((Component)owner).GetComponent<JunkController>();
		int num = FabricationService.CountActiveFabricatedDrones(owner.master);
		bool flag = num >= 8;
		CreateText(root.transform.Find("Panel"), "FabricatedDroneCount", "Fabricated Drones: " + num + " / " + 8, 17f, (TextAlignmentOptions)514, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -128f), new Vector2(-40f, 28f), null);
		foreach (DroneRecipe recipe in UesRecipes.Fabrication)
		{
			DroneDef val = recipe.drone();
			if (!((Object)(object)val == (Object)null))
			{
				bool enabled = !flag && FabricationService.CanPay(owner.inventory, component, recipe.cost);
				string label = recipe.displayName + "  •  Tier " + recipe.fabricationTier + "\n" + CostText(recipe.cost) + (flag ? "  (8 drone limit reached)" : string.Empty);
				CreateSelectionButton(parent, val.iconSprite, label, enabled, delegate
				{
					UesNetwork.SendFabrication(recipe.id);
					Close(root);
				});
			}
		}
	}

	private static void ConfigureNanobots(GameObject root, CharacterBody owner)
	{
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
		Transform parent = root.transform.Find("Panel/SelectionScroll/Viewport/Content");
		CharacterMaster master = owner.master;
		JunkController component = ((Component)owner).GetComponent<JunkController>();
		bool flag = NanobotUpgradeService.CountActiveNanobotUpgrades(master) >= 2;
		bool flag2 = false;
		foreach (CharacterMaster drone in GetEligibleDrones(master))
		{
			flag2 = true;
			bool flag3 = NanobotUpgradeService.IsNanobotActive(drone);
			int num = 1 + drone.inventory.GetItemCountPermanent(Items.DroneUpgradeHidden) - (flag3 ? 1 : 0);
			ResourceCost cost = NanobotUpgradeService.CostForPermanentTier(num);
			bool enabled = !flag3 && !flag && FabricationService.CanPay(owner.inventory, component, cost);
			CharacterBody body = drone.GetBody();
			DroneDef droneDef = DroneCatalog.GetDroneDef(DroneCatalog.GetDroneIndexFromBodyIndex(body.bodyIndex));
			string text = (((Object)(object)droneDef != (Object)null && !Language.IsTokenInvalid(droneDef.nameToken)) ? Language.GetString(droneDef.nameToken) : body.GetDisplayName());
			string label = text + "  •  Tier " + num + " → " + (num + 1) + "\n" + CostText(cost) + (flag3 ? "  (already upgraded)" : (flag ? "  (2 upgrade limit reached)" : string.Empty));
			CreateSelectionButton(parent, ((Object)(object)droneDef != (Object)null) ? droneDef.iconSprite : null, label, enabled, delegate
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				UesNetwork.SendNanobot(((NetworkBehaviour)drone).netId);
				Close(root);
			});
		}
		if (!flag2)
		{
			CreateText(parent, "Empty", "No eligible allied drones are currently owned by this player.", 20f, (TextAlignmentOptions)514, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(0f, 90f), null);
		}
	}

	private static IEnumerable<CharacterMaster> GetEligibleDrones(CharacterMaster owner)
	{
		MinionGroup group = (((Object)(object)owner != (Object)null) ? MinionGroup.FindGroup(((NetworkBehaviour)owner).netId) : null);
		if (group == null)
		{
			yield break;
		}
		MinionOwnership[] members = group.members;
		foreach (MinionOwnership member in members)
		{
			CharacterMaster master = (Object.op_Implicit((Object)(object)member) ? ((Component)member).GetComponent<CharacterMaster>() : null);
			if ((Object)(object)master != (Object)null && (NanobotUpgradeService.IsEligible(owner, master) || NanobotUpgradeService.IsNanobotActive(master)))
			{
				yield return master;
			}
		}
	}

	private static void CreateSelectionButton(Transform parent, Sprite icon, string label, bool enabled, Action onClick)
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Expected O, but got Unknown
		//IL_00f4: 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_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("DroneOption", new Type[4]
		{
			typeof(RectTransform),
			typeof(Image),
			typeof(Button),
			typeof(LayoutElement)
		});
		val.transform.SetParent(parent, false);
		val.GetComponent<LayoutElement>().preferredHeight = 82f;
		Image component = val.GetComponent<Image>();
		((Graphic)component).color = (enabled ? new Color(0.12f, 0.24f, 0.31f, 1f) : new Color(0.09f, 0.09f, 0.09f, 1f));
		Button component2 = val.GetComponent<Button>();
		((Selectable)component2).interactable = enabled;
		((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
		{
			onClick();
		});
		Transform val2 = CreateChild(val.transform, "Icon", new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(50f, 0f), new Vector2(60f, 60f));
		Image val3 = ((Component)val2).gameObject.AddComponent<Image>();
		val3.sprite = icon;
		val3.preserveAspect = true;
		((Graphic)val3).color = (Color)(enabled ? Color.white : new Color(0.35f, 0.35f, 0.35f, 1f));
		CreateText(val.transform, "Text", label, 19f, (TextAlignmentOptions)513, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 0.5f), new Vector2(94f, 0f), new Vector2(-110f, -10f), null);
	}

	private static void CreateCloseButton(Transform parent, HUD hud, GameObject root)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Expected O, but got Unknown
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Close", new Type[3]
		{
			typeof(RectTransform),
			typeof(Image),
			typeof(Button)
		});
		val.transform.SetParent(parent, false);
		RectTransform val2 = (RectTransform)val.transform;
		Vector2 val3 = default(Vector2);
		((Vector2)(ref val3))..ctor(1f, 1f);
		val2.anchorMax = val3;
		val2.anchorMin = val3;
		val2.pivot = new Vector2(1f, 1f);
		val2.anchoredPosition = new Vector2(-16f, -14f);
		val2.sizeDelta = new Vector2(118f, 38f);
		((Graphic)val.GetComponent<Image>()).color = new Color(0.35f, 0.12f, 0.12f, 1f);
		((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
		{
			Close(root);
		});
		CreateText(val.transform, "Text", "CANCEL", 18f, (TextAlignmentOptions)514, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(-4f, -4f), hud);
	}

	private static Transform CreateChild(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 anchoredPosition, Vector2 size)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		RectTransform val2 = (RectTransform)val.transform;
		val2.anchorMin = anchorMin;
		val2.anchorMax = anchorMax;
		val2.pivot = pivot;
		val2.anchoredPosition = anchoredPosition;
		val2.sizeDelta = size;
		return val.transform;
	}

	private static TextMeshProUGUI CreateText(Transform parent, string name, string value, float size, TextAlignmentOptions alignment, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 anchoredPosition, Vector2 dimensions, HUD hud)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: 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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		Transform val = CreateChild(parent, name, anchorMin, anchorMax, pivot, anchoredPosition, dimensions);
		TextMeshProUGUI val2 = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>();
		object font;
		if (!((Object)(object)hud != (Object)null))
		{
			font = TMP_Settings.defaultFontAsset;
		}
		else
		{
			TextMeshProUGUI componentInChildren = ((Component)hud).GetComponentInChildren<TextMeshProUGUI>(true);
			font = ((componentInChildren != null) ? ((TMP_Text)componentInChildren).font : null);
		}
		((TMP_Text)val2).font = (TMP_FontAsset)font;
		((TMP_Text)val2).text = value;
		((TMP_Text)val2).fontSize = size;
		((TMP_Text)val2).alignment = alignment;
		((TMP_Text)val2).enableWordWrapping = true;
		((Graphic)val2).color = Color.white;
		return val2;
	}

	private static void Close(GameObject root)
	{
		if ((Object)(object)activeMenuRoot == (Object)(object)root)
		{
			activeMenuRoot = null;
		}
		Object.Destroy((Object)(object)root);
	}

	private static void AddResourceSummary(GameObject menuRoot, CharacterBody owner)
	{
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		Inventory val = (((Object)(object)owner != (Object)null) ? owner.inventory : null);
		if (!((Object)(object)val == (Object)null))
		{
			JunkController component = ((Component)owner).GetComponent<JunkController>();
			string value = "Resources: " + (((Object)(object)component != (Object)null) ? component.CurrentJunk : 0f) + " Junk  |  " + val.GetItemCountPermanent(Items.ScrapWhite.itemIndex) + " White  |  " + val.GetItemCountPermanent(Items.ScrapGreen.itemIndex) + " Green  |  " + val.GetItemCountPermanent(Items.ScrapRed.itemIndex) + " Red Scrap";
			CreateText(menuRoot.transform.Find("Panel"), "Resources", value, 17f, (TextAlignmentOptions)514, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -104f), new Vector2(-40f, 28f), null);
		}
	}

	private static string CostText(ResourceCost cost)
	{
		string text = cost.junk + " Junk";
		if (cost.whiteScrap > 0)
		{
			text = text + ", " + cost.whiteScrap + " White Scrap";
		}
		if (cost.greenScrap > 0)
		{
			text = text + ", " + cost.greenScrap + " Green Scrap";
		}
		if (cost.redScrap > 0)
		{
			text = text + ", " + cost.redScrap + " Red Scrap";
		}
		return text;
	}
}
internal static class UesNetwork
{
	internal enum SelectionKind : byte
	{
		Fabricator = 1,
		Nanobot
	}

	internal sealed class SelectionMessage : MessageBase
	{
		public SelectionKind kind;

		public byte recipeId;

		public NetworkInstanceId targetMasterId;

		public override void Serialize(NetworkWriter writer)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			writer.Write((byte)kind);
			writer.Write(recipeId);
			writer.Write(targetMasterId);
		}

		public override void Deserialize(NetworkReader reader)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			kind = (SelectionKind)reader.ReadByte();
			recipeId = reader.ReadByte();
			targetMasterId = reader.ReadNetworkId();
		}
	}

	internal const short SelectionMessageType = 151;

	internal static void SendFabrication(byte recipeId)
	{
		Send(new SelectionMessage
		{
			kind = SelectionKind.Fabricator,
			recipeId = recipeId
		});
	}

	internal static void SendNanobot(NetworkInstanceId targetMasterId)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		Send(new SelectionMessage
		{
			kind = SelectionKind.Nanobot,
			targetMasterId = targetMasterId
		});
	}

	private static void Send(SelectionMessage message)
	{
		NetworkClient val = (((Object)(object)NetworkManagerSystem.singleton != (Object)null) ? ((NetworkManager)NetworkManagerSystem.singleton).client : null);
		if (val != null && val.connection != null)
		{
			val.connection.Send((short)151, (MessageBase)(object)message);
		}
	}

	internal static void HandleSelection(NetworkMessage netMessage)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		if (!NetworkServer.active)
		{
			return;
		}
		CharacterMaster senderMaster = GetSenderMaster(netMessage.conn);
		if ((Object)(object)senderMaster == (Object)null)
		{
			Debug.LogWarning((object)"[UES Drifter] Rejected selection: could not resolve the requesting player's CharacterMaster.");
			return;
		}
		SelectionMessage selectionMessage = netMessage.ReadMessage<SelectionMessage>();
		bool flag = false;
		switch (selectionMessage.kind)
		{
		case SelectionKind.Fabricator:
			flag = FabricationService.TryFabricate(senderMaster, selectionMessage.recipeId);
			break;
		case SelectionKind.Nanobot:
			flag = NanobotUpgradeService.TryUpgrade(senderMaster, selectionMessage.targetMasterId);
			break;
		}
		if (!flag)
		{
			Debug.LogWarning((object)("[UES Drifter] Server rejected selection kind=" + selectionMessage.kind.ToString() + ". Resources were not consumed."));
		}
	}

	private static CharacterMaster GetSenderMaster(NetworkConnection connection)
	{
		if (connection == null || connection.playerControllers.Count == 0)
		{
			return null;
		}
		GameObject gameObject = connection.playerControllers[0].gameObject;
		if (!Object.op_Implicit((Object)(object)gameObject))
		{
			return null;
		}
		CharacterMaster component = gameObject.GetComponent<CharacterMaster>();
		if ((Object)(object)component != (Object)null)
		{
			return component;
		}
		NetworkUser component2 = gameObject.GetComponent<NetworkUser>();
		if ((Object)(object)component2 != (Object)null && Object.op_Implicit((Object)(object)component2.masterObject))
		{
			return component2.masterObject.GetComponent<CharacterMaster>();
		}
		PlayerCharacterMasterController component3 = gameObject.GetComponent<PlayerCharacterMasterController>();
		return ((Object)(object)component3 != (Object)null) ? component3.master : null;
	}
}
internal static class SelectionAuthority
{
	internal enum Kind
	{
		Fabricator,
		Nanobot
	}

	private sealed class Window
	{
		internal Kind kind;

		internal float expiresAt;
	}

	private static readonly Dictionary<NetworkInstanceId, Window> windows = new Dictionary<NetworkInstanceId, Window>();

	internal static void Open(CharacterBody body, Kind kind)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		if (NetworkServer.active && !((Object)(object)body == (Object)null) && !((Object)(object)body.master == (Object)null) && IsCorrectVariant(body, kind) && (kind != Kind.Fabricator || (!((Object)(object)body.skillLocator == (Object)null) && body.skillLocator.secondary.stock >= 1)))
		{
			windows[((NetworkBehaviour)body.master).netId] = new Window
			{
				kind = kind,
				expiresAt = FixedTimeStamp.now.t + 12f
			};
		}
	}

	internal static bool Consume(CharacterMaster master, Kind kind, out CharacterBody body)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		body = (((Object)(object)master != (Object)null) ? master.GetBody() : null);
		if ((Object)(object)body == (Object)null || !IsCorrectVariant(body, kind) || !windows.TryGetValue(((NetworkBehaviour)master).netId, out var value))
		{
			return false;
		}
		if (value.kind != kind || FixedTimeStamp.now.t > value.expiresAt)
		{
			windows.Remove(((NetworkBehaviour)master).netId);
			return false;
		}
		windows.Remove(((NetworkBehaviour)master).netId);
		return true;
	}

	private static bool IsCorrectVariant(CharacterBody body, Kind kind)
	{
		if ((Object)(object)body == (Object)null || (Object)(object)((Component)body).GetComponent<JunkController>() == (Object)null || (Object)(object)body.skillLocator == (Object)null)
		{
			return false;
		}
		return (kind == Kind.Fabricator) ? ((Object)(object)body.skillLocator.secondary.skillDef == (Object)(object)Plugin.FabricatorSkill) : ((Object)(object)body.skillLocator.special.skillDef == (Object)(object)Plugin.NanobotSkill);
	}
}
internal static class FabricationService
{
	internal const int MaxActiveFabricatedDrones = 8;

	internal static bool HasAvailableFabricationRecipe()
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Run.instance == (Object)null || (Object)(object)VoidStageMissionController.instance != (Object)null)
		{
			return false;
		}
		SceneDef val = (((Object)(object)SceneInfo.instance != (Object)null) ? SceneInfo.instance.sceneDef : null);
		if ((Object)(object)val != (Object)null && val.suppressNpcEntry)
		{
			return false;
		}
		foreach (DroneRecipe item in UesRecipes.Fabrication)
		{
			DroneDef val2 = item.drone();
			if ((Object)(object)val2 != (Object)null && Run.instance.IsDroneAvailable(val2.droneIndex))
			{
				return true;
			}
		}
		return false;
	}

	internal static bool TryFabricate(CharacterMaster playerMaster, byte recipeId)
	{
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		if (!NetworkServer.active || !SelectionAuthority.Consume(playerMaster, SelectionAuthority.Kind.Fabricator, out var body))
		{
			return false;
		}
		if (!HasAvailableFabricationRecipe() || !UesRecipes.TryGet(recipeId, out var recipe))
		{
			return false;
		}
		DroneDef val = recipe.drone();
		JunkController component = ((Component)body).GetComponent<JunkController>();
		if ((Object)(object)val == (Object)null || (Object)(object)val.masterPrefab == (Object)null || (Object)(object)component == (Object)null)
		{
			return false;
		}
		if ((Object)(object)Run.instance == (Object)null || !Run.instance.IsDroneAvailable(val.droneIndex))
		{
			return false;
		}
		if ((Object)(object)body.skillLocator == (Object)null || body.skillLocator.secondary.stock < 1 || CountActiveFabricatedDrones(playerMaster) >= 8)
		{
			return false;
		}
		ResourceCost cost = recipe.cost;
		if (!CanPay(playerMaster.inventory, component, cost))
		{
			return false;
		}
		Pay(playerMaster.inventory, component, cost);
		CharacterMaster val2 = new MasterSummon
		{
			masterPrefab = val.masterPrefab,
			position = body.corePosition + ((Component)body).transform.forward * 3f,
			rotation = ((Component)body).transform.rotation,
			summonerBodyObject = ((Component)body).gameObject,
			ignoreTeamMemberLimit = true,
			useAmbientLevel = true,
			enablePrintController = true
		}.Perform();
		if ((Object)(object)val2 == (Object)null)
		{
			Refund(playerMaster.inventory, cost);
			playerMaster.inventory.GiveItemPermanent(Items.Junk, cost.junk);
			return false;
		}
		if (recipe.fabricationTier > 1 && (Object)(object)val2.inventory != (Object)null)
		{
			val2.inventory.GiveItemPermanent(Items.DroneUpgradeHidden, recipe.fabricationTier - 1);
		}
		UESFabricatedDrone uESFabricatedDrone = ((Component)val2).gameObject.AddComponent<UESFabricatedDrone>();
		uESFabricatedDrone.permanentTier = recipe.fabricationTier;
		uESFabricatedDrone.ownerMasterNetId = ((NetworkBehaviour)playerMaster).netId;
		StartFabricatorCooldown(body);
		return true;
	}

	internal static int CountActiveFabricatedDrones(CharacterMaster owner)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		MinionGroup val = (((Object)(object)owner != (Object)null) ? MinionGroup.FindGroup(((NetworkBehaviour)owner).netId) : null);
		if (val == null)
		{
			return 0;
		}
		int num = 0;
		MinionOwnership[] members = val.members;
		foreach (MinionOwnership val2 in members)
		{
			CharacterMaster val3 = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).GetComponent<CharacterMaster>() : null);
			UESFabricatedDrone uESFabricatedDrone = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<UESFabricatedDrone>() : null);
			if ((Object)(object)val3 != (Object)null && (Object)(object)val3.GetBody() != (Object)null && (Object)(object)uESFabricatedDrone != (Object)null && uESFabricatedDrone.ownerMasterNetId == ((NetworkBehaviour)owner).netId)
			{
				num++;
			}
		}
		return num;
	}

	private static void StartFabricatorCooldown(CharacterBody playerBody)
	{
		GenericSkill val = (((Object)(object)playerBody != (Object)null && (Object)(object)playerBody.skillLocator != (Object)null) ? playerBody.skillLocator.secondary : null);
		if (!((Object)(object)val == (Object)null))
		{
			val.stock = 0;
			val.rechargeStopwatch = 0f;
			playerBody.OnSkillCooldown(val, 1);
		}
	}

	internal static bool CanPay(Inventory inventory, JunkController junk, ResourceCost cost)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		return (Object)(object)inventory != (Object)null && (Object)(object)junk != (Object)null && junk.CanAfford(cost.junk) && inventory.GetItemCountPermanent(Items.ScrapWhite.itemIndex) >= cost.whiteScrap && inventory.GetItemCountPermanent(Items.ScrapGreen.itemIndex) >= cost.greenScrap && inventory.GetItemCountPermanent(Items.ScrapRed.itemIndex) >= cost.redScrap;
	}

	internal static void Pay(Inventory inventory, JunkController junk, ResourceCost cost)
	{
		junk.ConsumeJunk(cost.junk);
		if (cost.whiteScrap > 0)
		{
			inventory.RemoveItemPermanent(Items.ScrapWhite, cost.whiteScrap);
		}
		if (cost.greenScrap > 0)
		{
			inventory.RemoveItemPermanent(Items.ScrapGreen, cost.greenScrap);
		}
		if (cost.redScrap > 0)
		{
			inventory.RemoveItemPermanent(Items.ScrapRed, cost.redScrap);
		}
	}

	private static void Refund(Inventory inventory, ResourceCost cost)
	{
		if (cost.whiteScrap > 0)
		{
			inventory.GiveItemPermanent(Items.ScrapWhite, cost.whiteScrap);
		}
		if (cost.greenScrap > 0)
		{
			inventory.GiveItemPermanent(Items.ScrapGreen, cost.greenScrap);
		}
		if (cost.redScrap > 0)
		{
			inventory.GiveItemPermanent(Items.ScrapRed, cost.redScrap);
		}
	}
}
public sealed class UESFabricatedDrone : MonoBehaviour
{
	public int permanentTier = 1;

	public NetworkInstanceId ownerMasterNetId;
}
public sealed class NanobotTemporaryUpgrade : MonoBehaviour
{
	public int addedStacks = 1;
}
internal sealed class HoarderEfficiencyRemainder : MonoBehaviour
{
	internal float extraJunkRemainder;
}
internal static class HoarderEfficiencyService
{
	private const float WhiteScrapChance = 0.05f;

	private const float GreenScrapChance = 0.01f;

	private const float RedScrapChance = 0.005f;

	private const float YellowScrapChance = 0.001f;

	private const float MinimumScrapChance = 0.0001f;

	internal static bool IsActive(CharacterBody body)
	{
		return (Object)(object)body != (Object)null && (Object)(object)body.skillLocator != (Object)null && (Object)(object)body.skillLocator.secondary != (Object)null && (Object)(object)body.skillLocator.secondary.skillDef == (Object)(object)Plugin.FabricatorSkill;
	}

	internal static int ProcessJunkGeneration(JunkController controller, int quantity)
	{
		if (!NetworkServer.active || (Object)(object)controller == (Object)null || quantity <= 0 || !IsActive(((Component)controller).GetComponent<CharacterBody>()))
		{
			return quantity;
		}
		CharacterBody component = ((Component)controller).GetComponent<CharacterBody>();
		int num = Mathf.Max(0, 8 - FabricationService.CountActiveFabricatedDrones(component.master)) / 2;
		float num2 = 1f + 0.25f * (float)num;
		HoarderEfficiencyRemainder hoarderEfficiencyRemainder = ((Component)controller).GetComponent<HoarderEfficiencyRemainder>() ?? ((Component)controller).gameObject.AddComponent<HoarderEfficiencyRemainder>();
		float num3 = (float)quantity * num2 + hoarderEfficiencyRemainder.extraJunkRemainder;
		int num4 = Mathf.FloorToInt(num3);
		hoarderEfficiencyRemainder.extraJunkRemainder = num3 - (float)num4;
		quantity = Mathf.Max(quantity, num4);
		if (controller.CurrentJunk < (float)controller.MaxJunk || (Object)(object)component.inventory == (Object)null)
		{
			return quantity;
		}
		for (int num5 = quantity - 1; num5 >= 0; num5--)
		{
			float num6 = AdjustedChance(component.inventory, Items.ScrapWhite, 0.05f);
			float num7 = AdjustedChance(component.inventory, Items.ScrapGreen, 0.01f);
			float num8 = AdjustedChance(component.inventory, Items.ScrapRed, 0.005f);
			float num9 = AdjustedChance(component.inventory, Items.ScrapYellow, 0.001f);
			float value = Random.value;
			ItemDef val = ((value < num6) ? Items.ScrapWhite : ((value < num6 + num7) ? Items.ScrapGreen : ((value < num6 + num7 + num8) ? Items.ScrapRed : ((value < num6 + num7 + num8 + num9) ? Items.ScrapYellow : null))));
			if ((Object)(object)val != (Object)null)
			{
				component.inventory.GiveItemPermanent(val, 1);
				quantity--;
			}
		}
		return quantity;
	}

	private static float AdjustedChance(Inventory inventory, ItemDef scrap, float baseChance)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		int itemCountPermanent = inventory.GetItemCountPermanent(scrap.itemIndex);
		return Mathf.Max(0.0001f, baseChance * Mathf.Max(0.05f, 1f - (float)itemCountPermanent * (19f / 120f)));
	}

	internal static float GetFabricatedDroneCooldownMultiplier(GenericSkill skill)
	{
		CharacterBody val = (((Object)(object)skill != (Object)null) ? skill.characterBody : null);
		CharacterMaster val2 = (((Object)(object)val != (Object)null) ? val.master : null);
		if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponent<UESFabricatedDrone>() == (Object)null || (Object)(object)val2.minionOwnership == (Object)null)
		{
			return 1f;
		}
		CharacterMaster ownerMaster = val2.minionOwnership.ownerMaster;
		CharacterBody val3 = ((ownerMaster != null) ? ownerMaster.GetBody() : null);
		JunkController val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<JunkController>() : null);
		if (!IsActive(val3) || (Object)(object)val4 == (Object)null)
		{
			return 1f;
		}
		float num = Mathf.Min(0.4f, (float)Mathf.FloorToInt(val4.CurrentJunk / 4f) * 0.1f);
		return 1f - num;
	}

	internal static bool IsFabricatedDroneSkill(GenericSkill skill)
	{
		CharacterBody val = (((Object)(object)skill != (Object)null) ? skill.characterBody : null);
		return (Object)(object)val != (Object)null && (Object)(object)val.master != (Object)null && (Object)(object)((Component)val.master).GetComponent<UESFabricatedDrone>() != (Object)null;
	}
}
internal sealed class HoarderPassiveDisplay : MonoBehaviour
{
	private CharacterBody characterBody;

	private JunkController junkController;

	private int originalMaxJunk;

	private int appliedMaxJunk = -1;

	private bool fabricatorActive;

	private int observedJunk = -1;

	private void Awake()
	{
		characterBody = ((Component)this).GetComponent<CharacterBody>();
		junkController = ((Component)this).GetComponent<JunkController>();
		if ((Object)(object)junkController != (Object)null)
		{
			originalMaxJunk = junkController.MaxJunk;
		}
	}

	private void Update()
	{
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		bool flag = HoarderEfficiencyService.IsActive(characterBody);
		int num = (flag ? 20 : originalMaxJunk);
		if ((Object)(object)junkController == (Object)null)
		{
			return;
		}
		if (appliedMaxJunk != num)
		{
			junkController.MaxJunk = num;
			appliedMaxJunk = num;
			CharacterBody component = ((Component)junkController).GetComponent<CharacterBody>();
			if (NetworkServer.active && (Object)(object)component != (Object)null && (Object)(object)component.inventory != (Object)null)
			{
				component.inventory.EnforceItemStackLimit(Items.Junk.itemIndex, num);
			}
		}
		int num2 = Mathf.RoundToInt(junkController.CurrentJunk);
		if (fabricatorActive != flag || observedJunk != num2)
		{
			fabricatorActive = flag;
			observedJunk = num2;
			characterBody.RecalculateStats();
		}
	}
}
internal static class JunkPatchTrashToTreasureService
{
	internal static void Apply(CharacterBody source, CharacterBody target)
	{
		if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null) && !((Object)(object)source.inventory == (Object)null))
		{
			Refresh(target, Buffs.TrashToTreasureWhite, source.inventory.GetItemCountEffective(Items.ScrapWhite));
			Refresh(target, Buffs.TrashToTreasureGreen, source.inventory.GetItemCountEffective(Items.ScrapGreen) + source.inventory.GetItemCountEffective(Items.RegeneratingScrap));
			Refresh(target, Buffs.TrashToTreasureRed, source.inventory.GetItemCountEffective(Items.ScrapRed));
			Refresh(target, Buffs.TrashToTreasureYellow, source.inventory.GetItemCountEffective(Items.ScrapYellow));
		}
	}

	private static void Refresh(CharacterBody target, BuffDef buff, int count)
	{
		target.ClearTimedBuffs(buff);
		for (int i = 0; i < count; i++)
		{
			target.AddTimedBuff(buff, 10f);
		}
	}
}
internal sealed class JunkHudCounter : MonoBehaviour
{
	private JunkController junkController;

	private TextMeshProUGUI text;

	private int currentJunk = -1;

	private int maxJunk = -1;

	internal void Initialize(JunkController controller)
	{
		junkController = controller;
		ChildLocator component = ((Component)this).GetComponent<ChildLocator>();
		Transform val = (((Object)(object)component != (Object)null && (Object)(object)controller != (Object)null) ? component.FindChild(controller.percentageUIString) : null);
		text = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TextMeshProUGUI>() : null);
	}

	private void Update()
	{
		if (!((Object)(object)junkController == (Object)null) && !((Object)(object)text == (Object)null))
		{
			int num = Mathf.RoundToInt(junkController.CurrentJunk);
			if (num != currentJunk || junkController.MaxJunk != maxJunk)
			{
				currentJunk = num;
				maxJunk = junkController.MaxJunk;
				((TMP_Text)text).SetText(currentJunk + " / " + maxJunk, true);
			}
		}
	}
}
internal static class NanobotUpgradeService
{
	internal const int MaxActiveNanobotUpgrades = 2;

	internal static bool TryUpgrade(CharacterMaster playerMaster, NetworkInstanceId targetMasterId)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (!NetworkServer.active || !SelectionAuthority.Consume(playerMaster, SelectionAuthority.Kind.Nanobot, out var body))
		{
			return false;
		}
		GameObject val = NetworkServer.FindLocalObject(targetMasterId);
		CharacterMaster val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CharacterMaster>() : null);
		if (!IsEligible(playerMaster, val2))
		{
			return false;
		}
		if (CountActiveNanobotUpgrades(playerMaster) >= 2)
		{
			return false;
		}
		JunkController component = ((Component)body).GetComponent<JunkController>();
		int permanentTier = 1 + val2.inventory.GetItemCountPermanent(Items.DroneUpgradeHidden);
		ResourceCost cost = CostForPermanentTier(permanentTier);
		if (!FabricationService.CanPay(playerMaster.inventory, component, cost))
		{
			return false;
		}
		FabricationService.Pay(playerMaster.inventory, component, cost);
		val2.inventory.GiveItemPermanent(Items.DroneUpgradeHidden, 1);
		((Component)val2).gameObject.AddComponent<NanobotTemporaryUpgrade>();
		CharacterBody body2 = val2.GetBody();
		if (body2 != null)
		{
			body2.AddBuff(Plugin.NanobotActiveBuff);
		}
		return true;
	}

	internal static int CountActiveNanobotUpgrades(CharacterMaster owner)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		MinionGroup val = (((Object)(object)owner != (Object)null) ? MinionGroup.FindGroup(((NetworkBehaviour)owner).netId) : null);
		if (val == null)
		{
			return 0;
		}
		int num = 0;
		MinionOwnership[] members = val.members;
		foreach (MinionOwnership val2 in members)
		{
			CharacterMaster val3 = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).GetComponent<CharacterMaster>() : null);
			if ((Object)(object)val3 != (Object)null && (Object)(object)val3.GetBody() != (Object)null && (Object)(object)((Component)val3).GetComponent<NanobotTemporaryUpgrade>() != (Object)null)
			{
				num++;
			}
		}
		return num;
	}

	internal static bool IsEligible(CharacterMaster owner, CharacterMaster droneMaster)
	{
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Invalid comparison between Unknown and I4
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)owner == (Object)null || (Object)(object)droneMaster == (Object)null || (Object)(object)droneMaster.inventory == (Object)null || IsNanobotActive(droneMaster))
		{
			return false;
		}
		if ((Object)(object)droneMaster.minionOwnership == (Object)null || (Object)(object)droneMaster.minionOwnership.ownerMaster != (Object)(object)owner)
		{
			return false;
		}
		CharacterBody body = droneMaster.GetBody();
		if ((Object)(object)body == (Object)null || (body.bodyFlags & 0x400000) == 0)
		{
			return false;
		}
		DroneDef droneDef = DroneCatalog.GetDroneDef(DroneCatalog.GetDroneIndexFromBodyIndex(body.bodyIndex));
		return (Object)(object)droneDef != (Object)null && droneDef.canCombine;
	}

	internal static bool IsNanobotActive(CharacterMaster droneMaster)
	{
		if ((Object)(object)droneMaster == (Object)null)
		{
			return false;
		}
		if ((Object)(object)((Component)droneMaster).GetComponent<NanobotTemporaryUpgrade>() != (Object)null)
		{
			return true;
		}
		CharacterBody body = droneMaster.GetBody();
		return (Object)(object)body != (Object)null && (Object)(object)Plugin.NanobotActiveBuff != (Object)null && body.HasBuff(Plugin.NanobotActiveBuff);
	}

	internal static ResourceCost CostForPermanentTier(int permanentTier)
	{
		if (permanentTier <= 1)
		{
			return new ResourceCost(8, 1, 0, 0);
		}
		if (permanentTier == 2)
		{
			return new ResourceCost(12, 0, 1, 0);
		}
		return new ResourceCost(16, 2, 3, 0);
	}

	internal static void RemoveStageLimitedUpgrades(Stage _)
	{
		if (!NetworkServer.active)
		{
			return;
		}
		NanobotTemporaryUpgrade[] array = Object.FindObjectsOfType<NanobotTemporaryUpgrade>();
		foreach (NanobotTemporaryUpgrade nanobotTemporaryUpgrade in array)
		{
			CharacterMaster component = ((Component)nanobotTemporaryUpgrade).GetComponent<CharacterMaster>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.inventory != (Object)null)
			{
				component.inventory.RemoveItemPermanent(Items.DroneUpgradeHidden, nanobotTemporaryUpgrade.addedStacks);
				CharacterBody body = component.GetBody();
				if (body != null)
				{
					body.RemoveBuff(Plugin.NanobotActiveBuff);
				}
			}
			Object.Destroy((Object)(object)nanobotTemporaryUpgrade);
		}
	}
}
[HarmonyPatch(typeof(PauseManager), "TogglePauseScreen")]
internal static class PreventPauseWhileUesMenuIsOpen
{
	private static bool Prefix()
	{
		return !FabricationMenu.IsOpen;
	}
}
[HarmonyPatch(typeof(JunkController), "GenerateJunk")]
internal static class ApplyHoarderEfficiencyToJunkGeneration
{
	private static void Prefix(JunkController __instance, ref int quantity)
	{
		quantity = HoarderEfficiencyService.ProcessJunkGeneration(__instance, quantity);
	}
}
[HarmonyPatch(typeof(JunkController), "OnOverlayInstanceAdded")]
internal static class ShowNumericalJunkCount
{
	private static void Postfix(JunkController __instance, GameObject instance)
	{
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)instance == (Object)null) && !((Object)(object)instance.GetComponent<JunkHudCounter>() != (Object)null))
		{
			instance.AddComponent<JunkHudCounter>().Initialize(__instance);
		}
	}
}
[HarmonyPatch(typeof(GenericSkill), "RunRecharge")]
internal static class ApplyHoarderEfficiencyToFabricatedDroneCooldowns
{
	private static void Prefix(GenericSkill __instance)
	{
		if (HoarderEfficiencyService.IsFabricatedDroneSkill(__instance))
		{
			__instance.RecalculateValues();
		}
	}
}
[HarmonyPatch(typeof(GenericSkill), "CalculateFinalRechargeInterval")]
internal static class ApplyHoarderEfficiencyCooldownMultiplier
{
	private static void Postfix(GenericSkill __instance, ref float __result)
	{
		__result *= HoarderEfficiencyService.GetFabricatedDroneCooldownMultiplier(__instance);
	}
}
[HarmonyPatch(typeof(CharacterBody), "RecalculateStats")]
internal static class ApplyFabricatorJunkCombatStats
{
	private static readonly FieldInfo DamageField = AccessTools.Field(typeof(CharacterBody), "<damage>k__BackingField");

	private static readonly FieldInfo AttackSpeedField = AccessTools.Field(typeof(CharacterBody), "<attackSpeed>k__BackingField");

	private static void Postfix(CharacterBody __instance)
	{
		JunkController val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<JunkController>() : null);
		if (HoarderEfficiencyService.IsActive(__instance) && !((Object)(object)val == (Object)null) && val.MaxJunk > 0 && !(DamageField == null) && !(AttackSpeedField == null))
		{
			float num = Mathf.Clamp01(val.CurrentJunk / (float)val.MaxJunk);
			DamageField.SetValue(__instance, __instance.damage * Mathf.Lerp(1f, 2f, num));
			AttackSpeedField.SetValue(__instance, __instance.attackSpeed * Mathf.Lerp(1f, 0.5f, num));
		}
	}
}
[HarmonyPatch(typeof(DeathState), "OnImpactServer")]
internal static class SuppressFabricatedDroneRepairSpawn
{
	private static bool Prefix(DeathState __instance)
	{
		CharacterBody val = (((Object)(object)((EntityState)__instance).outer != (Object)null) ? ((EntityState)__instance).outer.commonComponents.characterBody : null);
		return (Object)(object)val == (Object)null || (Object)(object)val.master == (Object)null || (Object)(object)((Component)val.master).GetComponent<UESFabricatedDrone>() == (Object)null;
	}
}
[HarmonyPatch(typeof(DroneCombinerController), "GetInteractability")]
internal static class PreventCombiningTemporaryNanobotTier
{
	private static void Postfix(Interactor activator, ref Interactability __result)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		if ((int)__result == 0 || (Object)(object)activator == (Object)null)
		{
			return;
		}
		CharacterBody component = ((Component)activator).GetComponent<CharacterBody>();
		CharacterMaster val = ((component != null) ? component.master : null);
		MinionGroup val2 = (((Object)(object)val != (Object)null) ? MinionGroup.FindGroup(((NetworkBehaviour)val).netId) : null);
		if (val2 == null)
		{
			return;
		}
		MinionOwnership[] members = val2.members;
		foreach (MinionOwnership val3 in members)
		{
			if ((Object)(object)val3 != (Object)null && (Object)(object)((Component)val3).GetComponent<NanobotTemporaryUpgrade>() != (Object)null)
			{
				__result = (Interactability)1;
				break;
			}
		}
	}
}
[BepInPlugin("com.dermitio.uesdrifter", "UES Drifter", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.dermitio.uesdrifter";

	public const string PluginName = "UES Drifter";

	public const string PluginVersion = "1.0.0";

	internal static Plugin Instance;

	internal static DrifterSkillDef FabricatorSkill;

	internal static DrifterSkillDef NanobotSkill;

	internal static DrifterSkillDef JunkPatchSkill;

	internal static BuffDef NanobotActiveBuff;

	private static Texture2D fabricatorTexture;

	private static Texture2D nanobotTexture;

	private static Sprite fabricatorIcon;

	private static Sprite nanobotIcon;

	private static Texture2D junkPatchTexture;

	private static Sprite junkPatchIcon;

	private static Texture2D hoarderTexture;

	internal static Sprite HoarderIcon;

	private static string trashToTreasureDescriptionToken;

	private bool networkHandlerRegistered;

	private void Awake()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		new Harmony("com.dermitio.uesdrifter").PatchAll();
		CreateAndRegisterSkillDefs();
		RegisterEntityStates();
		Language.onCurrentLanguageChanged += RegisterLanguageTokens;
		RoR2Application.onLoadFinished = (Action)Delegate.Combine(RoR2Application.onLoadFinished, new Action(InstallSkillVariants));
		NetworkManagerSystem.onStartServerGlobal += RegisterServerNetworkHandler;
		NetworkManagerSystem.onStopServerGlobal += ResetServerNetworkHandler;
		Stage.onStageStartGlobal += NanobotUpgradeService.RemoveStageLimitedUpgrades;
	}

	private void OnDestroy()
	{
		NetworkManagerSystem.onStartServerGlobal -= RegisterServerNetworkHandler;
		NetworkManagerSystem.onStopServerGlobal -= ResetServerNetworkHandler;
		Stage.onStageStartGlobal -= NanobotUpgradeService.RemoveStageLimitedUpgrades;
		Language.onCurrentLanguageChanged -= RegisterLanguageTokens;
		RoR2Application.onLoadFinished = (Action)Delegate.Remove(RoR2Application.onLoadFinished, new Action(InstallSkillVariants));
	}

	private void RegisterServerNetworkHandler()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		if (!networkHandlerRegistered)
		{
			NetworkServer.RegisterHandler((short)151, new NetworkMessageDelegate(UesNetwork.HandleSelection));
			networkHandlerRegistered = true;
		}
	}

	private void ResetServerNetworkHandler()
	{
		networkHandlerRegistered = false;
	}

	private static void InstallSkillVariants()
	{
		CharacterBody drifterBody = BodyPrefabs.DrifterBody;
		SkillLocator locator = (Object.op_Implicit((Object)(object)drifterBody) ? ((Component)drifterBody).GetComponent<SkillLocator>() : null);
		if ((Object)(object)locator == (Object)null)
		{
			((BaseUnityPlugin)Instance).Logger.LogError((object)"Could not find Drifter's SkillLocator; UES variants were not installed.");
			return;
		}
		FabricatorSkill.minimumJunkCost = 4f;
		NanobotSkill.minimumJunkCost = 8f;
		JunkPatchSkill.minimumJunkCost = 12f;
		AddVariant(locator.secondary.skillFamily, (SkillDef)(object)FabricatorSkill);
		AddVariant(locator.utility.skillFamily, (SkillDef)(object)JunkPatchSkill);
		AddVariant(locator.special.skillFamily, (SkillDef)(object)NanobotSkill);
		GenericSkill val = ((IEnumerable<GenericSkill>)((Component)drifterBody).GetComponents<GenericSkill>()).FirstOrDefault((Func<GenericSkill, bool>)((GenericSkill skill) => (int)locator.FindSkillSlot(skill) == -1));
		if ((Object)(object)val == (Object)null || (Object)(object)val.skillFamily == (Object)null)
		{
			((BaseUnityPlugin)Instance).Logger.LogError((object)"Could not find Drifter's Trash To Treasure SkillFamily; Hoarder Efficiency details were not installed.");
		}
		else
		{
			SkillDef defaultSkillDef = val.skillFamily.defaultSkillDef;
			if ((Object)(object)defaultSkillDef != (Object)null && defaultSkillDef.skillDescriptionToken != "DRIFTER_TRASH_TO_TREASURE_WITH_HOARDER_DESCRIPTION")
			{
				trashToTreasureDescriptionToken = defaultSkillDef.skillDescriptionToken;
				defaultSkillDef.skillDescriptionToken = "DRIFTER_TRASH_TO_TREASURE_WITH_HOARDER_DESCRIPTION";
			}
		}
		RegisterLanguageTokens();
		if ((Object)(object)((Component)drifterBody).GetComponent<HoarderPassiveDisplay>() == (Object)null)
		{
			((Component)drifterBody).gameObject.AddComponent<HoarderPassiveDisplay>();
		}
	}

	private static void CreateAndRegisterSkillDefs()
	{
		if ((Object)(object)FabricatorSkill != (Object)null || (Object)(object)NanobotSkill != (Object)null || (Object)(object)JunkPatchSkill != (Object)null)
		{
			return;
		}
		fabricatorIcon = LoadEmbeddedSprite("DrifterUES.Assets.Fabricator.png", out fabricatorTexture);
		nanobotIcon = LoadEmbeddedSprite("DrifterUES.Assets.Nanobot.png", out nanobotTexture);
		HoarderIcon = LoadEmbeddedSprite("DrifterUES.Assets.HoarderEfficiency.png", out hoarderTexture);
		NanobotActiveBuff = ScriptableObject.CreateInstance<BuffDef>();
		((Object)NanobotActiveBuff).name = "UESNanobotUpgradeActive";
		NanobotActiveBuff.iconSprite = nanobotIcon;
		NanobotActiveBuff.isHidden = true;
		NanobotActiveBuff.canStack = false;
		LegacyModContentPackProvider.instance.registrationContentPack.buffDefs.Add((BuffDef[])(object)new BuffDef[1] { NanobotActiveBuff });
		FabricatorSkill = CreateSkill("UESFabricator", "DRIFTER_UES_FABRICATOR_NAME", "DRIFTER_UES_FABRICATOR_DESCRIPTION", fabricatorIcon, typeof(OpenFabricatorMenu), 1f);
		((SkillDef)FabricatorSkill).stockToConsume = 1;
		NanobotSkill = CreateSkill("NanobotUpgrades", "DRIFTER_NANOBOT_UPGRADES_NAME", "DRIFTER_NANOBOT_UPGRADES_DESCRIPTION", nanobotIcon, typeof(OpenNanobotMenu), 1f);
		junkPatchIcon = LoadEmbeddedSprite("DrifterUES.Assets.JunkPatch.png", out junkPatchTexture);
		JunkPatchSkill = CreateSkill("JunkPatch", "DRIFTER_JUNK_PATCH_NAME", "DRIFTER_JUNK_PATCH_DESCRIPTION", junkPatchIcon, typeof(JunkPatch), 16f);
		((SkillDef)JunkPatchSkill).baseRechargeInterval = 7f;
		((SkillDef)JunkPatchSkill).stockToConsume = 1;
		JunkPatchSkill.requireJunkForActivation = true;
		((SkillDef)JunkPatchSkill).hideCooldown = false;
		((SkillDef)JunkPatchSkill).hideStockCount = false;
		SkillCatalog.getAdditionalSkillDefs += delegate(List<SkillDef> skillDefs)
		{
			if (!skillDefs.Contains((SkillDef)(object)FabricatorSkill))
			{
				skillDefs.Add((SkillDef)(object)FabricatorSkill);
			}
			if (!skillDefs.Contains((SkillDef)(object)NanobotSkill))
			{
				skillDefs.Add((SkillDef)(object)NanobotSkill);
			}
			if (!skillDefs.Contains((SkillDef)(object)JunkPatchSkill))
			{
				skillDefs.Add((SkillDef)(object)JunkPatchSkill);
			}
		};
	}

	private static void RegisterEntityStates()
	{
		NamedAssetCollection<Type> entityStateTypes = LegacyModContentPackProvider.instance.registrationContentPack.entityStateTypes;
		if (!entityStateTypes.Contains(typeof(OpenFabricatorMenu)))
		{
			entityStateTypes.Add(new Type[1] { typeof(OpenFabricatorMenu) });
		}
		if (!entityStateTypes.Contains(typeof(OpenNanobotMenu)))
		{
			entityStateTypes.Add(new Type[1] { typeof(OpenNanobotMenu) });
		}
		if (!entityStateTypes.Contains(typeof(JunkPatch)))
		{
			entityStateTypes.Add(new Type[1] { typeof(JunkPatch) });
		}
	}

	private static DrifterSkillDef CreateSkill(string name, string skillNameToken, string descriptionToken, Sprite icon, Type stateType, float minimumJunk)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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)
		DrifterSkillDef val = (DrifterSkillDef)(object)((name == "UESFabricator") ? ScriptableObject.CreateInstance<DeferredFabricatorSkillDef>() : ((DeferredFabricatorSkillDef)(object)ScriptableObject.CreateInstance<DrifterSkillDef>()));
		((Object)val).name = name;
		((SkillDef)val).skillName = name;
		((SkillDef)val).skillNameToken = skillNameToken;
		((SkillDef)val).skillDescriptionToken = descriptionToken;
		((SkillDef)val).icon = icon;
		((SkillDef)val).activationState = new SerializableEntityStateType(stateType);
		((SkillDef)val).activationStateMachineName = "Weapon";
		((SkillDef)val).interruptPriority = (InterruptPriority)1;
		((SkillDef)val).baseMaxStock = 1;
		((SkillDef)val).baseRechargeInterval = ((name == "UESFabricator") ? 20f : 0f);
		((SkillDef)val).stockToConsume = 0;
		val.minimumJunkCost = minimumJunk;
		val.requireJunkForActivation = false;
		val.bypassCooldown = false;
		((SkillDef)val).cancelSprintingOnActivation = false;
		((SkillDef)val).mustKeyPress = true;
		((SkillDef)val).hideCooldown = name != "UESFabricator";
		((SkillDef)val).hideStockCount = name != "UESFabricator";
		return val;
	}

	private static void AddVariant(SkillFamily family, SkillDef skill)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)family) && !family.variants.Any((Variant v) => (Object)(object)v.skillDef == (Object)(object)skill || ((Object)(object)v.skillDef != (Object)null && v.skillDef.skillName == skill.skillName)))
		{
			List<Variant> list = family.variants.ToList();
			Variant item = new Variant
			{
				skillDef = skill,
				unlockableDef = null
			};
			((Variant)(ref item)).viewableNode = CreateVariantViewableNode(family, skill);
			list.Add(item);
			family.variants = list.ToArray();
		}
	}

	private static Node CreateVariantViewableNode(SkillFamily family, SkillDef skill)
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Expected O, but got Unknown
		CharacterBody drifterBody = BodyPrefabs.DrifterBody;
		string text = (Object.op_Implicit((Object)(object)drifterBody) ? ((Object)drifterBody).name : null);
		if (string.IsNullOrEmpty(text))
		{
			return null;
		}
		Node val = ViewablesCatalog.FindNode("/Loadout/Bodies/" + text + "/");
		if (val == null)
		{
			return null;
		}
		string skillFamilyName = SkillCatalog.GetSkillFamilyName(family.catalogIndex);
		Node node = new Node(skillFamilyName + "." + ((Object)skill).name, false, val);
		node.shouldShowUnviewed = (UserProfile profile) => !profile.HasViewedViewable(node.fullName);
		return node;
	}

	private static Sprite LoadEmbeddedSprite(string resourceName, out Texture2D texture)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Expected O, but got Unknown
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
		if (stream == null)
		{
			throw new InvalidOperationException("Missing embedded icon resource: " + resourceName);
		}
		using MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		texture = new Texture2D(2, 2, (TextureFormat)4, false)
		{
			name = resourceName,
			filterMode = (FilterMode)1,
			wrapMode = (TextureWrapMode)1
		};
		if (!ImageConversion.LoadImage(texture, memoryStream.ToArray(), false))
		{
			throw new InvalidOperationException("Could not decode icon resource: " + resourceName);
		}
		return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f);
	}

	private static void RegisterLanguageTokens()
	{
		SetLanguageTokens(Language.english);
		if (Language.currentLanguage != null && Language.currentLanguage != Language.english)
		{
			SetLanguageTokens(Language.currentLanguage);
		}
	}

	private static void SetLanguageTokens(Language language)
	{
		if (language != null)
		{
			language.SetStringByToken("DRIFTER_UES_FABRICATOR_NAME", "UES Fabricator");
			language.SetStringByToken("DRIFTER_UES_FABRICATOR_DESCRIPTION", "Open the UES fabrication menu. Select a drone to fabricate using collected Junk and Scrap. Carried Junk linearly raises damage to 2x and lowers attack speed to 0.5x at full Junk.");
			language.SetStringByToken("DRIFTER_NANOBOT_UPGRADES_NAME", "Nanobot Upgrades");
			language.SetStringByToken("DRIFTER_NANOBOT_UPGRADES_DESCRIPTION", "Open the Nanobot menu. Upgrade one compatible owned drone for the current stage.");
			language.SetStringByToken("DRIFTER_JUNK_PATCH_NAME", "Junk Patch");
			language.SetStringByToken("DRIFTER_JUNK_PATCH_DESCRIPTION", "Spend 16 Junk to heal yourself or an aimed ally within 12m for 35% of missing health. Drones heal for 60%. The target receives your Trash To Treasure buffs for 10 seconds; another Junk Patch refreshes them.");
			language.SetStringByToken("DRIFTER_HOARDER_EFFICIENCY_NAME", "Hoarder Efficiency");
			language.SetStringByToken("DRIFTER_HOARDER_EFFICIENCY_DESCRIPTION", "This passive is only active when UES Fabricator is selected.\nRaises Junk capacity to 20.\nFor every two fabricated drones below the 8-drone limit, generate 25% more Junk.\nAt 20 Junk, each would-be Junk can become Scrap; owned matching Scrap lowers its chance.\nFabricated drones gain 10% cooldown reduction per 4 Junk, up to 40%.");
			string text = (string.IsNullOrEmpty(trashToTreasureDescriptionToken) ? string.Empty : language.GetLocalizedStringByToken(trashToTreasureDescriptionToken));
			language.SetStringByToken("DRIFTER_TRASH_TO_TREASURE_WITH_HOARDER_DESCRIPTION", string.IsNullOrEmpty(text) ? "Hoarder Efficiency: This passive is only active when UES Fabricator is selected. Raises Junk capacity to 20. For every two fabricated drones below the 8-drone limit, generate 25% more Junk. At 20 Junk, each would-be Junk can become Scrap; owned matching Scrap lowers its chance. Fabricated drones gain 10% cooldown reduction per 4 Junk, up to 40%." : (text + "\n\nHoarder Efficiency: This passive is only active when UES Fabricator is selected. Raises Junk capacity to 20. For every two fabricated drones below the 8-drone limit, generate 25% more Junk. At 20 Junk, each would-be Junk can become Scrap; owned matching Scrap lowers its chance. Fabricated drones gain 10% cooldown reduction per 4 Junk, up to 40%."));
		}
	}
}
public readonly struct ResourceCost
{
	public readonly int junk;

	public readonly int whiteScrap;

	public readonly int greenScrap;

	public readonly int redScrap;

	public ResourceCost(int junk, int whiteScrap, int greenScrap, int redScrap)
	{
		this.junk = junk;
		this.whiteScrap = whiteScrap;
		this.greenScrap = greenScrap;
		this.redScrap = redScrap;
	}
}
public sealed class DroneRecipe
{
	public readonly byte id;

	public readonly string displayName;

	public readonly int fabricationTier;

	public readonly Func<DroneDef> drone;

	public readonly ResourceCost cost;

	public DroneRecipe(byte id, string displayName, int fabricationTier, Func<DroneDef> drone, ResourceCost cost)
	{
		this.id = id;
		this.displayName = displayName;
		this.fabricationTier = fabricationTier;
		this.drone = drone;
		this.cost = cost;
	}
}
public static class UesRecipes
{
	public static readonly IReadOnlyList<DroneRecipe> Fabrication = new DroneRecipe[17]
	{
		new DroneRecipe(1, "Gunner Drone", 1, () => DroneDefs.Drone1, new ResourceCost(4, 1, 0, 0)),
		new DroneRecipe(2, "Healing Drone", 1, () => DroneDefs.Drone2, new ResourceCost(4, 0, 1, 0)),
		new DroneRecipe(3, "Healing Drone", 1, () => DroneDefs.Drone2, new ResourceCost(6, 2, 0, 0)),
		new DroneRecipe(4, "Missile Drone", 2, () => DroneDefs.MissileDrone, new ResourceCost(6, 0, 1, 0)),
		new DroneRecipe(5, "Emergency Drone", 2, () => DroneDefs.EmergencyDrone, new ResourceCost(6, 2, 1, 0)),
		new DroneRecipe(6, "Emergency Drone", 2, () => DroneDefs.EmergencyDrone, new ResourceCost(8, 4, 0, 0)),
		new DroneRecipe(7, "Barrier Drone", 2, () => DroneDefs.RechargeDrone, new ResourceCost(6, 1, 1, 0)),
		new DroneRecipe(8, "Barrier Drone", 2, () => DroneDefs.RechargeDrone, new ResourceCost(10, 3, 0, 0)),
		new DroneRecipe(9, "Jailer Drone", 2, () => DroneDefs.JailerDrone, new ResourceCost(10, 3, 0, 0)),
		new DroneRecipe(10, "Incinerator Drone", 2, () => DroneDefs.FlameDrone, new ResourceCost(12, 0, 2, 0)),
		new DroneRecipe(11, "Incinerator Drone", 2, () => DroneDefs.FlameDrone, new ResourceCost(14, 6, 0, 0)),
		new DroneRecipe(12, "Bombardment Drone", 3, () => DroneDefs.BombardmentDrone, new ResourceCost(12, 1, 0, 1)),
		new DroneRecipe(13, "Bombardment Drone", 3, () => DroneDefs.BombardmentDrone, new ResourceCost(14, 2, 3, 0)),
		new DroneRecipe(14, "TC-280 Prototype", 3, () => DroneDefs.MegaDrone, new ResourceCost(16, 2, 1, 1)),
		new DroneRecipe(15, "TC-280 Prototype", 3, () => DroneDefs.MegaDrone, new ResourceCost(20, 4, 4, 0)),
		new DroneRecipe(16, "Freeze Drone", 3, () => DroneDefs.CopycatDrone, new ResourceCost(14, 0, 1, 1)),
		new DroneRecipe(17, "Freeze Drone", 3, () => DroneDefs.CopycatDrone, new ResourceCost(16, 0, 3, 0))
	};

	public static bool TryGet(byte id, out DroneRecipe recipe)
	{
		foreach (DroneRecipe item in Fabrication)
		{
			if (item.id == id)
			{
				recipe = item;
				return true;
			}
		}
		recipe = null;
		return false;
	}
}
public sealed class OpenFabricatorMenu : BaseState
{
	public override void OnEnter()
	{
		((BaseState)this).OnEnter();
		bool flag = (Object)(object)((EntityState)this).characterBody != (Object)null && (Object)(object)((EntityState)this).characterBody.skillLocator != (Object)null && ((EntityState)this).characterBody.skillLocator.secondary.stock > 0 && FabricationService.HasAvailableFabricationRecipe();
		if (((EntityState)this).isAuthority && flag)
		{
			FabricationMenu.Open(FabricationMenu.Mode.Fabricator, ((EntityState)this).characterBody);
		}
		if (NetworkServer.active && flag)
		{
			SelectionAuthority.Open(((EntityState)this).characterBody, SelectionAuthority.Kind.Fabricator);
		}
		((EntityState)this).outer.SetNextStateToMain();
	}
}
public sealed class OpenNanobotMenu : BaseState
{
	public override void OnEnter()
	{
		((BaseState)this).OnEnter();
		if (((EntityState)this).isAuthority)
		{
			FabricationMenu.Open(FabricationMenu.Mode.Nanobot, ((EntityState)this).characterBody);
		}
		if (NetworkServer.active)
		{
			SelectionAuthority.Open(((EntityState)this).characterBody, SelectionAuthority.Kind.Nanobot);
		}
		((EntityState)this).outer.SetNextStateToMain();
	}
}
public sealed class JunkPatch : BaseState
{
	private const float Range = 12f;

	public override void OnEnter()
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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)
		((BaseState)this).OnEnter();
		if (NetworkServer.active && (Object)(object)((EntityState)this).characterBody != (Object)null)
		{
			HealthComponent val = FindTarget() ?? ((EntityState)this).characterBody.healthComponent;
			if ((Object)(object)val != (Object)null)
			{
				float num = Mathf.Max(0f, val.fullCombinedHealth - val.combinedHealth);
				CharacterBody body = val.body;
				float num2 = (((Object)(object)body != (Object)null && (body.bodyFlags & 0x400000) != 0) ? 0.6f : 0.35f);
				val.Heal(num * num2, default(ProcChainMask), true);
				if ((Object)(object)body != (Object)null)
				{
					JunkPatchTrashToTreasureService.Apply(((EntityState)this).characterBody, body);
				}
			}
		}
		((EntityState)this).outer.SetNextStateToMain();
	}

	private HealthComponent FindTarget()
	{
		//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_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		BullseyeSearch val = new BullseyeSearch
		{
			viewer = ((EntityState)this).characterBody
		};
		Ray aimRay = ((BaseState)this).GetAimRay();
		val.searchOrigin = ((Ray)(ref aimRay)).origin;
		aimRay = ((BaseState)this).GetAimRay();
		val.searchDirection = ((Ray)(ref aimRay)).direction;
		val.maxDistanceFilter = 12f;
		val.maxAngleFilter = 14f;
		val.sortMode = (SortMode)2;
		val.filterByLoS = true;
		val.filterByDistinctEntity = true;
		val.teamMaskFilter = TeamMask.none;
		BullseyeSearch val2 = val;
		((TeamMask)(ref val2.teamMaskFilter)).AddTeam(((EntityState)this).teamComponent.teamIndex);
		val2.RefreshCandidates();
		val2.FilterOutGameObject(((EntityState)this).gameObject);
		return val2.GetResults().FirstOrDefault()?.healthComponent;
	}
}