Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LethalBounties v1.0.2
BepInEx/plugins/LethalBounty.dll
Decompiled 6 hours agousing 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", }; } } }