using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("SpawnableItems")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SpawnableItems")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("88eb7093-29b6-4240-b426-8f5de785c178")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SpawnableItems;
[BepInPlugin("Snowlance.SpawnableItems", "Spawnable Items", "1.0.0")]
public class SpawnableItemsBase : BaseUnityPlugin
{
private const string modGUID = "Snowlance.SpawnableItems";
private const string modName = "Spawnable Items";
private const string modVersion = "1.0.0";
private readonly Harmony harmony = new Harmony("Snowlance.SpawnableItems");
public static SpawnableItemsBase Instance;
public static ConfigEntry<bool> configShouldScrapSpawn;
public static ConfigEntry<string> configItemSpawnSequence;
public static ConfigEntry<bool> configIncludeDefensiveItems;
public static ConfigEntry<int> configMinItemsToSpawn;
public static ConfigEntry<int> configMaxItemsToSpawn;
public static ConfigEntry<string> configItemsToSpawn;
public static ManualLogSource LoggerInstance { get; private set; }
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
LoggerInstance = ((BaseUnityPlugin)this).Logger;
LoggerInstance.LogInfo((object)"Plugin Spawnable Items loaded successfully.");
configShouldScrapSpawn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShouldScrapSpawn", true, "Should items spawn when scrapping?\nIf set to false, ItemSpawnSequence will default to 'WithScrap' and items will just be added to the loot table");
configItemSpawnSequence = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ItemSpawnSequence", "WithScrap", "When should the items spawn? Accepted Values: BeforeScrap, WithScrap, AfterScrap\nSets the timing for item spawns relative to initial scrap spawning.");
configIncludeDefensiveItems = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludeDefensiveItems", true, "Should defensive items be included in the item spawning?\nYield Sign, Shotgun, Shells, etc.");
configMinItemsToSpawn = ((BaseUnityPlugin)this).Config.Bind<int>("Item Counts", "MinItemsToSpawn", 0, "Minimum number of items to spawn.");
configMaxItemsToSpawn = ((BaseUnityPlugin)this).Config.Bind<int>("Item Counts", "MaxItemsToSpawn", -1, "Maximum number of items to spawn.\n-1 for unlimited (ItemSpawnSequence will default to 'WithScrap' and items will just be added to the loot table)");
configItemsToSpawn = ((BaseUnityPlugin)this).Config.Bind<string>("Item Customization", "ItemsToSpawn", "", "Items to spawn with their rarity.\nIMPORTANT: This will fill with all items when the terminal is loaded in the game. MAKE SURE THIS IS EMPTY TO FILL WITH DEFAULT VALUES, run the game and load into a lobby, close the game and edit it here.\nFormat: ItemName:Rarity,ItemName:Rarity,ItemName:Rarity\nExample: Shotgun:1,YieldSign:2,Shells:3");
LoggerInstance.LogDebug((object)("configItemsToSpawn.Value = " + configItemsToSpawn.Value));
harmony.PatchAll();
}
}
[HarmonyPatch]
internal static class PatchHandler
{
private static SpawnableItemsBase Instance = SpawnableItemsBase.Instance;
private static readonly ManualLogSource LoggerInstance = SpawnableItemsBase.LoggerInstance;
private static float totalInverseItemsValue;
private static List<SpawnableItemWithRarity> defaultItemsToSpawn;
private static List<SpawnableItemWithRarity> itemsToSpawn;
private static string defaultItemsToSpawnString => string.Join(",", from itemWithRarity in GetDefaultItemsToSpawn()
select $"{itemWithRarity.spawnableItem.itemName}:{itemWithRarity.rarity}");
private static string itemsToSpawnString => string.Join(",", itemsToSpawn.Select((SpawnableItemWithRarity itemWithRarity) => $"{itemWithRarity.spawnableItem.itemName}:{itemWithRarity.rarity}"));
private static List<SpawnableItemWithRarity> GetDefaultItemsToSpawn()
{
if (defaultItemsToSpawn == null)
{
List<Item> source = StartOfRound.Instance.allItemsList.itemsList.Where((Item item) => (!item.isScrap && Object.op_Implicit((Object)(object)item.spawnPrefab)) || (SpawnableItemsBase.configIncludeDefensiveItems.Value && item.isDefensiveWeapon)).ToList();
return (from item in source
select GetSpawnableItemWithRarity(item) into item
where item != null
select item).ToList();
}
return defaultItemsToSpawn;
}
[HarmonyPatch(typeof(Terminal), "Awake")]
[HarmonyPostfix]
private static void TerminalAwakePostFix()
{
if (itemsToSpawn != null)
{
return;
}
try
{
string value = SpawnableItemsBase.configItemsToSpawn.Value;
if (value == "")
{
throw new Exception();
}
itemsToSpawn = new List<SpawnableItemWithRarity>();
string[] array = value.Split(new char[1] { ',' });
string[] array2 = array;
foreach (string text in array2)
{
string[] parts = text.Split(new char[1] { ':' });
Item val = StartOfRound.Instance.allItemsList.itemsList.Where((Item item) => item.itemName == parts[0]).First();
LoggerInstance.LogDebug((object)("tempSpawnableItem: " + val.itemName + ":" + parts[1]));
itemsToSpawn.Add(GetSpawnableItemWithRarity(val, int.Parse(parts[1])));
}
LoggerInstance.LogDebug((object)("List retrieved:\n" + itemsToSpawnString));
}
catch (Exception)
{
LoggerInstance.LogDebug((object)"Error parsing config string, using default values...");
if (itemsToSpawn != null)
{
itemsToSpawn.Clear();
LoggerInstance.LogDebug((object)"itemsToSpawn cleared");
}
itemsToSpawn = GetDefaultItemsToSpawn();
if (SpawnableItemsBase.configItemsToSpawn.Value == "")
{
SpawnableItemsBase.configItemsToSpawn.Value = itemsToSpawnString;
}
LoggerInstance.LogDebug((object)("Default list: " + itemsToSpawnString));
}
}
[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
[HarmonyPrefix]
private static void SpawnScrapInLevelPreFix(RoundManager __instance)
{
if (!SpawnableItemsBase.configShouldScrapSpawn.Value)
{
__instance.currentLevel.spawnableScrap.Clear();
}
if (SpawnableItemsBase.configItemSpawnSequence.Value == "WithScrap" || SpawnableItemsBase.configMaxItemsToSpawn.Value == -1 || !SpawnableItemsBase.configShouldScrapSpawn.Value)
{
__instance.currentLevel.spawnableScrap.AddRange(itemsToSpawn);
}
else if (SpawnableItemsBase.configItemSpawnSequence.Value == "BeforeScrap")
{
SpawnItemsInLevel();
}
}
[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
[HarmonyPostfix]
public static void SpawnScrapInLevelPostFix()
{
if (SpawnableItemsBase.configItemSpawnSequence.Value == "AfterScrap")
{
SpawnItemsInLevel();
}
}
private static void SpawnItemsInLevel()
{
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
try
{
if (SpawnableItemsBase.configMaxItemsToSpawn.Value == -1 || !(SpawnableItemsBase.configItemSpawnSequence.Value != "WithScrap") || !SpawnableItemsBase.configShouldScrapSpawn.Value)
{
return;
}
SpawnableItemWithRarity[] array = itemsToSpawn.ToArray();
int[] array2 = array.Select((SpawnableItemWithRarity f) => f.rarity).ToArray();
List<RandomScrapSpawn> list = (from s in Object.FindObjectsOfType<RandomScrapSpawn>()
where !s.spawnUsed
select s).ToList();
Random random = new Random(StartOfRound.Instance.randomMapSeed - 7);
int num = random.Next(SpawnableItemsBase.configMinItemsToSpawn.Value, SpawnableItemsBase.configMaxItemsToSpawn.Value);
LoggerInstance.LogDebug((object)$"Spawning {num} items in level");
for (int i = 0; i < num; i++)
{
if (list.Count <= 0)
{
break;
}
int index = random.Next(0, list.Count);
RandomScrapSpawn val = list[index];
Vector3 val2 = ((Component)val).transform.position;
if (val.spawnedItemsCopyPosition)
{
list.RemoveAt(index);
}
else
{
val2 = RoundManager.Instance.GetRandomNavMeshPositionInRadiusSpherical(((Component)val).transform.position, val.itemSpawnRange, RoundManager.Instance.navHit);
}
int randomWeightedIndex = RoundManager.Instance.GetRandomWeightedIndex(array2, random);
GameObject val3 = Object.Instantiate<GameObject>(array[randomWeightedIndex].spawnableItem.spawnPrefab, val2 + Vector3.up * 0.5f, Quaternion.identity, StartOfRound.Instance.propsContainer);
val3.GetComponent<GrabbableObject>().fallTime = 0f;
val3.GetComponent<NetworkObject>().Spawn(false);
}
}
catch (Exception ex)
{
LoggerInstance.LogError((object)("Unable to spawn all items, ERROR: " + ex));
}
}
private static SpawnableItemWithRarity GetSpawnableItemWithRarity(Item item)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
if (item.itemName == "Mapper" || item.itemName == "Binoculars" || item.itemName == "Key")
{
return null;
}
LoggerInstance.LogDebug((object)("Setting SpawnableItemWithRarity for item " + item.itemName));
return new SpawnableItemWithRarity
{
rarity = 50,
spawnableItem = item
};
}
private static SpawnableItemWithRarity GetSpawnableItemWithRarity(Item _item, int _rarity)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
LoggerInstance.LogDebug((object)$"Setting SpawnableItemWithRarity for item {_item.itemName}:{_rarity}");
return new SpawnableItemWithRarity
{
rarity = _rarity,
spawnableItem = _item
};
}
}