Decompiled source of LethalBounties v1.0.2

BepInEx/plugins/LethalBounty.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalBounty")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalBounty")]
[assembly: AssemblyTitle("LethalBounty")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal class LethalBountiesConfig
{
	private readonly ConfigFile _configFile;

	public ConfigEntry<int> SnareFleaMin;

	public ConfigEntry<int> SnareFleaMax;

	public ConfigEntry<int> TulipSnakesMin;

	public ConfigEntry<int> TulipSnakesMax;

	public ConfigEntry<int> ManticoilMin;

	public ConfigEntry<int> ManticoilMax;

	public ConfigEntry<int> ButlerMin;

	public ConfigEntry<int> ButlerMax;

	public ConfigEntry<int> BackwaterGunkfishMin;

	public ConfigEntry<int> BackwaterGunkfishMax;

	public ConfigEntry<int> HoardingBugMin;

	public ConfigEntry<int> HoardingBugMax;

	public ConfigEntry<int> CadaverBloomMin;

	public ConfigEntry<int> CadaverBloomMax;

	public ConfigEntry<int> BaboonHawkMin;

	public ConfigEntry<int> BaboonHawkMax;

	public ConfigEntry<int> ThumperMin;

	public ConfigEntry<int> ThumperMax;

	public ConfigEntry<int> FeioparMin;

	public ConfigEntry<int> FeioparMax;

	public ConfigEntry<int> BunkerSpiderMin;

	public ConfigEntry<int> BunkerSpiderMax;

	public ConfigEntry<int> MaskedMin;

	public ConfigEntry<int> MaskedMax;

	public ConfigEntry<int> EyelessDogMin;

	public ConfigEntry<int> EyelessDogMax;

	public ConfigEntry<int> NutcrackerMin;

	public ConfigEntry<int> NutcrackerMax;

	public ConfigEntry<int> KidnapperFoxMin;

	public ConfigEntry<int> KidnapperFoxMax;

	public ConfigEntry<int> GiantSapsuckerMin;

	public ConfigEntry<int> GiantSapsuckerMax;

	public ConfigEntry<int> BrackenMin;

	public ConfigEntry<int> BrackenMax;

	public ConfigEntry<int> ManeaterMin;

	public ConfigEntry<int> ManeaterMax;

	public ConfigEntry<int> ForestKeeperMin;

	public ConfigEntry<int> ForestKeeperMax;

	public ConfigEntry<bool> OverrideScrapWeight;

	public ConfigEntry<float> BountyUISize;

	public ConfigEntry<bool> ResetKillStreakOnOrbit;

	public ConfigEntry<bool> FullClearReward;

	public ConfigEntry<bool> DisableIndoorBounties;

	public ConfigEntry<bool> DisableOutdoorBounties;

	public ConfigEntry<bool> DisableDaytimeBounties;

	public ConfigEntry<bool> DisableAssassinationBounties;

	public LethalBountiesConfig(ConfigFile configFile)
	{
		_configFile = configFile;
	}

	public void RegisterOptions()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected O, but got Unknown
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Expected O, but got Unknown
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Expected O, but got Unknown
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Expected O, but got Unknown
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Expected O, but got Unknown
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Expected O, but got Unknown
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Expected O, but got Unknown
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Expected O, but got Unknown
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Expected O, but got Unknown
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Expected O, but got Unknown
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Expected O, but got Unknown
		//IL_032b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0335: Expected O, but got Unknown
		//IL_0362: Unknown result type (might be due to invalid IL or missing references)
		//IL_036c: Expected O, but got Unknown
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Expected O, but got Unknown
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03da: Expected O, but got Unknown
		//IL_0407: Unknown result type (might be due to invalid IL or missing references)
		//IL_0411: Expected O, but got Unknown
		//IL_043e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0448: Expected O, but got Unknown
		//IL_0475: Unknown result type (might be due to invalid IL or missing references)
		//IL_047f: Expected O, but got Unknown
		//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b6: Expected O, but got Unknown
		//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Expected O, but got Unknown
		//IL_051a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0524: Expected O, but got Unknown
		//IL_0551: Unknown result type (might be due to invalid IL or missing references)
		//IL_055b: Expected O, but got Unknown
		//IL_058b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0595: Expected O, but got Unknown
		//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05cc: Expected O, but got Unknown
		//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0603: Expected O, but got Unknown
		//IL_0630: Unknown result type (might be due to invalid IL or missing references)
		//IL_063a: Expected O, but got Unknown
		//IL_066a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0674: Expected O, but got Unknown
		//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ab: Expected O, but got Unknown
		//IL_06d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e2: Expected O, but got Unknown
		//IL_070f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0719: Expected O, but got Unknown
		//IL_0749: Unknown result type (might be due to invalid IL or missing references)
		//IL_0753: Expected O, but got Unknown
		//IL_0780: Unknown result type (might be due to invalid IL or missing references)
		//IL_078a: Expected O, but got Unknown
		//IL_07b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c1: Expected O, but got Unknown
		//IL_07f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_07fb: Expected O, but got Unknown
		//IL_082b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0835: Expected O, but got Unknown
		//IL_085d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0867: Expected O, but got Unknown
		//IL_088f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0899: Expected O, but got Unknown
		//IL_08c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_08cb: Expected O, but got Unknown
		//IL_08ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0909: Expected O, but got Unknown
		//IL_0931: Unknown result type (might be due to invalid IL or missing references)
		//IL_093b: Expected O, but got Unknown
		//IL_0963: Unknown result type (might be due to invalid IL or missing references)
		//IL_096d: Expected O, but got Unknown
		//IL_0995: Unknown result type (might be due to invalid IL or missing references)
		//IL_099f: Expected O, but got Unknown
		//IL_09c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_09d1: Expected O, but got Unknown
		SnareFleaMin = _configFile.Bind<int>("Snare Flea", "Snare Flea Min Value", 20, new ConfigDescription("The minimum scrap value of the Snare Flea scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		SnareFleaMax = _configFile.Bind<int>("Snare Flea", "Snare Flea Max Value", 40, new ConfigDescription("The maximum scrap value of the Snare Flea scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		TulipSnakesMin = _configFile.Bind<int>("Tulip Snakes", "Tulip Snakes Min Value", 10, new ConfigDescription("The minimum scrap value of the Tulip Snakes scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		TulipSnakesMax = _configFile.Bind<int>("Tulip Snakes", "Tulip Snakes Max Value", 30, new ConfigDescription("The maximum scrap value of the Tulip Snakes scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ManticoilMin = _configFile.Bind<int>("Manticoil", "Manticoil Min Value", 15, new ConfigDescription("The minimum scrap value of the Manticoil scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ManticoilMax = _configFile.Bind<int>("Manticoil", "Manticoil Max Value", 35, new ConfigDescription("The maximum scrap value of the Manticoil scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ButlerMin = _configFile.Bind<int>("Butler", "Butler Min Value", 25, new ConfigDescription("The minimum scrap value of the Butler scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ButlerMax = _configFile.Bind<int>("Butler", "Butler Max Value", 45, new ConfigDescription("The maximum scrap value of the Butler scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BackwaterGunkfishMin = _configFile.Bind<int>("Backwater Gunkfish", "Backwater Gunkfish Min Value", 30, new ConfigDescription("The minimum scrap value of the Backwater Gunkfish scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BackwaterGunkfishMax = _configFile.Bind<int>("Backwater Gunkfish", "Backwater Gunkfish Max Value", 50, new ConfigDescription("The maximum scrap value of the Backwater Gunkfish scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		HoardingBugMin = _configFile.Bind<int>("Hoarding Bug", "Hoarding Bug Min Value", 30, new ConfigDescription("The minimum scrap value of the Hoarding Bug scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		HoardingBugMax = _configFile.Bind<int>("Hoarding Bug", "Hoarding Bug Max Value", 50, new ConfigDescription("The maximum scrap value of the Hoarding Bug scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		CadaverBloomMin = _configFile.Bind<int>("Cadaver Bloom", "Cadaver Bloom Min Value", 70, new ConfigDescription("The minimum scrap value of the Cadaver Bloom scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		CadaverBloomMax = _configFile.Bind<int>("Cadaver Bloom", "Cadaver Bloom Max Value", 100, new ConfigDescription("The maximum scrap value of the Cadaver Bloom scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BaboonHawkMin = _configFile.Bind<int>("Baboon Hawk", "Baboon Hawk Min Value", 45, new ConfigDescription("The minimum scrap value of the Baboon Hawk scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BaboonHawkMax = _configFile.Bind<int>("Baboon Hawk", "Baboon Hawk Max Value", 70, new ConfigDescription("The maximum scrap value of the Baboon Hawk scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ThumperMin = _configFile.Bind<int>("Thumper", "Thumper Min Value", 45, new ConfigDescription("The minimum scrap value of the Thumper scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ThumperMax = _configFile.Bind<int>("Thumper", "Thumper Max Value", 70, new ConfigDescription("The maximum scrap value of the Thumper scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		FeioparMin = _configFile.Bind<int>("Feiopar", "Feiopar Min Value", 80, new ConfigDescription("The minimum scrap value of the Feiopar scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		FeioparMax = _configFile.Bind<int>("Feiopar", "Feiopar Max Value", 110, new ConfigDescription("The maximum scrap value of the Feiopar scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BunkerSpiderMin = _configFile.Bind<int>("Bunker Spider", "Bunker Spider Min Value", 50, new ConfigDescription("The minimum scrap value of the Bunker Spider scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BunkerSpiderMax = _configFile.Bind<int>("Bunker Spider", "Bunker Spider Max Value", 75, new ConfigDescription("The maximum scrap value of the Bunker Spider scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		MaskedMin = _configFile.Bind<int>("Masked", "Masked Min Value", 50, new ConfigDescription("The minimum scrap value of the Masked scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		MaskedMax = _configFile.Bind<int>("Masked", "Masked Max Value", 80, new ConfigDescription("The maximum scrap value of the Masked scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		EyelessDogMin = _configFile.Bind<int>("Eyeless Dog", "Eyeless Dog Min Value", 100, new ConfigDescription("The minimum scrap value of the Eyeless Dog scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		EyelessDogMax = _configFile.Bind<int>("Eyeless Dog", "Eyeless Dog Max Value", 130, new ConfigDescription("The maximum scrap value of the Eyeless Dog scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		NutcrackerMin = _configFile.Bind<int>("Nutcracker", "Nutcracker Min Value", 70, new ConfigDescription("The minimum scrap value of the Nutcracker scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		NutcrackerMax = _configFile.Bind<int>("Nutcracker", "Nutcracker Max Value", 90, new ConfigDescription("The maximum scrap value of the Nutcracker scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		KidnapperFoxMin = _configFile.Bind<int>("Kidnapper Fox", "Kidnapper Fox Min Value", 100, new ConfigDescription("The minimum scrap value of the Kidnapper Fox scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		KidnapperFoxMax = _configFile.Bind<int>("Kidnapper Fox", "Kidnapper Fox Max Value", 130, new ConfigDescription("The maximum scrap value of the Kidnapper Fox scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		GiantSapsuckerMin = _configFile.Bind<int>("Giant Sapsucker", "Giant Sapsucker Min Value", 60, new ConfigDescription("The minimum scrap value of the Giant Sapsucker scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		GiantSapsuckerMax = _configFile.Bind<int>("Giant Sapsucker", "Giant Sapsucker Max Value", 85, new ConfigDescription("The maximum scrap value of the Giant Sapsucker scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BrackenMin = _configFile.Bind<int>("Bracken", "Bracken Min Value", 110, new ConfigDescription("The minimum scrap value of the Bracken scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		BrackenMax = _configFile.Bind<int>("Bracken", "Bracken Max Value", 135, new ConfigDescription("The maximum scrap value of the Bracken scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ManeaterMin = _configFile.Bind<int>("Maneater", "Maneater Min Value", 90, new ConfigDescription("The minimum scrap value of the Maneater scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ManeaterMax = _configFile.Bind<int>("Maneater", "Maneater Max Value", 120, new ConfigDescription("The maximum scrap value of the Maneater scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ForestKeeperMin = _configFile.Bind<int>("Forest Keeper", "Forest Keeper Min Value", 150, new ConfigDescription("The minimum scrap value of the Forest Keeper scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		ForestKeeperMax = _configFile.Bind<int>("Forest Keeper", "Forest Keeper Max Value", 180, new ConfigDescription("The maximum scrap value of the Forest Keeper scrap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900), Array.Empty<object>()));
		OverrideScrapWeight = _configFile.Bind<bool>("Scrap", "Override Scrap Weight", true, new ConfigDescription("If enabled, scrap by bounties will be 0lb. If disabled, scrap will have their default lb values.", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		FullClearReward = _configFile.Bind<bool>("Kill", "Enable Bounty Clear Reward", false, new ConfigDescription("If enabled, the last bounty kill will spawn an additional item. Excludes Assassination Bounties.", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		ResetKillStreakOnOrbit = _configFile.Bind<bool>("Kill", "Reset Kill Streak On Orbit", false, new ConfigDescription("If enabled, your Kill Streak is reset every day.", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		BountyUISize = _configFile.Bind<float>("Bounty", "Bounty UI Size", 11f, new ConfigDescription("The size of the Bounty UI. 0 size would just disable it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 16f), Array.Empty<object>()));
		DisableIndoorBounties = _configFile.Bind<bool>("Bounty", "Disable Indoor Bounties", false, new ConfigDescription("If enabled, Indoor bounties can not be assigned.", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		DisableOutdoorBounties = _configFile.Bind<bool>("Bounty", "Disable Outdoor Bounties", false, new ConfigDescription("If enabled, Outdoor bounties can not be assigned.", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		DisableDaytimeBounties = _configFile.Bind<bool>("Bounty", "Disable Daytime Bounties", false, new ConfigDescription("If enabled, Daytime bounties can not be assigned.", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
		DisableAssassinationBounties = _configFile.Bind<bool>("Bounty", "Disable Assassination Bounties", false, new ConfigDescription("If enabled, Assassination bounties can not be assigned.", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
	}
}
namespace LethalBounty
{
	public static class BountyManager
	{
		public static Dictionary<SelectableLevel, MoonBounty> MoonBounties = new Dictionary<SelectableLevel, MoonBounty>();

		public static MoonBounty CurrentBounty = new MoonBounty();

		public static Dictionary<EnemyAI, int> ActiveBounties = new Dictionary<EnemyAI, int>();

		public static int KillStreak = 0;

		public static bool BountyTargetsSpawned = false;

		public static int FullClearValueTotal;

		public static int FullClearTargetCount;

		private static bool HasValidBountyTargets(List<SpawnableEnemyWithRarity> pool)
		{
			return pool?.Any((SpawnableEnemyWithRarity x) => (Object)(object)x?.enemyType != (Object)null && x.rarity > 0 && IsBountyKillable(x.enemyType)) ?? false;
		}

		public static MoonBounty GenerateBounty(SelectableLevel level)
		{
			MoonBounty moonBounty = new MoonBounty();
			if ((Object)(object)level == (Object)null)
			{
				return moonBounty;
			}
			int num = level.maxEnemyPowerCount;
			int num2 = level.maxOutsideEnemyPowerCount / 3;
			int num3 = level.maxDaytimeEnemyPowerCount / 3;
			int num4 = level.maxEnemyPowerCount - level.maxOutsideEnemyPowerCount;
			int num5 = num + num2 + num3 + num4;
			while (num5 > 0)
			{
				if (num > 0 && HasValidBountyTargets(level.Enemies))
				{
					if (Random.Range(0, num5) < num)
					{
						moonBounty.Type = BountyType.Indoor;
						break;
					}
					num5 -= num;
					num = 0;
					continue;
				}
				if (num2 > 0 && HasValidBountyTargets(level.OutsideEnemies))
				{
					if (Random.Range(0, num5) < num2)
					{
						moonBounty.Type = BountyType.Outdoor;
						break;
					}
					num5 -= num2;
					num2 = 0;
					continue;
				}
				if (num3 > 0 && HasValidBountyTargets(level.DaytimeEnemies))
				{
					if (Random.Range(0, num5) < num3)
					{
						moonBounty.Type = BountyType.Daytime;
						break;
					}
					num5 -= num3;
					num3 = 0;
					continue;
				}
				if (num4 > 0 && HasValidBountyTargets(level.Enemies))
				{
					if (Random.Range(0, num5) < num4)
					{
						moonBounty.Type = BountyType.Assassination;
						break;
					}
					num5 -= num4;
					num4 = 0;
					continue;
				}
				moonBounty.Type = BountyType.Indoor;
				break;
			}
			switch (moonBounty.Type)
			{
			case BountyType.Indoor:
				GenerateIndoorBounty(level, moonBounty);
				break;
			case BountyType.Outdoor:
				GenerateOutdoorBounty(level, moonBounty);
				break;
			case BountyType.Assassination:
				GenerateAssassinationBounty(level, moonBounty);
				break;
			case BountyType.Daytime:
				GenerateDaytimeBounty(level, moonBounty);
				break;
			}
			GenerateSpecialThreats(level, moonBounty);
			return moonBounty;
		}

		private static void GenerateIndoorBounty(SelectableLevel level, MoonBounty bounty)
		{
			float powerBudget = level.maxEnemyPowerCount;
			bounty.Targets = GenerateEnemyList(level.Enemies, powerBudget, requireKillable: true);
		}

		private static void GenerateOutdoorBounty(SelectableLevel level, MoonBounty bounty)
		{
			float powerBudget = level.maxOutsideEnemyPowerCount;
			bounty.Targets = GenerateEnemyList(level.OutsideEnemies, powerBudget, requireKillable: true);
		}

		private static void GenerateDaytimeBounty(SelectableLevel level, MoonBounty bounty)
		{
			float powerBudget = level.maxDaytimeEnemyPowerCount;
			bounty.Targets = GenerateEnemyList(level.DaytimeEnemies, powerBudget, requireKillable: true);
		}

		private static void GenerateAssassinationBounty(SelectableLevel level, MoonBounty bounty)
		{
			List<SpawnableEnemyWithRarity> list = level.Enemies.Where((SpawnableEnemyWithRarity entry) => entry != null && (Object)(object)entry.enemyType != (Object)null && IsBountyKillable(entry.enemyType) && entry.rarity > 0).ToList();
			if (list.Count != 0)
			{
				SpawnableEnemyWithRarity val = PickWeightedEnemy(list);
				if (val != null && !((Object)(object)val.enemyType == (Object)null))
				{
					EnemyType enemyType = val.enemyType;
					bounty.Targets.Add(enemyType);
					float num = level.maxEnemyPowerCount;
					float powerBudget = Mathf.Max(0f, num - enemyType.PowerLevel);
					bounty.IndoorThreats = GenerateEnemyList(level.Enemies, powerBudget, requireKillable: false, onlyUnkillable: true);
					float powerBudget2 = level.maxOutsideEnemyPowerCount;
					bounty.OutdoorThreats = GenerateEnemyList(level.OutsideEnemies, powerBudget2, requireKillable: false, onlyUnkillable: true);
				}
			}
		}

		public static bool IsBountyKillable(EnemyType enemyType)
		{
			if ((Object)(object)enemyType == (Object)null)
			{
				return false;
			}
			string displayName = GetDisplayName(enemyType);
			if (displayName == "Hygrodere")
			{
				return false;
			}
			if (enemyType.isDaytimeEnemy)
			{
				switch (displayName)
				{
				case "Giant Sapsucker":
					return true;
				case "Red Locust Bees":
					return true;
				case "Roaming Locusts":
					return false;
				case "Tulip Snakes":
					return true;
				}
			}
			return enemyType.canDie;
		}

		private static List<EnemyType> GenerateEnemyList(List<SpawnableEnemyWithRarity> pool, float powerBudget, bool requireKillable = false, bool onlyUnkillable = false)
		{
			List<EnemyType> list = new List<EnemyType>();
			if (pool == null)
			{
				return list;
			}
			Dictionary<EnemyType, int> selectedCounts = new Dictionary<EnemyType, int>();
			float remainingPower;
			EnemyType enemyType;
			for (remainingPower = powerBudget; remainingPower > 0f; remainingPower -= enemyType.PowerLevel)
			{
				List<SpawnableEnemyWithRarity> list2 = pool.Where(delegate(SpawnableEnemyWithRarity entry)
				{
					if (entry == null || (Object)(object)entry.enemyType == (Object)null || entry.rarity <= 0)
					{
						return false;
					}
					EnemyType enemyType2 = entry.enemyType;
					if (enemyType2.PowerLevel <= 0f || enemyType2.PowerLevel > remainingPower)
					{
						return false;
					}
					bool flag = IsBountyKillable(enemyType2);
					if (requireKillable && !flag)
					{
						return false;
					}
					if (onlyUnkillable && flag)
					{
						return false;
					}
					return (GetSelectedCount(selectedCounts, enemyType2) < enemyType2.MaxCount) ? true : false;
				}).ToList();
				if (list2.Count == 0)
				{
					break;
				}
				SpawnableEnemyWithRarity val = PickWeightedEnemy(list2);
				if (val == null)
				{
					break;
				}
				enemyType = val.enemyType;
				list.Add(enemyType);
				if (!selectedCounts.ContainsKey(enemyType))
				{
					selectedCounts[enemyType] = 0;
				}
				selectedCounts[enemyType]++;
			}
			return list;
		}

		public static void GenerateAllMoonBounties()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer)
			{
				return;
			}
			MoonBounties.Clear();
			SelectableLevel[] array = Resources.FindObjectsOfTypeAll<SelectableLevel>();
			SelectableLevel[] array2 = array;
			foreach (SelectableLevel val in array2)
			{
				if (!((Object)(object)val == (Object)null))
				{
					MoonBounty moonBounty = GenerateBounty(val);
					MoonBounties[val] = moonBounty;
					Plugin.Instance.logger.LogInfo((object)$"{val.PlanetName}: {moonBounty.Type}");
				}
			}
			BountyNetworking.SyncBountyBoard();
		}

		private static int GetSelectedCount(Dictionary<EnemyType, int> selectedCounts, EnemyType enemyType)
		{
			if (selectedCounts.TryGetValue(enemyType, out var value))
			{
				return value;
			}
			return 0;
		}

		private static SpawnableEnemyWithRarity PickWeightedEnemy(List<SpawnableEnemyWithRarity> enemies)
		{
			int num = enemies.Sum((SpawnableEnemyWithRarity x) => x.rarity);
			if (num <= 0)
			{
				return null;
			}
			int num2 = Random.Range(0, num);
			int num3 = 0;
			foreach (SpawnableEnemyWithRarity enemy in enemies)
			{
				num3 += enemy.rarity;
				if (num2 < num3)
				{
					return enemy;
				}
			}
			return enemies[enemies.Count - 1];
		}

		private static void GenerateSpecialThreats(SelectableLevel level, MoonBounty bounty)
		{
			GenerateKidnapperFoxThreat(level, bounty);
		}

		private static void GenerateKidnapperFoxThreat(SelectableLevel level, MoonBounty bounty)
		{
			RoundManager instance = RoundManager.Instance;
			if ((Object)(object)instance == (Object)null || instance.WeedEnemies == null)
			{
				return;
			}
			SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)instance.WeedEnemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity x) => (Object)(object)x?.enemyType != (Object)null && GetDisplayName(x.enemyType) == "Kidnapper Fox"));
			if ((Object)(object)val?.enemyType == (Object)null)
			{
				return;
			}
			EnemyType fox = val.enemyType;
			if (fox.spawningDisabled || fox.MaxCount <= 0 || fox.PowerLevel > 4f)
			{
				return;
			}
			int moldSpreadIterations = level.moldSpreadIterations;
			Plugin.Instance.logger.LogInfo((object)($"{level.PlanetName} | Mold: {moldSpreadIterations} | Fox threat: " + $"{bounty.OutdoorThreats.Count((EnemyType x) => (Object)(object)x == (Object)(object)fox)}"));
			if (moldSpreadIterations <= 15)
			{
				return;
			}
			int num = Mathf.Clamp(moldSpreadIterations, 0, 70);
			if (Random.Range(0, 70) >= num)
			{
				return;
			}
			int num2 = Random.Range(1, 3);
			float num3 = 0f;
			for (int num4 = 0; num4 < num2; num4++)
			{
				if (num3 + fox.PowerLevel > 4f)
				{
					break;
				}
				if (bounty.OutdoorThreats.Count((EnemyType x) => (Object)(object)x == (Object)(object)fox) >= fox.MaxCount)
				{
					break;
				}
				bounty.OutdoorThreats.Add(fox);
				num3 += fox.PowerLevel;
			}
		}

		public static int GetBountyValue(EnemyType enemyType)
		{
			LethalBountiesConfig configuration = Plugin.Instance.Configuration;
			return GetDisplayName(enemyType) switch
			{
				"Snare Flea" => Random.Range(configuration.SnareFleaMin.Value, configuration.SnareFleaMax.Value + 1), 
				"Bracken" => Random.Range(configuration.BrackenMin.Value, configuration.BrackenMax.Value + 1), 
				"Maneater" => Random.Range(configuration.ManeaterMin.Value, configuration.ManeaterMax.Value + 1), 
				"Nutcracker" => Random.Range(configuration.NutcrackerMin.Value, configuration.NutcrackerMax.Value + 1), 
				"Cadaver Bloom" => Random.Range(configuration.CadaverBloomMin.Value, configuration.CadaverBloomMax.Value + 1), 
				"Masked" => Random.Range(configuration.MaskedMin.Value, configuration.MaskedMax.Value + 1), 
				"Backwater Gunkfish" => Random.Range(configuration.BackwaterGunkfishMin.Value, configuration.BackwaterGunkfishMax.Value + 1), 
				"Bunker Spider" => Random.Range(configuration.BunkerSpiderMin.Value, configuration.BunkerSpiderMax.Value + 1), 
				"Butler" => Random.Range(configuration.ButlerMin.Value, configuration.ButlerMax.Value + 1), 
				"Hoarding Bug" => Random.Range(configuration.HoardingBugMin.Value, configuration.HoardingBugMax.Value + 1), 
				"Thumper" => Random.Range(configuration.ThumperMin.Value, configuration.ThumperMax.Value + 1), 
				"Baboon Hawk" => Random.Range(configuration.BaboonHawkMin.Value, configuration.BaboonHawkMax.Value + 1), 
				"Eyeless Dog" => Random.Range(configuration.EyelessDogMin.Value, configuration.EyelessDogMax.Value + 1), 
				"Forest Keeper" => Random.Range(configuration.ForestKeeperMin.Value, configuration.ForestKeeperMax.Value + 1), 
				"Kidnapper Fox" => Random.Range(configuration.KidnapperFoxMin.Value, configuration.KidnapperFoxMax.Value + 1), 
				"Feiopar" => Random.Range(configuration.FeioparMin.Value, configuration.FeioparMax.Value + 1), 
				"Giant Sapsucker" => Random.Range(configuration.GiantSapsuckerMin.Value, configuration.GiantSapsuckerMax.Value + 1), 
				"Manticoil" => Random.Range(configuration.ManticoilMin.Value, configuration.ManticoilMax.Value + 1), 
				"Tulip Snakes" => Random.Range(configuration.TulipSnakesMin.Value, configuration.TulipSnakesMax.Value + 1), 
				_ => Mathf.RoundToInt(enemyType.PowerLevel * 50f), 
			};
		}

		public static void SpawnBountyReward(Vector3 position, int bountyValue, EnemyType enemyType, bool fullClear = false)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			RoundManager instance = RoundManager.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.currentLevel == (Object)null)
			{
				return;
			}
			List<SpawnableItemWithRarity> spawnableScrap = instance.currentLevel.spawnableScrap;
			if (spawnableScrap == null || spawnableScrap.Count == 0)
			{
				Plugin.Instance.logger.LogWarning((object)"No scrap available for bounty reward.");
				return;
			}
			Item val = null;
			float num = spawnableScrap.Sum((SpawnableItemWithRarity x) => x.spawnableItem.weight);
			spawnableScrap.Shuffle();
			for (int num2 = 0; num2 < spawnableScrap.Count; num2++)
			{
				Item spawnableItem = spawnableScrap[num2].spawnableItem;
				if (Random.Range(0f, num) < spawnableItem.weight)
				{
					val = spawnableItem;
					break;
				}
				num -= spawnableItem.weight;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val.spawnPrefab, position, Quaternion.identity);
			GrabbableObject component = val2.GetComponent<GrabbableObject>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val2);
				return;
			}
			component.SetScrapValue(bountyValue);
			if (!fullClear)
			{
				BountyRewardData bountyRewardData = val2.AddComponent<BountyRewardData>();
				bountyRewardData.EnemyName = GetDisplayName(enemyType);
				bountyRewardData.Value = bountyValue;
				bountyRewardData.Grabbable = component;
			}
			if (Plugin.Instance.Configuration.OverrideScrapWeight.Value)
			{
				component.itemProperties.weight = 1f;
			}
			NetworkObject component2 = val2.GetComponent<NetworkObject>();
			if (component2 != null)
			{
				component2.Spawn(false);
			}
			Plugin.Instance.logger.LogInfo((object)("Spawned bounty reward: " + component.itemProperties.itemName + " " + $"worth ${bountyValue}"));
		}

		public static void Shuffle<T>(this List<T> list)
		{
			for (int num = list.Count - 1; num > 0; num--)
			{
				int num2 = Random.Range(0, num + 1);
				int index = num;
				int index2 = num2;
				T value = list[num2];
				T value2 = list[num];
				list[index] = value;
				list[index2] = value2;
			}
		}

		public static float GetKillStreakMultiplier()
		{
			int num = Mathf.Max(0, KillStreak - 1);
			return 1f + (float)num * 0.1f;
		}

		public static int ApplyKillStreak(int baseValue)
		{
			float killStreakMultiplier = GetKillStreakMultiplier();
			return Mathf.RoundToInt((float)baseValue * killStreakMultiplier);
		}

		public static void ResetKillStreak()
		{
			if (KillStreak > 0)
			{
				HUDManager.Instance.AddTextToChatOnServer("<color=#dd0000>Kill Streak lost!</color>", -1);
				Plugin.Instance.logger.LogInfo((object)$"Kill streak lost! Previous streak: {KillStreak}");
				KillStreak = 0;
				BountyNetworking.SyncBounty();
			}
		}

		public static string GetBountyBoardText()
		{
			BountyBoardSyncData syncedBoard = BountyNetworking.SyncedBoard;
			if (syncedBoard == null || syncedBoard.Moons == null || syncedBoard.Moons.Count == 0)
			{
				return "\n=== BOUNTY BOARD ===\n\nNo bounties are currently available.\n\n";
			}
			string text = "\n=== BOUNTY BOARD ===\n\n";
			foreach (MoonBountySyncData moon in syncedBoard.Moons)
			{
				if (moon == null)
				{
					continue;
				}
				BountyType bountyType = (BountyType)moon.BountyType;
				text = text + moon.MoonName + "\n";
				text = text + "  " + GetBountyTypeDisplayName(bountyType) + "\n";
				if (moon.Targets == null || moon.Targets.Count == 0)
				{
					text += "  No valid targets\n\n";
					continue;
				}
				foreach (string target in moon.Targets)
				{
					text = text + "  " + target;
					if (bountyType == BountyType.Assassination)
					{
						text += $" [x{moon.AssassinationMultiplier:0.##}]";
					}
					text += "\n";
				}
				text += "\n";
			}
			return text;
		}

		public static int GetCurrentAssassinationMultiplier(SelectableLevel level)
		{
			int num = level.maxEnemyPowerCount + level.maxOutsideEnemyPowerCount;
			return num / 3;
		}

		public static string GetBountyTypeDisplayName(BountyType type)
		{
			return type switch
			{
				BountyType.Indoor => "Indoor Bounty", 
				BountyType.Outdoor => "Outdoor Bounty", 
				BountyType.Daytime => "Daytime Bounty", 
				BountyType.Assassination => "Assassination Bounty", 
				_ => "Bounty", 
			};
		}

		public static string GetDisplayName(EnemyType enemyType)
		{
			if ((Object)(object)enemyType == (Object)null)
			{
				return "Unknown";
			}
			return enemyType.enemyName switch
			{
				"Centipede" => "Snare Flea", 
				"Flowerman" => "Bracken", 
				"Crawler" => "Thumper", 
				"Stingray" => "Backwater Gunkfish", 
				"Hoarding bug" => "Hoarding Bug", 
				"Clay Surgeon" => "Barber", 
				"Blob" => "Hygrodere", 
				"Puffer" => "Spore Lizard", 
				"Spring" => "Coil-head", 
				"Docile Locust Bees" => "Roaming Locusts", 
				"MouthDog" => "Eyeless Dog", 
				"ForestGiant" => "Forest Keeper", 
				"Baboon hawk" => "Baboon Hawk", 
				"RadMech" => "Old Bird", 
				"Girl" => "Ghost Girl", 
				"GiantKiwi" => "Giant Sapsucker", 
				"Red Locust Bees" => "Circuit Bees", 
				_ => enemyType.enemyName, 
			};
		}

		public static string GetBountyScanText()
		{
			GrabbableObject[] source = Object.FindObjectsOfType<GrabbableObject>();
			int num = 0;
			string text = "";
			BountySyncData data = BountyNetworking.SyncedBounty;
			if (data != null && data.ScanEntries != null)
			{
				foreach (BountyScanEntry entry in data.ScanEntries)
				{
					int num2 = data.Targets.Select((string name, int index) => new { name, index }).Count(x => x.name == entry.EnemyName && x.index < data.Defeated.Count && !data.Defeated[x.index]);
					text += $"{entry.EnemyName} x{num2} - ${entry.Value}\n";
					num += entry.Value;
				}
			}
			List<GrabbableObject> list = source.Where((GrabbableObject x) => (Object)(object)x != (Object)null && (Object)(object)x.itemProperties != (Object)null && x.itemProperties.itemName == "Key" && !x.isInShipRoom).ToList();
			if (list.Count > 0)
			{
				int num3 = list.Count * 3;
				text += $"Key x{list.Count} - ${num3}\n";
				num += num3;
			}
			if (string.IsNullOrEmpty(text))
			{
				return "Full Cleared!\n";
			}
			return text + $"\nTotal Value - ${num}";
		}

		public static int GetFullClearRewardValue()
		{
			if (FullClearTargetCount <= 0)
			{
				return 0;
			}
			return Mathf.RoundToInt((float)FullClearValueTotal / (float)FullClearTargetCount);
		}

		public static string GetBountyHUDText()
		{
			MoonBounty currentBounty = CurrentBounty;
			if (currentBounty == null || currentBounty.Targets == null || currentBounty.Targets.Count == 0)
			{
				return "";
			}
			string text = "";
			if (KillStreak > 0)
			{
				text = text + $"KILL STREAK: {KillStreak}\n" + $"x{GetKillStreakMultiplier():0.00} BOUNTY\n\n";
			}
			text = text + GetBountyTypeDisplayName(currentBounty.Type).ToUpper() + "\n";
			Dictionary<EnemyType, int> dictionary = new Dictionary<EnemyType, int>();
			if (BountyTargetsSpawned)
			{
				foreach (EnemyAI key in ActiveBounties.Keys)
				{
					if (!((Object)(object)key == (Object)null) && !((Object)(object)key.enemyType == (Object)null))
					{
						if (!dictionary.ContainsKey(key.enemyType))
						{
							dictionary[key.enemyType] = 0;
						}
						dictionary[key.enemyType]++;
					}
				}
			}
			Dictionary<EnemyType, int> dictionary2 = new Dictionary<EnemyType, int>();
			foreach (EnemyType target in currentBounty.Targets)
			{
				if ((Object)(object)target == (Object)null)
				{
					continue;
				}
				bool flag = false;
				if (BountyTargetsSpawned)
				{
					dictionary.TryGetValue(target, out var value);
					dictionary2.TryGetValue(target, out var value2);
					if (value2 < value)
					{
						dictionary2[target] = value2 + 1;
					}
					else
					{
						flag = true;
					}
				}
				string text2 = GetDisplayName(target);
				if (currentBounty.Type == BountyType.Assassination)
				{
					text2 += " [x5]";
				}
				text += (flag ? (text2 + " [X]\n") : (text2 + " [ ]\n"));
			}
			if (currentBounty.IndoorThreats.Count > 0 || currentBounty.OutdoorThreats.Count > 0)
			{
				text += "\nTHREATS\n";
				foreach (IGrouping<EnemyType, EnemyType> item in from x in currentBounty.IndoorThreats.Concat(currentBounty.OutdoorThreats)
					group x by x)
				{
					text = text + GetDisplayName(item.Key) + " " + $"x{item.Count()}\n";
				}
			}
			return text;
		}

		public static string GetSyncedBountyHUDText()
		{
			BountySyncData syncedBounty = BountyNetworking.SyncedBounty;
			if (syncedBounty == null || syncedBounty.Targets.Count == 0)
			{
				return "";
			}
			string text = "";
			if (syncedBounty.KillStreak > 0)
			{
				int num = Mathf.Max(0, syncedBounty.KillStreak - 1);
				float num2 = 1f + (float)num * 0.1f;
				text = text + $"KILL STREAK: {syncedBounty.KillStreak}\n" + $"x{num2:0.00} BOUNTY\n\n";
			}
			text = text + GetBountyTypeDisplayName((BountyType)syncedBounty.BountyType).ToUpper() + "\n";
			for (int i = 0; i < syncedBounty.Targets.Count; i++)
			{
				bool flag = i < syncedBounty.Defeated.Count && syncedBounty.Defeated[i];
				text += (flag ? (syncedBounty.Targets[i] + " [X]\n") : (syncedBounty.Targets[i] + " [ ]\n"));
			}
			if (syncedBounty.Threats.Count > 0)
			{
				text += "\nTHREATS\n";
				foreach (string threat in syncedBounty.Threats)
				{
					text = text + threat + "\n";
				}
			}
			return text;
		}
	}
	public class BountyRewardData : MonoBehaviour
	{
		public string EnemyName;

		public int Value;

		public GrabbableObject Grabbable;
	}
	public enum BountyType
	{
		Indoor,
		Outdoor,
		Assassination,
		Daytime
	}
	public class MoonBounty
	{
		public BountyType Type;

		public List<EnemyType> Targets = new List<EnemyType>();

		public List<EnemyType> IndoorThreats = new List<EnemyType>();

		public List<EnemyType> OutdoorThreats = new List<EnemyType>();
	}
	[Serializable]
	public class BountySyncData
	{
		public int BountyType;

		public int KillStreak;

		public bool TargetsSpawned;

		public List<string> Targets = new List<string>();

		public List<bool> Defeated = new List<bool>();

		public List<string> Threats = new List<string>();

		public List<BountyScanEntry> ScanEntries = new List<BountyScanEntry>();
	}
	[Serializable]
	public class MoonBountySyncData
	{
		public string MoonName;

		public int BountyType;

		public float AssassinationMultiplier;

		public float BountyPower;

		public List<string> Targets = new List<string>();

		public List<string> Threats = new List<string>();
	}
	[Serializable]
	public class BountyScanEntry
	{
		public string EnemyName;

		public int Value;
	}
	[Serializable]
	public class BountyBoardSyncData
	{
		public List<MoonBountySyncData> Moons = new List<MoonBountySyncData>();
	}
	public static class BountyNetworking
	{
		public static BountySyncData SyncedBounty = new BountySyncData();

		public static BountyBoardSyncData SyncedBoard = new BountyBoardSyncData();

		private static LNetworkVariable<BountyBoardSyncData> bountyBoardVariable;

		private static LNetworkVariable<BountySyncData> bountyVariable;

		private static LNetworkMessage<bool> resetKillStreakMessage;

		public static void Initialize()
		{
			bountyVariable = LNetworkVariable<BountySyncData>.Create("LethalBounties_BountySync", new BountySyncData(), (LNetworkVariableWritePerms)0, (Action<BountySyncData, BountySyncData>)OnBountyChanged);
			bountyBoardVariable = LNetworkVariable<BountyBoardSyncData>.Create("LethalBounties_BountyBoard", new BountyBoardSyncData(), (LNetworkVariableWritePerms)0, (Action<BountyBoardSyncData, BountyBoardSyncData>)OnBountyBoardChanged);
			bountyBoardVariable.OnInitialized += OnBoardInitialized;
			resetKillStreakMessage = LNetworkMessage<bool>.Connect("LethalBounties_ResetKillStreak", (Action<bool, ulong>)OnResetKillStreakReceived, (Action<bool>)null, (Action<bool, ulong>)null);
			bountyVariable.OnInitialized += OnInitialized;
			Plugin.Instance.logger.LogInfo((object)"[NETWORK] Bounty network variable created.");
		}

		private static void OnInitialized()
		{
			Plugin.Instance.logger.LogInfo((object)"[NETWORK] Bounty network variable initialized.");
			if (bountyVariable.Value != null)
			{
				SyncedBounty = bountyVariable.Value;
			}
		}

		private static void OnBountyChanged(BountySyncData oldValue, BountySyncData newValue)
		{
			if (newValue != null)
			{
				SyncedBounty = newValue;
				Plugin.Instance.logger.LogInfo((object)("[NETWORK] Bounty updated | " + $"Type: {(BountyType)newValue.BountyType} | " + $"Targets: {newValue.Targets.Count} | " + $"Streak: {newValue.KillStreak}"));
			}
		}

		public static void SyncBounty()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || bountyVariable == null || !bountyVariable.IsInitialized)
			{
				return;
			}
			MoonBounty currentBounty = BountyManager.CurrentBounty;
			if (currentBounty == null)
			{
				return;
			}
			BountySyncData bountySyncData = new BountySyncData
			{
				BountyType = (int)currentBounty.Type,
				KillStreak = BountyManager.KillStreak,
				TargetsSpawned = BountyManager.BountyTargetsSpawned
			};
			Dictionary<EnemyType, int> dictionary = new Dictionary<EnemyType, int>();
			foreach (EnemyAI key in BountyManager.ActiveBounties.Keys)
			{
				if (!((Object)(object)key == (Object)null) && !((Object)(object)key.enemyType == (Object)null))
				{
					if (!dictionary.ContainsKey(key.enemyType))
					{
						dictionary[key.enemyType] = 0;
					}
					dictionary[key.enemyType]++;
				}
			}
			Dictionary<EnemyType, int> dictionary2 = new Dictionary<EnemyType, int>();
			foreach (EnemyType target in currentBounty.Targets)
			{
				bountySyncData.Targets.Add(BountyManager.GetDisplayName(target));
				dictionary.TryGetValue(target, out var value);
				dictionary2.TryGetValue(target, out var value2);
				bool flag = BountyManager.BountyTargetsSpawned && value2 >= value;
				bountySyncData.Defeated.Add(flag);
				if (!flag)
				{
					dictionary2[target] = value2 + 1;
				}
			}
			foreach (IGrouping<EnemyType, EnemyType> item in from x in currentBounty.IndoorThreats.Concat(currentBounty.OutdoorThreats)
				group x by x)
			{
				bountySyncData.Threats.Add($"{BountyManager.GetDisplayName(item.Key)} x{item.Count()}");
			}
			foreach (IGrouping<string, KeyValuePair<EnemyAI, int>> item2 in from x in BountyManager.ActiveBounties
				where (Object)(object)x.Key != (Object)null && (Object)(object)x.Key.enemyType != (Object)null && !x.Key.isEnemyDead
				group x by BountyManager.GetDisplayName(x.Key.enemyType))
			{
				bountySyncData.ScanEntries.Add(new BountyScanEntry
				{
					EnemyName = item2.Key,
					Value = item2.Sum((KeyValuePair<EnemyAI, int> x) => x.Value)
				});
			}
			SyncedBounty = bountySyncData;
			bountyVariable.Value = bountySyncData;
			Plugin.Instance.logger.LogInfo((object)("[NETWORK] Synced bounty | " + $"{currentBounty.Type} | {bountySyncData.Targets.Count} targets"));
		}

		public static void RequestKillStreakReset()
		{
			if (!((Object)(object)NetworkManager.Singleton == (Object)null))
			{
				if (NetworkManager.Singleton.IsServer)
				{
					BountyManager.ResetKillStreak();
				}
				else
				{
					resetKillStreakMessage.SendServer(true);
				}
			}
		}

		private static void OnResetKillStreakReceived(bool _, ulong clientId)
		{
			if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsServer)
			{
				Plugin.Instance.logger.LogInfo((object)$"Client {clientId} requested kill streak reset.");
				BountyManager.ResetKillStreak();
			}
		}

		public static void Clear()
		{
			SyncedBounty = new BountySyncData();
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && bountyVariable != null && bountyVariable.IsInitialized)
			{
				bountyVariable.Value = new BountySyncData();
			}
		}

		private static void OnBoardInitialized()
		{
			if (bountyBoardVariable.Value != null)
			{
				SyncedBoard = bountyBoardVariable.Value;
			}
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && BountyManager.MoonBounties.Count > 0)
			{
				SyncBountyBoard();
			}
		}

		private static void OnBountyBoardChanged(BountyBoardSyncData oldValue, BountyBoardSyncData newValue)
		{
			if (newValue != null)
			{
				SyncedBoard = newValue;
				Plugin.Instance.logger.LogInfo((object)$"[NETWORK] Bounty board updated | {newValue.Moons.Count} moons");
			}
		}

		public static void SyncBountyBoard()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || bountyBoardVariable == null || !bountyBoardVariable.IsInitialized)
			{
				return;
			}
			BountyBoardSyncData bountyBoardSyncData = new BountyBoardSyncData();
			foreach (KeyValuePair<SelectableLevel, MoonBounty> moonBounty in BountyManager.MoonBounties)
			{
				SelectableLevel key = moonBounty.Key;
				MoonBounty value = moonBounty.Value;
				if ((Object)(object)key == (Object)null || value == null)
				{
					continue;
				}
				MoonBountySyncData moonBountySyncData = new MoonBountySyncData
				{
					MoonName = CleanMoonName(key.PlanetName),
					BountyType = (int)value.Type,
					AssassinationMultiplier = BountyManager.GetCurrentAssassinationMultiplier(key),
					BountyPower = value.Targets.Sum((EnemyType x) => x.PowerLevel) + value.IndoorThreats.Sum((EnemyType x) => x.PowerLevel) + value.OutdoorThreats.Sum((EnemyType x) => x.PowerLevel)
				};
				foreach (IGrouping<EnemyType, EnemyType> item in from x in value.Targets
					group x by x)
				{
					moonBountySyncData.Targets.Add($"{BountyManager.GetDisplayName(item.Key)} x{item.Count()}");
				}
				foreach (IGrouping<EnemyType, EnemyType> item2 in from x in value.IndoorThreats.Concat(value.OutdoorThreats)
					group x by x)
				{
					moonBountySyncData.Threats.Add($"{BountyManager.GetDisplayName(item2.Key)} x{item2.Count()}");
				}
				bountyBoardSyncData.Moons.Add(moonBountySyncData);
			}
			SyncedBoard = bountyBoardSyncData;
			bountyBoardVariable.Value = bountyBoardSyncData;
			Plugin.Instance.logger.LogInfo((object)$"[NETWORK] Synced bounty board | {bountyBoardSyncData.Moons.Count} moons");
		}

		private static string CleanMoonName(string planetName)
		{
			if (string.IsNullOrWhiteSpace(planetName))
			{
				return "";
			}
			string text = planetName.Trim();
			int num = text.IndexOf(' ');
			if (num >= 0 && num < text.Length - 1)
			{
				string s = text.Substring(0, num);
				if (int.TryParse(s, out var _))
				{
					text = text.Substring(num + 1);
				}
			}
			return text.Trim();
		}
	}
	[BepInPlugin("Windyways.LethalBounties", "Lethal Bounties", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "Windyways.LethalBounties";

		private const string modName = "Lethal Bounties";

		private const string modVersion = "1.0.2";

		public readonly Harmony harmony = new Harmony("Windyways.LethalBounties");

		public static Plugin Instance;

		internal ManualLogSource logger;

		internal LethalBountiesConfig Configuration;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = ((BaseUnityPlugin)this).Logger;
			logger.LogInfo((object)" -- Lethal Bounties");
			logger.LogInfo((object)" | Registering Configuration Options...");
			Configuration = new LethalBountiesConfig(((BaseUnityPlugin)this).Config);
			Configuration.RegisterOptions();
			logger.LogInfo((object)" | Patching All...");
			BountyNetworking.Initialize();
			harmony.PatchAll();
			logger.LogInfo((object)" -- Monster Lethal Bounties Loaded Successfully!");
		}
	}
}
namespace LethalBounty.Patches
{
	[HarmonyPatch(typeof(HUDManager))]
	public static class BountyHUDPatch
	{
		private static TextMeshProUGUI bountyText;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(HUDManager __instance)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Instance.logger.LogInfo((object)"Creating Bounty HUD...");
			if ((Object)(object)__instance == (Object)null)
			{
				Plugin.Instance.logger.LogWarning((object)"HUDManager was null.");
				return;
			}
			if (__instance.controlTipLines == null || __instance.controlTipLines.Length == 0 || (Object)(object)__instance.controlTipLines[0] == (Object)null)
			{
				Plugin.Instance.logger.LogWarning((object)"Could not find controlTipLines font.");
				return;
			}
			Canvas componentInParent = ((Component)__instance.PTTIcon).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				Plugin.Instance.logger.LogWarning((object)"Could not find HUD Canvas.");
				return;
			}
			GameObject val = new GameObject("LethalBounties_BountyHUD");
			RectTransform val2 = val.AddComponent<RectTransform>();
			bountyText = val.AddComponent<TextMeshProUGUI>();
			((Transform)val2).SetParent(((Component)componentInParent).transform, false);
			val2.anchorMin = new Vector2(1f, 1f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(1f, 1f);
			val2.anchoredPosition = new Vector2(-25f, -120f);
			val2.sizeDelta = new Vector2(350f, 450f);
			((TMP_Text)bountyText).font = ((TMP_Text)__instance.controlTipLines[0]).font;
			((TMP_Text)bountyText).fontMaterial = ((TMP_Text)__instance.controlTipLines[0]).fontMaterial;
			((TMP_Text)bountyText).fontSize = Plugin.Instance.Configuration.BountyUISize.Value;
			((TMP_Text)bountyText).alignment = (TextAlignmentOptions)260;
			((Graphic)bountyText).color = Color.white;
			((TMP_Text)bountyText).enableWordWrapping = false;
			((TMP_Text)bountyText).richText = true;
			((Graphic)bountyText).raycastTarget = false;
			((TMP_Text)bountyText).text = "BOUNTY HUD TEST";
			val.transform.SetAsLastSibling();
			Plugin.Instance.logger.LogInfo((object)("Bounty HUD created on Canvas: " + ((Object)componentInParent).name));
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix()
		{
			if ((Object)(object)bountyText == (Object)null)
			{
				return;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase)
			{
				((Behaviour)bountyText).enabled = false;
				return;
			}
			((Behaviour)bountyText).enabled = true;
			BountySyncData syncedBounty = BountyNetworking.SyncedBounty;
			if (syncedBounty == null)
			{
				((TMP_Text)bountyText).text = "BOUNTY NET: NO DATA";
			}
			else if (syncedBounty.Targets == null || syncedBounty.Targets.Count == 0)
			{
				((TMP_Text)bountyText).text = "BOUNTY NET: EMPTY";
			}
			else
			{
				((TMP_Text)bountyText).text = BountyManager.GetSyncedBountyHUDText();
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager), "AssignRandomEnemyToVent")]
	public static class DisableNormalIndoorEnemySpawningPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(RoundManager), "SpawnDaytimeEnemiesOutside")]
	public static class DisableNormalDaytimeEnemySpawningPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(RoundManager), "SpawnEnemiesOutside")]
	public static class DisableNormalOutdoorEnemySpawningPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(RoundManager), "SpawnWeedEnemies")]
	public static class DisableNormalWeedEnemySpawningPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
	public static class DisableScrapSpawnPatch
	{
		[HarmonyPrefix]
		private static bool SpawnScrapInLevelPrefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "KillEnemy")]
	public static class EnemyDeathPatch
	{
		[HarmonyPostfix]
		private static void KillEnemyPostfix(EnemyAI __instance, bool destroy)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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)
			//IL_00cf: 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_00e1: 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)
			if ((Object)(object)__instance == (Object)null || destroy || (Object)(object)((NetworkBehaviour)__instance).NetworkManager == (Object)null || !((NetworkBehaviour)__instance).NetworkManager.IsServer || !BountyManager.ActiveBounties.TryGetValue(__instance, out var value))
			{
				return;
			}
			BountyManager.KillStreak++;
			int num = BountyManager.ApplyKillStreak(value);
			Plugin.Instance.logger.LogInfo((object)("Bounty completed: " + __instance.enemyType.enemyName + " | " + $"Base: ${value} | Streak: {BountyManager.KillStreak} | Reward: ${num}"));
			Vector3 position = ((Component)__instance).transform.position + Vector3.up * 0.5f;
			BountyManager.ActiveBounties.Remove(__instance);
			BountyManager.SpawnBountyReward(position, num, __instance.enemyType);
			if (BountyManager.ActiveBounties.Count == 0)
			{
				HUDManager.Instance.AddTextToChatOnServer("Bounty has been completed!", -1);
				if (Plugin.Instance.Configuration.FullClearReward.Value && BountyManager.CurrentBounty.Type != BountyType.Assassination)
				{
					int fullClearRewardValue = BountyManager.GetFullClearRewardValue();
					Plugin.Instance.logger.LogInfo((object)$"Full bounty cleared! Bonus reward: ${fullClearRewardValue}");
					BountyManager.SpawnBountyReward(position, fullClearRewardValue, __instance.enemyType, fullClear: true);
				}
			}
			BountyNetworking.SyncBounty();
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	public static class EnemySpawnPatch
	{
		private static bool spawnedBounties;

		private static List<EnemyVent> availableVents = new List<EnemyVent>();

		private static int nextVent;

		[HarmonyPatch("RefreshEnemyVents")]
		[HarmonyPostfix]
		private static void RefreshEnemyVentsPostfix(RoundManager __instance)
		{
			if (spawnedBounties || (Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).IsServer)
			{
				return;
			}
			MoonBounty currentBounty = BountyManager.CurrentBounty;
			if (currentBounty == null)
			{
				return;
			}
			PrepareVents(__instance);
			if ((currentBounty.Type == BountyType.Indoor || currentBounty.Type == BountyType.Assassination) && availableVents.Count == 0)
			{
				return;
			}
			spawnedBounties = true;
			Plugin.Instance.logger.LogInfo((object)$"Spawning {currentBounty.Type} bounty.");
			switch (currentBounty.Type)
			{
			case BountyType.Indoor:
				foreach (EnemyType target in currentBounty.Targets)
				{
					SpawnIndoorEnemy(__instance, target, registerAsBounty: true);
				}
				break;
			case BountyType.Outdoor:
				foreach (EnemyType target2 in currentBounty.Targets)
				{
					SpawnOutdoorEnemy(__instance, target2, registerAsBounty: true);
				}
				break;
			case BountyType.Daytime:
				foreach (EnemyType target3 in currentBounty.Targets)
				{
					SpawnOutdoorEnemy(__instance, target3, registerAsBounty: true);
				}
				break;
			case BountyType.Assassination:
			{
				float valueMultiplier = BountyManager.GetCurrentAssassinationMultiplier(__instance.currentLevel);
				foreach (EnemyType target4 in currentBounty.Targets)
				{
					SpawnIndoorEnemy(__instance, target4, registerAsBounty: true, valueMultiplier);
				}
				foreach (EnemyType indoorThreat in currentBounty.IndoorThreats)
				{
					SpawnIndoorEnemy(__instance, indoorThreat, registerAsBounty: false);
				}
				break;
			}
			}
			foreach (EnemyType outdoorThreat in currentBounty.OutdoorThreats)
			{
				SpawnOutdoorEnemy(__instance, outdoorThreat, registerAsBounty: false);
			}
			BountyManager.BountyTargetsSpawned = true;
			BountyNetworking.SyncBounty();
			Plugin.Instance.logger.LogInfo((object)("[SPAWN DEBUG] Finished bounty spawn. " + $"SpawnedEnemies count: {__instance.SpawnedEnemies.Count}"));
			foreach (EnemyAI spawnedEnemy in __instance.SpawnedEnemies)
			{
				if (!((Object)(object)spawnedEnemy == (Object)null))
				{
					Plugin.Instance.logger.LogInfo((object)("[SPAWN DEBUG] " + spawnedEnemy.enemyType.enemyName + " | " + $"NetworkObjectId: {((NetworkBehaviour)spawnedEnemy).NetworkObjectId} | " + $"IsServer: {((NetworkBehaviour)spawnedEnemy).IsServer} | " + $"IsSpawned: {((NetworkBehaviour)spawnedEnemy).IsSpawned}"));
				}
			}
		}

		private static void PrepareVents(RoundManager roundManager)
		{
			availableVents.Clear();
			nextVent = 0;
			if (roundManager.allEnemyVents != null)
			{
				availableVents = (from x in roundManager.allEnemyVents
					where (Object)(object)x != (Object)null && (Object)(object)x.floorNode != (Object)null
					orderby Random.value
					select x).ToList();
			}
		}

		private static EnemyVent GetNextVent()
		{
			if (availableVents.Count == 0)
			{
				return null;
			}
			EnemyVent result = availableVents[nextVent % availableVents.Count];
			nextVent++;
			return result;
		}

		private static void SpawnIndoorEnemy(RoundManager roundManager, EnemyType enemyType, bool registerAsBounty, float valueMultiplier = 1f)
		{
			//IL_0074: 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)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemyType == (Object)null)
			{
				return;
			}
			EnemyVent val = GetNextVent();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Instance.logger.LogWarning((object)("Could not spawn " + enemyType.enemyName + ": no indoor vents."));
				return;
			}
			Plugin.Instance.logger.LogInfo((object)("Spawning indoor enemy: " + enemyType.enemyName));
			GameObject val2 = NetworkObjectReference.op_Implicit(roundManager.SpawnEnemyGameObject(val.floorNode.position, val.floorNode.eulerAngles.y, val.enemyTypeIndex, enemyType));
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Instance.logger.LogWarning((object)("Failed to spawn " + enemyType.enemyName + "."));
				return;
			}
			val.OpenVentClientRpc();
			RegisterEnemy(val2, enemyType, registerAsBounty, valueMultiplier);
		}

		private static void SpawnOutdoorEnemy(RoundManager roundManager, EnemyType enemyType, bool registerAsBounty, float valueMultiplier = 1f)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemyType == (Object)null)
			{
				return;
			}
			if (roundManager.outsideAINodes == null || roundManager.outsideAINodes.Length == 0)
			{
				Plugin.Instance.logger.LogWarning((object)("Could not spawn " + enemyType.enemyName + ": no outside AI nodes."));
				return;
			}
			GameObject val = roundManager.outsideAINodes[Random.Range(0, roundManager.outsideAINodes.Length)];
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 randomNavMeshPositionInRadius = roundManager.GetRandomNavMeshPositionInRadius(val.transform.position, 4f, default(NavMeshHit));
				Plugin.Instance.logger.LogInfo((object)("Spawning outdoor enemy: " + enemyType.enemyName));
				GameObject spawnedEnemy = NetworkObjectReference.op_Implicit(roundManager.SpawnEnemyGameObject(randomNavMeshPositionInRadius, Random.Range(0f, 360f), -1, enemyType));
				RegisterEnemy(spawnedEnemy, enemyType, registerAsBounty, valueMultiplier);
			}
		}

		private static void RegisterEnemy(GameObject spawnedEnemy, EnemyType enemyType, bool registerAsBounty, float valueMultiplier)
		{
			if (registerAsBounty && !((Object)(object)spawnedEnemy == (Object)null))
			{
				EnemyAI component = spawnedEnemy.GetComponent<EnemyAI>();
				if (!((Object)(object)component == (Object)null))
				{
					int bountyValue = BountyManager.GetBountyValue(enemyType);
					int num = Mathf.RoundToInt((float)bountyValue * valueMultiplier);
					BountyManager.ActiveBounties[component] = num;
					BountyManager.FullClearValueTotal += num;
					BountyManager.FullClearTargetCount++;
					BountyManager.BountyTargetsSpawned = true;
					Plugin.Instance.logger.LogInfo((object)$"Registered bounty target: {enemyType.enemyName} worth ${num}");
				}
			}
		}

		public static void Reset()
		{
			spawnedBounties = false;
			availableVents.Clear();
			nextVent = 0;
			BountyManager.BountyTargetsSpawned = false;
			BountyManager.FullClearValueTotal = 0;
			BountyManager.FullClearTargetCount = 0;
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	public static class MoonPatch
	{
		[HarmonyPatch("LoadNewLevel")]
		[HarmonyPostfix]
		private static void LoadNewLevelPostfix(SelectableLevel newLevel)
		{
			EnemySpawnPatch.Reset();
			BountyManager.ActiveBounties.Clear();
			if (Plugin.Instance.Configuration.ResetKillStreakOnOrbit.Value)
			{
				BountyManager.KillStreak = 0;
			}
			if ((Object)(object)newLevel == (Object)null)
			{
				Plugin.Instance.logger.LogWarning((object)"Loaded level was null!");
			}
			else if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsServer)
			{
				Plugin.Instance.logger.LogInfo((object)("Loading bounty for " + newLevel.PlanetName));
				if (BountyManager.MoonBounties.TryGetValue(newLevel, out var value))
				{
					BountyManager.CurrentBounty = value;
					Plugin.Instance.logger.LogInfo((object)$"Loaded {value.Type} bounty.");
				}
				else
				{
					Plugin.Instance.logger.LogWarning((object)("No pre-generated bounty existed for " + newLevel.PlanetName + "; generating fallback."));
					BountyManager.CurrentBounty = BountyManager.GenerateBounty(newLevel);
				}
				LogCurrentBounty();
			}
		}

		private static void LogCurrentBounty()
		{
			MoonBounty currentBounty = BountyManager.CurrentBounty;
			Plugin.Instance.logger.LogInfo((object)$"BOUNTY TYPE: {currentBounty.Type}");
			foreach (EnemyType target in currentBounty.Targets)
			{
				Plugin.Instance.logger.LogInfo((object)("TARGET: " + target.enemyName));
			}
			foreach (EnemyType indoorThreat in currentBounty.IndoorThreats)
			{
				Plugin.Instance.logger.LogInfo((object)("INDOOR THREAT: " + indoorThreat.enemyName));
			}
			foreach (EnemyType outdoorThreat in currentBounty.OutdoorThreats)
			{
				Plugin.Instance.logger.LogInfo((object)("OUTDOOR THREAT: " + outdoorThreat.enemyName));
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public static class OrbitPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix()
		{
			Plugin.Instance.logger.LogInfo((object)"Generating initial bounty board.");
			BountyManager.GenerateAllMoonBounties();
		}

		[HarmonyPatch("ShipHasLeft")]
		[HarmonyPostfix]
		private static void ShipHasLeftPostfix()
		{
			Plugin.Instance.logger.LogInfo((object)"Ship has left the moon. Rerolling all bounties.");
			BountyManager.GenerateAllMoonBounties();
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	public static class PlayerPatch
	{
		[HarmonyPatch("DamagePlayer")]
		[HarmonyPostfix]
		private static void DamagePlayerPostfix(PlayerControllerB __instance, int damageNumber)
		{
			if (damageNumber > 0 && !((Object)(object)__instance != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				BountyNetworking.RequestKillStreakReset();
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public static class TerminalPatch
	{
		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPrefix]
		private static bool ParsePlayerSentencePrefix(Terminal __instance, ref TerminalNode __result)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Trim().ToLower();
			if (text == "scan")
			{
				TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
				val.displayText = BountyManager.GetBountyScanText();
				val.clearPreviousText = true;
				__result = val;
				return false;
			}
			if (text != "bounties" && text != "bounty")
			{
				return true;
			}
			TerminalNode val2 = ScriptableObject.CreateInstance<TerminalNode>();
			val2.displayText = BountyManager.GetBountyBoardText();
			val2.clearPreviousText = true;
			__result = val2;
			return false;
		}

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPostfix]
		private static void ParsePlayerSentencePostfix(Terminal __instance, ref TerminalNode __result)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__result == (Object)null)
			{
				return;
			}
			string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Trim().ToLower();
			if (!(text == "bounties") && !(text == "bounty") && !(text == "scan"))
			{
				MoonBountySyncData moonBountySyncData = FindBountyFromCommand(text);
				if (moonBountySyncData != null)
				{
					string text2 = BuildMoonBountyText(moonBountySyncData);
					TerminalNode val = Object.Instantiate<TerminalNode>(__result);
					val.displayText = __result.displayText + text2;
					__result = val;
				}
			}
		}

		private static MoonBountySyncData FindBountyFromCommand(string command)
		{
			if (string.IsNullOrWhiteSpace(command))
			{
				return null;
			}
			command = command.Trim().ToLower();
			if (command.Length < 3)
			{
				return null;
			}
			if (BountyNetworking.SyncedBoard == null || BountyNetworking.SyncedBoard.Moons == null)
			{
				return null;
			}
			List<MoonBountySyncData> list = BountyNetworking.SyncedBoard.Moons.Where((MoonBountySyncData x) => x != null && !string.IsNullOrWhiteSpace(x.MoonName) && x.MoonName.ToLower().StartsWith(command)).ToList();
			if (list.Count != 1)
			{
				return null;
			}
			return list[0];
		}

		private static string BuildMoonBountyText(MoonBountySyncData bounty)
		{
			BountyType bountyType = (BountyType)bounty.BountyType;
			string text = "\n\n=== " + GetBountyTypeName(bountyType) + " ===\n";
			if (bounty.Targets == null || bounty.Targets.Count == 0)
			{
				return text + "No valid bounty targets.\n";
			}
			if (bountyType == BountyType.Assassination)
			{
				text = text + "\nTARGET:\n" + bounty.Targets[0] + "\n" + $"Reward: x{bounty.AssassinationMultiplier:0.##} value\n";
				if (bounty.Threats != null && bounty.Threats.Count > 0)
				{
					text += "\nTHREATS:\n";
					foreach (string threat in bounty.Threats)
					{
						text = text + threat + "\n";
					}
				}
				return text;
			}
			foreach (string target in bounty.Targets)
			{
				text = text + target + "\n";
			}
			text += $"\nBounty Power: {bounty.BountyPower:0.##}\n";
			if (bounty.Threats != null && bounty.Threats.Count > 0)
			{
				text += "\nTHREATS:\n";
				foreach (string threat2 in bounty.Threats)
				{
					text = text + threat2 + "\n";
				}
			}
			return text;
		}

		private static string GetBountyTypeName(BountyType type)
		{
			return type switch
			{
				BountyType.Indoor => "INDOOR BOUNTY", 
				BountyType.Outdoor => "OUTDOOR BOUNTY", 
				BountyType.Daytime => "DAYTIME BOUNTY", 
				BountyType.Assassination => "ASSASSINATION", 
				_ => "BOUNTY", 
			};
		}
	}
}