Decompiled source of Expand World Spawns v1.9.0

ExpandWorldSpawns.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
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.Logging;
using Data;
using ExpandWorld.Spawn;
using ExpandWorldData;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ServerSync;
using Service;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ExpandWorldSpawns")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ExpandWorldSpawns")]
[assembly: AssemblyTitle("ExpandWorldSpawns")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ExpandWorld
{
	public class Configuration
	{
		public static CustomSyncedValue<string> valueSpawnData;

		public static void Init(ConfigWrapper wrapper)
		{
			valueSpawnData = wrapper.AddValue("spawn_data");
			((CustomSyncedValueBase)valueSpawnData).ValueChanged += delegate
			{
				Manager.FromSetting(valueSpawnData.Value);
			};
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public class SetCommands
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				Manager.Save();
			}
		}

		private static void Postfix()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate
				{
					Manager.Save();
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("ew_spawns", "Forces spawn file creation.", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	[BepInPlugin("expand_world_spawns", "Expand World Spawns", "1.9")]
	[BepInDependency("expand_world_data", "1.27")]
	public class EWS : BaseUnityPlugin
	{
		public const string GUID = "expand_world_spawns";

		public const string NAME = "Expand World Spawns";

		public const string VERSION = "1.9";

		public static ManualLogSource Log;

		public static ConfigSync ConfigSync = new ConfigSync("expand_world_spawns")
		{
			DisplayName = "Expand World Spawns",
			CurrentVersion = "1.9",
			ModRequired = true,
			IsLocked = true
		};

		public static void LogWarning(string message)
		{
			Log.LogWarning((object)message);
		}

		public static void LogError(string message)
		{
			Log.LogError((object)message);
		}

		public static void LogInfo(string message)
		{
			Log.LogInfo((object)message);
		}

		public void Awake()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Configuration.Init(new ConfigWrapper("expand_spawns_config", ((BaseUnityPlugin)this).Config, ConfigSync, (Action)delegate
			{
			}));
			new Harmony("expand_world_spawns").PatchAll();
			try
			{
				if (Configuration.DataReload)
				{
					Manager.SetupWatcher();
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex);
			}
		}
	}
}
namespace ExpandWorld.Spawn
{
	public class Loader
	{
		public static Dictionary<SpawnData, DataEntry?> Data = new Dictionary<SpawnData, DataEntry>();

		public static Dictionary<SpawnData, List<BlueprintObject>> Objects = new Dictionary<SpawnData, List<BlueprintObject>>();

		public static Dictionary<SpawnData, Data> ExtraData = new Dictionary<SpawnData, Data>();

		private static readonly int HashFaction = StringExtensionMethods.GetStableHashCode("faction");

		public static SpawnData FromData(Data data)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_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_0046: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Expected O, but got Unknown
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			SpawnData val = new SpawnData
			{
				m_prefab = DataManager.ToPrefab(data.prefab),
				m_name = data.name,
				m_enabled = data.enabled,
				m_biome = DataManager.ToBiomes(data.biome),
				m_biomeArea = DataManager.ToBiomeAreas(data.biomeArea),
				m_maxSpawned = data.maxSpawned,
				m_spawnInterval = data.spawnInterval,
				m_spawnChance = data.spawnChance,
				m_spawnDistance = data.spawnDistance,
				m_spawnRadiusMin = data.spawnRadiusMin,
				m_spawnRadiusMax = data.spawnRadiusMax,
				m_requiredGlobalKey = data.requiredGlobalKey,
				m_requiredEnvironments = DataManager.ToList(data.requiredEnvironments, true),
				m_groupSizeMin = data.groupSizeMin,
				m_groupSizeMax = data.groupSizeMax,
				m_spawnAtDay = data.spawnAtDay,
				m_spawnAtNight = data.spawnAtNight,
				m_groupRadius = data.groupRadius,
				m_minAltitude = data.minAltitude,
				m_maxAltitude = data.maxAltitude,
				m_minTilt = data.minTilt,
				m_maxTilt = data.maxTilt,
				m_inForest = data.inForest,
				m_outsideForest = data.outsideForest,
				m_minOceanDepth = data.minOceanDepth,
				m_maxOceanDepth = data.maxOceanDepth,
				m_huntPlayer = data.huntPlayer,
				m_groundOffset = data.groundOffset,
				m_maxLevel = data.maxLevel,
				m_minLevel = data.minLevel,
				m_levelUpMinCenterDistance = data.levelUpMinCenterDistance,
				m_overrideLevelupChance = data.overrideLevelupChance,
				m_inLava = data.inLava,
				m_outsideLava = data.outsideLava,
				m_canSpawnCloseToPlayer = data.canSpawnCloseToPlayer,
				m_insidePlayerBase = data.insidePlayerBase,
				m_groundOffsetRandom = data.groundOffsetRandom
			};
			if (val.m_minAltitude == -10000f)
			{
				val.m_minAltitude = ((val.m_maxAltitude > 0f) ? 0f : (-1000f));
			}
			if (data.data != "")
			{
				Data[val] = DataHelper.Get(data.data);
			}
			if (data.faction != "")
			{
				DataEntry val2 = new DataEntry
				{
					Strings = new Dictionary<int, IStringValue>()
				};
				val2.Strings[HashFaction] = DataValue.Simple(data.faction);
				if (Data.ContainsKey(val))
				{
					Data[val] = DataHelper.Merge((DataEntry[])(object)new DataEntry[2]
					{
						Data[val],
						val2
					});
				}
				else
				{
					Data.Add(val, val2);
				}
			}
			if (data.objects != null)
			{
				Objects[val] = data.objects.Select((string s) => Parse.Split(s, true, ',')).Select((Func<string[], BlueprintObject>)((string[] split) => new BlueprintObject(split[0], Parse.VectorXZY(split, 1), Quaternion.identity, Vector3.one, DataHelper.Get((split.Length > 5) ? split[5] : ""), Parse.Float(split, 4, 1f), false))).ToList();
			}
			if (data.minDistance != 0f || data.maxDistance != 0f)
			{
				ExtraData[val] = data;
			}
			return val;
		}

		public static Data ToData(SpawnData spawn)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			return new Data
			{
				prefab = ((Object)spawn.m_prefab).name,
				name = spawn.m_name,
				enabled = spawn.m_enabled,
				biome = DataManager.FromBiomes(spawn.m_biome),
				biomeArea = DataManager.FromBiomeAreas(spawn.m_biomeArea),
				maxSpawned = spawn.m_maxSpawned,
				spawnInterval = spawn.m_spawnInterval,
				spawnChance = spawn.m_spawnChance,
				spawnDistance = spawn.m_spawnDistance,
				spawnRadiusMin = spawn.m_spawnRadiusMin,
				spawnRadiusMax = spawn.m_spawnRadiusMax,
				requiredGlobalKey = spawn.m_requiredGlobalKey,
				requiredEnvironments = DataManager.FromList((IEnumerable<string>)spawn.m_requiredEnvironments),
				spawnAtDay = spawn.m_spawnAtDay,
				spawnAtNight = spawn.m_spawnAtNight,
				groupSizeMin = spawn.m_groupSizeMin,
				groupSizeMax = spawn.m_groupSizeMax,
				groupRadius = spawn.m_groupRadius,
				minAltitude = spawn.m_minAltitude,
				maxAltitude = spawn.m_maxAltitude,
				minTilt = spawn.m_minTilt,
				maxTilt = spawn.m_maxTilt,
				inForest = spawn.m_inForest,
				outsideForest = spawn.m_outsideForest,
				minOceanDepth = spawn.m_minOceanDepth,
				maxOceanDepth = spawn.m_maxOceanDepth,
				huntPlayer = spawn.m_huntPlayer,
				groundOffset = spawn.m_groundOffset,
				maxLevel = spawn.m_maxLevel,
				minLevel = spawn.m_minLevel,
				levelUpMinCenterDistance = spawn.m_levelUpMinCenterDistance,
				overrideLevelupChance = spawn.m_overrideLevelupChance,
				inLava = spawn.m_inLava,
				outsideLava = spawn.m_outsideLava,
				canSpawnCloseToPlayer = spawn.m_canSpawnCloseToPlayer,
				insidePlayerBase = spawn.m_insidePlayerBase,
				groundOffsetRandom = spawn.m_groundOffsetRandom
			};
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "Spawn")]
	public class SpawnZDO
	{
		private static void Prefix(SpawnData critter, Vector3 spawnPoint)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (Loader.Data.TryGetValue(critter, out DataEntry value))
			{
				DataHelper.Init(critter.m_prefab, spawnPoint, Quaternion.identity, (Vector3?)null, value);
			}
		}

		private static string PrefabOverride(string prefab)
		{
			return prefab;
		}

		private static DataEntry? DataOverride(DataEntry? data, string prefab)
		{
			return data;
		}

		private static void Postfix(SpawnData critter, Vector3 spawnPoint)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!Loader.Objects.TryGetValue(critter, out List<BlueprintObject> value))
			{
				return;
			}
			foreach (BlueprintObject item in value)
			{
				if (!(item.Chance < 1f) || !(Random.value > item.Chance))
				{
					Spawn.BPO(item, spawnPoint, Quaternion.identity, Vector3.one, (Func<DataEntry, string, DataEntry>)DataOverride, (Func<string, string>)PrefabOverride, (List<GameObject>)null);
				}
			}
		}
	}
	public class Manager
	{
		public static string FileName = "expand_spawns.yaml";

		public static string FilePath = Path.Combine(Yaml.Directory, FileName);

		public static string Pattern = "expand_spawns*.yaml";

		public static bool IsValid(SpawnData spawn)
		{
			return Object.op_Implicit((Object)(object)spawn.m_prefab);
		}

		public static string Save()
		{
			SpawnSystem val = SpawnSystem.m_instances.FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				return "";
			}
			IEnumerable<SpawnData> source = val.m_spawnLists.SelectMany((SpawnSystemList s) => s.m_spawners);
			string text = Yaml.Serializer().Serialize((object)source.Select(Loader.ToData).ToList());
			File.WriteAllText(FilePath, text);
			return text;
		}

		public static void ToFile()
		{
			if (!Helper.IsClient() && !File.Exists(FilePath))
			{
				string value = Save();
				Configuration.valueSpawnData.Value = value;
			}
		}

		public static void FromFile()
		{
			if (!Helper.IsClient())
			{
				string text = DataManager.Read(Pattern);
				Configuration.valueSpawnData.Value = text;
				Set(text);
			}
		}

		public static void FromSetting(string yaml)
		{
			if (HandleSpawnData.Override != null && Helper.IsClient())
			{
				Set(yaml);
			}
		}

		public static void Set(string yaml)
		{
			HandleSpawnData.Override = null;
			Loader.Data.Clear();
			Loader.Objects.Clear();
			Loader.ExtraData.Clear();
			if (yaml == "")
			{
				return;
			}
			try
			{
				List<SpawnData> list = Yaml.Deserialize<Data>(yaml, FileName).Select(Loader.FromData).Where(IsValid)
					.ToList();
				if (list.Count == 0)
				{
					EWS.LogWarning("Failed to load any spawn data.");
					return;
				}
				EWS.LogInfo($"Reloading spawn data ({list.Count} entries).");
				HandleSpawnData.Override = list;
				SpawnSystem.m_instances.ForEach(HandleSpawnData.Set);
			}
			catch (Exception ex)
			{
				EWS.LogError(ex.Message);
				EWS.LogError(ex.StackTrace);
			}
		}

		public static void SetupWatcher()
		{
			Yaml.SetupWatcher(Pattern, (Action)FromFile);
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "Start")]
	[HarmonyPriority(100)]
	public class InitializeContent
	{
		private static void Postfix()
		{
			HandleSpawnData.Override = null;
			if (Helper.IsServer())
			{
				Manager.FromFile();
			}
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "Awake")]
	public class HandleSpawnData
	{
		public static List<SpawnData>? Override;

		private static void Postfix(SpawnSystem __instance)
		{
			if (Override == null)
			{
				if (Helper.IsClient() && Configuration.valueSpawnData.Value != "")
				{
					Manager.Set(Configuration.valueSpawnData.Value);
				}
				if (Helper.IsServer())
				{
					Manager.ToFile();
				}
			}
			Set(__instance);
		}

		public static void Set(SpawnSystem system)
		{
			if (Override != null)
			{
				while (system.m_spawnLists.Count > 1)
				{
					system.m_spawnLists.RemoveAt(system.m_spawnLists.Count - 1);
				}
				system.m_spawnLists[0].m_spawners = Override;
			}
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "IsSpawnPointGood")]
	public class IsSpawnPointGood
	{
		private static bool Postfix(bool result, SpawnData spawn, Vector3 spawnPoint)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!result)
			{
				return false;
			}
			if (Loader.ExtraData.TryGetValue(spawn, out Data value))
			{
				float num = Utils.LengthXZ(spawnPoint);
				if (num < value.minDistance)
				{
					return false;
				}
				if (value.maxDistance > 0f && num > value.maxDistance)
				{
					return false;
				}
			}
			return result;
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "RPC_SetGlobalKey")]
	public class RPC_SetGlobalKey
	{
		private static bool Prefix(ZoneSystem __instance, string name)
		{
			string[] array = name.Trim().Split(new char[1] { ' ' });
			if (array.Length < 2)
			{
				return true;
			}
			string text = array[0].ToLower();
			if (!int.TryParse(array[1], out var result))
			{
				return true;
			}
			if (__instance.m_globalKeysValues.TryGetValue(text, out var value))
			{
				if (int.TryParse(value, out var result2))
				{
					__instance.m_globalKeysValues[text] = (result2 + result).ToString();
				}
				else
				{
					__instance.m_globalKeysValues[text] = array[1];
				}
			}
			else
			{
				__instance.m_globalKeys.Add(text);
				__instance.m_globalKeysValues.Add(text, array[1]);
			}
			__instance.SendGlobalKeys(ZRoutedRpc.Everybody);
			return false;
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "GetGlobalKey", new Type[] { typeof(string) })]
	public class GetGlobalKey
	{
		private static bool Prefix(ZoneSystem __instance, string name, ref bool __result)
		{
			string[] array = name.Trim().Split(new char[1] { ' ' });
			if (array.Length < 2)
			{
				return true;
			}
			if (!int.TryParse(array[1], out var result))
			{
				return true;
			}
			__result = HasKey(__instance, array[0].ToLower(), result);
			return false;
		}

		private static bool HasKey(ZoneSystem zs, string requiredKey, int requiredValue)
		{
			if (!zs.m_globalKeysValues.TryGetValue(requiredKey, out var value))
			{
				return false;
			}
			if (!int.TryParse(value, out var result))
			{
				return false;
			}
			return result >= requiredValue;
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "Spawn")]
	public class Spawn
	{
		private static void Postfix(SpawnData critter)
		{
			string[] array = critter.m_requiredGlobalKey.Trim().Split(new char[1] { ' ' });
			if (array.Length >= 2 && int.TryParse(array[1], out var result))
			{
				ZoneSystem.instance.SetGlobalKey($"{array[0]} {-result}");
			}
		}
	}
	public class Data
	{
		public string prefab = "";

		public bool enabled = true;

		[DefaultValue("")]
		public string name = "";

		[DefaultValue("")]
		public string biome = "";

		[DefaultValue("")]
		public string biomeArea = "";

		[DefaultValue(100f)]
		public float spawnChance = 100f;

		public int maxSpawned = 1;

		public float spawnInterval;

		[DefaultValue(1)]
		public int maxLevel = 1;

		[DefaultValue(1)]
		public int minLevel = 1;

		[DefaultValue(-10000f)]
		public float minAltitude = -10000f;

		[DefaultValue(10000f)]
		public float maxAltitude = 10000f;

		[DefaultValue(true)]
		public bool spawnAtDay = true;

		[DefaultValue(true)]
		public bool spawnAtNight = true;

		[DefaultValue("")]
		public string requiredGlobalKey = "";

		[DefaultValue("")]
		public string requiredEnvironments = "";

		public float spawnDistance = 10f;

		[DefaultValue(0f)]
		public float spawnRadiusMin;

		[DefaultValue(0f)]
		public float spawnRadiusMax;

		[DefaultValue(1)]
		public int groupSizeMin = 1;

		[DefaultValue(1)]
		public int groupSizeMax = 1;

		[DefaultValue(0f)]
		public float groupRadius;

		[DefaultValue(0f)]
		public float minTilt;

		[DefaultValue(35f)]
		public float maxTilt = 35f;

		[DefaultValue(true)]
		public bool inForest = true;

		[DefaultValue(true)]
		public bool outsideForest = true;

		[DefaultValue(false)]
		public bool canSpawnCloseToPlayer;

		[DefaultValue(false)]
		public bool insidePlayerBase;

		[DefaultValue(false)]
		public bool inLava;

		[DefaultValue(true)]
		public bool outsideLava = true;

		[DefaultValue(0f)]
		public float minOceanDepth;

		[DefaultValue(0f)]
		public float maxOceanDepth;

		[DefaultValue(false)]
		public bool huntPlayer;

		[DefaultValue(0.5f)]
		public float groundOffset = 0.5f;

		[DefaultValue(0f)]
		public float groundOffsetRandom;

		[DefaultValue(0f)]
		public float levelUpMinCenterDistance;

		[DefaultValue(-1f)]
		public float overrideLevelupChance = -1f;

		[DefaultValue(0f)]
		public float minDistance;

		[DefaultValue(0f)]
		public float maxDistance;

		[DefaultValue("")]
		public string faction = "";

		[DefaultValue("")]
		public string data = "";

		[DefaultValue(null)]
		public string[]? objects;
	}
}