using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Ranensol.BepInEx.Aska.Woodcutting.Config;
using Ranensol.BepInEx.Aska.Woodcutting.Models;
using SSSGame;
using SandSailorStudio.Inventory;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Ranensol.BepInEx.Aska.Woodcutting")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.1+35193ebffc9aad8b48a1022a74120d61fa0b24c1")]
[assembly: AssemblyProduct("Ranensol Woodcutting")]
[assembly: AssemblyTitle("Ranensol.BepInEx.Aska.Woodcutting")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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;
}
}
}
namespace Ranensol.BepInEx.Aska.Woodcutting
{
public static class ConfigKeys
{
public const string Log = "Log";
public const string LongStick = "Long Stick";
public const string Stick = "Stick";
public const string Bark = "Bark";
public const string Resin = "Resin";
public const string Firewood = "Firewood";
public const string HardwoodLog = "Hardwood Log";
public const string HardwoodLongStick = "Hardwood Long Stick";
public const string Thatch = "Thatch";
public const string BarkFibres = "Fibers";
}
public static class ItemNames
{
public const string Log = "Item_Wood_RawLog";
public const string LongStick = "Item_Wood_RawLongStick";
public const string Stick = "Item_Wood_Sticks";
public const string Bark = "Item_Wood_Bark";
public const string Resin = "Item_Wood_Resin";
public const string Firewood = "Item_Wood_Firewood";
public const string HardwoodLog = "Item_Wood_HardWoodLog";
public const string HardwoodLongStick = "Item_Wood_HardWoodLongStick";
public const string Thatch = "Item_Wood_Thatch";
public const string BarkFibres = "Item_Wood_BarkFibres";
}
[BepInPlugin("Ranensol.BepInEx.Aska.Woodcutting", "Ranensol Woodcutting", "1.0.1")]
public class Plugin : BasePlugin
{
public override void Load()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Expected O, but got Unknown
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Expected O, but got Unknown
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Expected O, but got Unknown
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Ranensol Woodcutting");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.1");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loading...");
}
log.LogInfo(val);
ModConfig modConfig = new ModConfig(((BasePlugin)this).Config, ((BasePlugin)this).Log);
ManualLogSource log2 = ((BasePlugin)this).Log;
val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mod Enabled: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(modConfig.ModEnabled);
}
log2.LogInfo(val);
if (!modConfig.ModEnabled)
{
ManualLogSource log3 = ((BasePlugin)this).Log;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(69, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Ranensol Woodcutting");
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is DISABLED in config. No patches applied - using vanilla tree loot.");
}
log3.LogWarning(val2);
return;
}
ManualLogSource log4 = ((BasePlugin)this).Log;
val = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Verbose Logging: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(modConfig.VerboseLogging);
}
log4.LogInfo(val);
TreeLootSpawner.Initialize(((BasePlugin)this).Log, modConfig);
new Harmony("Ranensol.BepInEx.Aska.Woodcutting").PatchAll();
ManualLogSource log5 = ((BasePlugin)this).Log;
val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Ranensol Woodcutting");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded successfully!");
}
log5.LogInfo(val);
}
}
public static class TreeLootSpawner
{
private const float SpawnOffsetXZ = 0.3f;
private const float SpawnOffsetYMin = 0f;
private const float SpawnOffsetYMax = 3f;
private const int MaxProcessedSpawners = 1000;
private static readonly Dictionary<string, ItemInfo> _itemInfoCache = new Dictionary<string, ItemInfo>();
private static bool _hasSearchedItems = false;
private static readonly Queue<string> _processedSpawnersQueue = new Queue<string>(1000);
private static readonly HashSet<string> _processedSpawnersSet = new HashSet<string>();
private static readonly string[] ValidSpawnerNames = new string[4] { "TrunkSpawner", "StumpSpawner", "harvestSpawner", "HarvestInteraction" };
public static ModConfig Config { get; private set; }
public static ManualLogSource Logger { get; private set; }
public static void Initialize(ManualLogSource logger, ModConfig config)
{
Logger = logger;
Config = config;
}
public static bool IsValidSpawnerType(string gameObjName)
{
return ValidSpawnerNames.Any((string name) => gameObjName.Equals(name, StringComparison.OrdinalIgnoreCase));
}
public static (bool isTrunk, bool isStump, bool isRawWood) DetermineSpawnerType(string gameObjName, string parentName)
{
bool item = gameObjName.Equals("TrunkSpawner", StringComparison.OrdinalIgnoreCase) && ModConfig.IsProcessableTrunk(parentName);
bool item2 = gameObjName.Equals("StumpSpawner", StringComparison.OrdinalIgnoreCase) && ModConfig.IsProcessableStump(parentName);
bool item3 = (gameObjName.Equals("harvestSpawner", StringComparison.OrdinalIgnoreCase) || gameObjName.Equals("HarvestInteraction", StringComparison.OrdinalIgnoreCase)) && ModConfig.IsProcessableRawWood(parentName);
return (item, item2, item3);
}
public static string CreateSpawnerKey(string parentName, string gameObjName, Vector3 position)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
return $"{parentName}_{gameObjName}_{position.x:F3}_{position.y:F3}_{position.z:F3}";
}
public static bool ShouldProcessSpawner(string parentName)
{
if (!ModConfig.IsProcessableRawWood(parentName) && !ModConfig.IsProcessableTrunk(parentName))
{
return ModConfig.IsProcessableStump(parentName);
}
return true;
}
public static void MarkSpawnerAsProcessed(string spawnerKey)
{
if (_processedSpawnersSet.Add(spawnerKey))
{
_processedSpawnersQueue.Enqueue(spawnerKey);
if (_processedSpawnersQueue.Count > 1000)
{
string item = _processedSpawnersQueue.Dequeue();
_processedSpawnersSet.Remove(item);
}
}
}
public static bool IsSpawnerAlreadyProcessed(string spawnerKey)
{
return _processedSpawnersSet.Contains(spawnerKey);
}
public static void SpawnConfiguredLoot(GameObject parentObj, string gameObjName, string parentName, bool isTrunk, bool isRawWood)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
List<LootEntry> lootListForSpawner = GetLootListForSpawner(parentName, isTrunk, isRawWood);
if (lootListForSpawner == null)
{
return;
}
if (Config.VerboseLogging)
{
ManualLogSource logger = Logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(35, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Spawning loot for ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(gameObjName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" on ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(parentName);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at position ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(parentObj.transform.position);
}
logger.LogInfo(val);
}
foreach (LootEntry item in lootListForSpawner.Where((LootEntry e) => e.Quantity > 0))
{
SpawnLootEntry(parentObj.transform, item.ItemName, item.Quantity);
}
}
private static List<LootEntry> GetLootListForSpawner(string parentName, bool isTrunk, bool isRawWood)
{
if (isRawWood)
{
return Config.GetConfigForRawWood(parentName)?.Loot;
}
TreeLootConfig configForTree = Config.GetConfigForTree(parentName);
if (configForTree != null)
{
if (!isTrunk)
{
return configForTree.StumpLoot;
}
return configForTree.TrunkLoot;
}
return null;
}
private static void SpawnLootEntry(Transform spawnTransform, string itemName, int quantity)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
ItemInfo itemInfo = GetItemInfo(itemName);
bool flag = default(bool);
if ((Object)(object)itemInfo == (Object)null)
{
ManualLogSource logger = Logger;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not find ItemInfo for: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(itemName);
}
logger.LogWarning(val);
return;
}
if (Config.ShouldSpawnIndividually(itemName))
{
for (int i = 0; i < quantity; i++)
{
SpawnItemInWorld(spawnTransform, itemInfo, 1);
}
if (Config.VerboseLogging)
{
ManualLogSource logger2 = Logger;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Spawned: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(itemName);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" x");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(quantity);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (individual items)");
}
logger2.LogInfo(val2);
}
return;
}
SpawnItemInWorld(spawnTransform, itemInfo, quantity);
if (Config.VerboseLogging)
{
ManualLogSource logger3 = Logger;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(19, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Spawned: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(itemName);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" x");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(quantity);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (stack)");
}
logger3.LogInfo(val2);
}
}
private static void SpawnItemInWorld(Transform spawnTransform, ItemInfo itemInfo, int quantity)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(Random.Range(-0.3f, 0.3f), Random.Range(0f, 3f), Random.Range(-0.3f, 0.3f));
Vector3 val2 = spawnTransform.position + Vector3.up + val;
Quaternion identity = Quaternion.identity;
Vector3 one = Vector3.one;
ItemObjectSpawnContext val3 = (ItemObjectSpawnContext)1;
itemInfo.SpawnObject(ref val3, ref quantity, ref val2, ref identity, ref one, (Transform)null, true);
}
private static ItemInfo GetItemInfo(string itemName)
{
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
if (_itemInfoCache.TryGetValue(itemName, out var value))
{
return value;
}
if (!_hasSearchedItems)
{
_hasSearchedItems = true;
foreach (ItemInfo item in Resources.FindObjectsOfTypeAll<ItemInfo>())
{
if (((Object)item).name != null && !_itemInfoCache.ContainsKey(((Object)item).name))
{
_itemInfoCache[((Object)item).name] = item;
}
}
if (Config.VerboseLogging)
{
ManualLogSource logger = Logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cached ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_itemInfoCache.Count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ItemInfo objects");
}
logger.LogInfo(val);
}
}
_itemInfoCache.TryGetValue(itemName, out var value2);
return value2;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "Ranensol.BepInEx.Aska.Woodcutting";
public const string PLUGIN_NAME = "Ranensol Woodcutting";
public const string PLUGIN_VERSION = "1.0.1";
}
}
namespace Ranensol.BepInEx.Aska.Woodcutting.Patches
{
[HarmonyPatch(typeof(SubcomponentSpawner), "Run")]
public static class SubcomponentSpawnerPostfix
{
[HarmonyPostfix]
private static void Postfix(SubcomponentSpawner __instance)
{
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Expected O, but got Unknown
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
bool flag4 = default(bool);
try
{
if (!TreeLootSpawner.Config.ModEnabled)
{
return;
}
string name = ((Object)((Component)__instance).gameObject).name;
if (!TreeLootSpawner.IsValidSpawnerType(name))
{
return;
}
Transform parent = ((Component)__instance).transform.parent;
GameObject val = ((parent != null) ? ((Component)parent).gameObject : null);
if ((Object)(object)val == (Object)null)
{
return;
}
string name2 = ((Object)val).name;
if (!TreeLootSpawner.ShouldProcessSpawner(name2))
{
return;
}
var (flag, flag2, flag3) = TreeLootSpawner.DetermineSpawnerType(name, name2);
if (!flag && !flag2 && !flag3)
{
return;
}
string spawnerKey = TreeLootSpawner.CreateSpawnerKey(name2, name, val.transform.position);
if (TreeLootSpawner.IsSpawnerAlreadyProcessed(spawnerKey))
{
if (TreeLootSpawner.Config.VerboseLogging)
{
ManualLogSource logger = TreeLootSpawner.Logger;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(41, 2, ref flag4);
if (flag4)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Duplicate spawn attempt detected for ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" on ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name2);
}
logger.LogWarning(val2);
}
}
else
{
TreeLootSpawner.MarkSpawnerAsProcessed(spawnerKey);
TreeLootSpawner.SpawnConfiguredLoot(val, name, name2, flag, flag3);
}
}
catch (Exception ex)
{
ManualLogSource logger2 = TreeLootSpawner.Logger;
BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag4);
if (flag4)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Error in SubcomponentSpawner postfix: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
}
logger2.LogError(val3);
}
}
}
[HarmonyPatch(typeof(SubcomponentSpawner), "Run")]
public static class SubcomponentSpawnerPrefix
{
[HarmonyPrefix]
private static bool Prefix(SubcomponentSpawner __instance)
{
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Expected O, but got Unknown
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Expected O, but got Unknown
bool flag4 = default(bool);
try
{
if (!TreeLootSpawner.Config.ModEnabled)
{
return true;
}
string name = ((Object)((Component)__instance).gameObject).name;
if (!TreeLootSpawner.IsValidSpawnerType(name))
{
return true;
}
Transform parent = ((Component)__instance).transform.parent;
string text = ((parent != null) ? ((Object)((Component)parent).gameObject).name : null) ?? "";
if (!TreeLootSpawner.ShouldProcessSpawner(text))
{
return true;
}
var (flag, flag2, flag3) = TreeLootSpawner.DetermineSpawnerType(name, text);
if (!flag && !flag2 && !flag3)
{
return true;
}
if (TreeLootSpawner.Config.VerboseLogging)
{
ManualLogSource logger = TreeLootSpawner.Logger;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag4);
if (flag4)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Blocking vanilla spawning for ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" on ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
}
logger.LogInfo(val);
}
return false;
}
catch (Exception ex)
{
ManualLogSource logger2 = TreeLootSpawner.Logger;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(37, 1, ref flag4);
if (flag4)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Error in SubcomponentSpawner prefix: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
}
logger2.LogError(val2);
return true;
}
}
}
}
namespace Ranensol.BepInEx.Aska.Woodcutting.Models
{
public class LootEntry
{
public string ItemName { get; init; }
public int Quantity { get; init; }
public LootEntry(string itemName, int quantity)
{
ItemName = itemName;
Quantity = quantity;
base..ctor();
}
}
public class RawWoodLootConfig
{
public List<LootEntry> Loot { get; set; } = new List<LootEntry>();
}
public class TreeLootConfig
{
public List<LootEntry> TrunkLoot { get; set; } = new List<LootEntry>();
public List<LootEntry> StumpLoot { get; set; } = new List<LootEntry>();
}
}
namespace Ranensol.BepInEx.Aska.Woodcutting.Config
{
public class ModConfig
{
private readonly ConfigFile _config;
private readonly ManualLogSource _logger;
private const string SectionGeneral = "1 - General";
private const string SectionSpawn = "2 - SpawnMode";
private const string SectionYoungFirTrunk = "3a - YoungFir.Trunk";
private const string SectionYoungFirStump = "3b - YoungFir.Stump";
private const string SectionFirTrunk = "4a - Fir.Trunk";
private const string SectionFirStump = "4b - Fir.Stump";
private const string SectionBirchTrunk = "5a - Birch.Trunk";
private const string SectionBirchStump = "5b - Birch.Stump";
private const string SectionWillowTrunk = "6a - Willow.Trunk";
private const string SectionWillowStump = "6b - Willow.Stump";
private const string RawLogSection = "7a - RawLog";
private const string RawLongStickSection = "7b - RawLongStick";
private const string HardwoodLogSection = "8a - HardwoodLog";
private const string HardwoodLongStickSection = "8b - HardwoodLongStick";
private readonly Dictionary<string, bool> _spawnIndividually = new Dictionary<string, bool>();
private TreeLootConfig _firConfig;
private TreeLootConfig _youngFirConfig;
private TreeLootConfig _birchConfig;
private TreeLootConfig _willowConfig;
private RawWoodLootConfig _rawLogConfig;
private RawWoodLootConfig _rawLongStickConfig;
private RawWoodLootConfig _hardwoodLogConfig;
private RawWoodLootConfig _hardwoodLongStickConfig;
private static readonly string[] _youngFirTrunks = new string[2] { "Item_Wood_Fir3", "Item_Wood_Fir5" };
private static readonly string[] _youngFirStumps = new string[3] { "Item_Wood_TreeFir3Sapling", "Harvest_Wood_Fir3", "Harvest_Wood_Fir5" };
private static readonly string[] _adultFirTrunks = new string[3] { "Item_Wood_Fir1", "Item_Wood_Fir2", "Item_Wood_Fir4" };
private static readonly string[] _adultFirStumps = new string[1] { "Item_Wood_TreeFir2Sapling" };
private static readonly string[] _birchTrunks = new string[2] { "Item_Wood_birch1", "Item_Wood_birch2" };
private static readonly string[] _birchStumps = new string[1] { "Item_Wood_TreeBirch1Sapling" };
private static readonly string[] _rawWoodPrefixes = new string[4] { "Item_Wood_RawLog", "Item_Wood_RawLongStick", "Item_Wood_HardwoodLog", "Item_Wood_HardWooddLongStick" };
public bool ModEnabled { get; private set; }
public bool VerboseLogging { get; private set; }
public ModConfig(ConfigFile config, ManualLogSource logger)
{
_config = config;
_logger = logger;
InitializeGeneralConfig();
InitializeSpawnModeConfig();
InitializeConfig();
InitializeRawWoodConfig();
}
private void InitializeGeneralConfig()
{
_logger.LogInfo((object)"Initializing general configuration...");
ModEnabled = _config.Bind<bool>("1 - General", "ModEnabled", true, "Enable or disable the entire mod. Set to false to use vanilla loot.").Value;
VerboseLogging = _config.Bind<bool>("1 - General", "VerboseLogging", false, "Enable detailed logging for every tree/log/longstick harvested. Useful for debugging, but creates a lot of log entries.").Value;
}
private void InitializeSpawnModeConfig()
{
_logger.LogInfo((object)"Initializing spawn mode configuration...");
(string, string, bool)[] array = new(string, string, bool)[10]
{
("Item_Wood_RawLog", "LogsIndividual", true),
("Item_Wood_RawLongStick", "LongSticksIndividual", true),
("Item_Wood_Sticks", "SticksIndividual", true),
("Item_Wood_Bark", "BarkIndividual", true),
("Item_Wood_Resin", "ResinIndividual", false),
("Item_Wood_Firewood", "FirewoodIndividual", true),
("Item_Wood_HardWoodLog", "HardwoodLogsIndividual", true),
("Item_Wood_HardWoodLongStick", "HardwoodLongSticksIndividual", true),
("Item_Wood_Thatch", "ThatchIndividual", true),
("Item_Wood_BarkFibres", "BarkFibresIndividual", false)
};
for (int i = 0; i < array.Length; i++)
{
(string, string, bool) tuple = array[i];
_spawnIndividually[tuple.Item1] = _config.Bind<bool>("2 - SpawnMode", tuple.Item2, tuple.Item3, "Spawn " + tuple.Item1 + " individually (true) or as stacks (false)").Value;
}
}
private void InitializeConfig()
{
_logger.LogInfo((object)"Initializing tree loot configuration...");
_youngFirConfig = new TreeLootConfig
{
TrunkLoot = CreateLootList("3a - YoungFir.Trunk", new(string, string, int, string)[8]
{
("Log", "Item_Wood_RawLog", 0, "0"),
("Long Stick", "Item_Wood_RawLongStick", 3, "3"),
("Stick", "Item_Wood_Sticks", 7, "6"),
("Bark", "Item_Wood_Bark", 5, "4"),
("Resin", "Item_Wood_Resin", 10, "3"),
("Firewood", "Item_Wood_Firewood", 0, "0"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
}),
StumpLoot = CreateLootList("3b - YoungFir.Stump", new(string, string, int, string)[8]
{
("Log", "Item_Wood_RawLog", 0, "0"),
("Long Stick", "Item_Wood_RawLongStick", 0, "0"),
("Stick", "Item_Wood_Sticks", 0, "0"),
("Bark", "Item_Wood_Bark", 2, "0"),
("Resin", "Item_Wood_Resin", 5, "0"),
("Firewood", "Item_Wood_Firewood", 5, "2"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
_firConfig = new TreeLootConfig
{
TrunkLoot = CreateLootList("4a - Fir.Trunk", new(string, string, int, string)[8]
{
("Log", "Item_Wood_RawLog", 3, "3"),
("Long Stick", "Item_Wood_RawLongStick", 3, "3"),
("Stick", "Item_Wood_Sticks", 7, "7"),
("Bark", "Item_Wood_Bark", 6, "4"),
("Resin", "Item_Wood_Resin", 30, "3"),
("Firewood", "Item_Wood_Firewood", 0, "0"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
}),
StumpLoot = CreateLootList("4b - Fir.Stump", new(string, string, int, string)[8]
{
("Log", "Item_Wood_RawLog", 0, "0"),
("Long Stick", "Item_Wood_RawLongStick", 0, "0"),
("Stick", "Item_Wood_Sticks", 0, "0"),
("Bark", "Item_Wood_Bark", 4, "0"),
("Resin", "Item_Wood_Resin", 15, "0"),
("Firewood", "Item_Wood_Firewood", 10, "10"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
_birchConfig = new TreeLootConfig
{
TrunkLoot = CreateLootList("5a - Birch.Trunk", new(string, string, int, string)[8]
{
("Hardwood Log", "Item_Wood_HardWoodLog", 3, "2"),
("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 4, "3"),
("Stick", "Item_Wood_Sticks", 6, "6"),
("Bark", "Item_Wood_Bark", 8, "6"),
("Resin", "Item_Wood_Resin", 30, "0"),
("Firewood", "Item_Wood_Firewood", 0, "0"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
}),
StumpLoot = CreateLootList("5b - Birch.Stump", new(string, string, int, string)[8]
{
("Hardwood Log", "Item_Wood_HardWoodLog", 0, "0"),
("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 0, "0"),
("Stick", "Item_Wood_Sticks", 0, "0"),
("Bark", "Item_Wood_Bark", 5, "0"),
("Resin", "Item_Wood_Resin", 15, "0"),
("Firewood", "Item_Wood_Firewood", 10, "10"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
_willowConfig = new TreeLootConfig
{
TrunkLoot = CreateLootList("6a - Willow.Trunk", new(string, string, int, string)[8]
{
("Hardwood Log", "Item_Wood_HardWoodLog", 9, "5"),
("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 11, "7"),
("Stick", "Item_Wood_Sticks", 24, "14"),
("Bark", "Item_Wood_Bark", 16, "8"),
("Resin", "Item_Wood_Resin", 100, "0"),
("Firewood", "Item_Wood_Firewood", 0, "0"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
}),
StumpLoot = CreateLootList("6b - Willow.Stump", new(string, string, int, string)[8]
{
("Hardwood Log", "Item_Wood_HardWoodLog", 0, "0"),
("Hardwood Long Stick", "Item_Wood_HardWoodLongStick", 0, "0"),
("Stick", "Item_Wood_Sticks", 0, "0"),
("Bark", "Item_Wood_Bark", 12, "0"),
("Resin", "Item_Wood_Resin", 50, "0"),
("Firewood", "Item_Wood_Firewood", 25, "8"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
}
private void InitializeRawWoodConfig()
{
_logger.LogInfo((object)"Initializing raw wood loot configuration...");
_rawLogConfig = new RawWoodLootConfig
{
Loot = CreateLootList("7a - RawLog", new(string, string, int, string)[6]
{
("Stick", "Item_Wood_Sticks", 2, "4"),
("Bark", "Item_Wood_Bark", 6, "2"),
("Resin", "Item_Wood_Resin", 10, "0"),
("Firewood", "Item_Wood_Firewood", 8, "4"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
_rawLongStickConfig = new RawWoodLootConfig
{
Loot = CreateLootList("7b - RawLongStick", new(string, string, int, string)[6]
{
("Stick", "Item_Wood_Sticks", 4, "4"),
("Bark", "Item_Wood_Bark", 4, "2"),
("Resin", "Item_Wood_Resin", 5, "0"),
("Firewood", "Item_Wood_Firewood", 4, "2"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
_hardwoodLogConfig = new RawWoodLootConfig
{
Loot = CreateLootList("8a - HardwoodLog", new(string, string, int, string)[6]
{
("Stick", "Item_Wood_Sticks", 4, "5"),
("Bark", "Item_Wood_Bark", 8, "3"),
("Resin", "Item_Wood_Resin", 10, "0"),
("Firewood", "Item_Wood_Firewood", 8, "4"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
_hardwoodLongStickConfig = new RawWoodLootConfig
{
Loot = CreateLootList("8b - HardwoodLongStick", new(string, string, int, string)[6]
{
("Stick", "Item_Wood_Sticks", 3, "3"),
("Bark", "Item_Wood_Bark", 6, "3"),
("Resin", "Item_Wood_Resin", 5, "0"),
("Firewood", "Item_Wood_Firewood", 6, "4"),
("Thatch", "Item_Wood_Thatch", 0, "0"),
("Fibers", "Item_Wood_BarkFibres", 0, "0")
})
};
}
private List<LootEntry> CreateLootList(string section, (string configKey, string internalName, int defaultValue, string vanillaInfo)[] entries)
{
return entries.Select(((string configKey, string internalName, int defaultValue, string vanillaInfo) e) => new LootEntry(e.internalName, _config.Bind<int>(section, e.configKey, e.defaultValue, "Enter 0+, Vanilla: " + e.vanillaInfo).Value)).ToList();
}
public TreeLootConfig GetConfigForTree(string parentName)
{
if (_youngFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || _youngFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)))
{
return _youngFirConfig;
}
if (_adultFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || _adultFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || parentName.StartsWith("Harvest_Wood_Fir", StringComparison.OrdinalIgnoreCase))
{
return _firConfig;
}
if (_birchTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || _birchStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) || parentName.StartsWith("Harvest_Wood_birch", StringComparison.OrdinalIgnoreCase))
{
return _birchConfig;
}
if (!parentName.StartsWith("Item_Wood_Willow", StringComparison.OrdinalIgnoreCase) && !parentName.StartsWith("Harvest_Wood_Willow", StringComparison.OrdinalIgnoreCase))
{
return null;
}
return _willowConfig;
}
public RawWoodLootConfig GetConfigForRawWood(string parentName)
{
if (!parentName.StartsWith("Item_Wood_RawLog", StringComparison.OrdinalIgnoreCase))
{
if (!parentName.StartsWith("Item_Wood_RawLongStick", StringComparison.OrdinalIgnoreCase))
{
if (!parentName.StartsWith("Item_Wood_HardwoodLog", StringComparison.OrdinalIgnoreCase))
{
if (!parentName.StartsWith("Item_Wood_HardWooddLongStick", StringComparison.OrdinalIgnoreCase))
{
return null;
}
return _hardwoodLongStickConfig;
}
return _hardwoodLogConfig;
}
return _rawLongStickConfig;
}
return _rawLogConfig;
}
public static bool IsProcessableRawWood(string parentName)
{
return _rawWoodPrefixes.Any((string prefix) => parentName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
}
public static bool IsProcessableTrunk(string parentName)
{
if (!_youngFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_adultFirTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_birchTrunks.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)))
{
return parentName.StartsWith("Item_Wood_Willow", StringComparison.OrdinalIgnoreCase);
}
return true;
}
public static bool IsProcessableStump(string parentName)
{
if (!_youngFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_adultFirStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !_birchStumps.Any((string name) => parentName.Equals(name, StringComparison.OrdinalIgnoreCase)) && !parentName.StartsWith("Harvest_Wood_Fir", StringComparison.OrdinalIgnoreCase) && !parentName.StartsWith("Harvest_Wood_birch", StringComparison.OrdinalIgnoreCase))
{
return parentName.StartsWith("Harvest_Wood_Willow", StringComparison.OrdinalIgnoreCase);
}
return true;
}
public bool ShouldSpawnIndividually(string itemName)
{
if (_spawnIndividually.TryGetValue(itemName, out var value))
{
return value;
}
return true;
}
}
}