Decompiled source of RRRCore v3.1.5

RRRCore.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using RRRCore.monster;
using RRRCore.npc;
using RRRCore.prefabs._0_2_0;
using ServerSync;
using TMPro;
using UnityEngine;
using fastJSON;

[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDescription("Core library required by all of my other mods.")]
[assembly: AssemblyProduct("RRRCore")]
[assembly: AssemblyTitle("RRRCore")]
[assembly: ComVisible(false)]
[assembly: Guid("8B7B1E6C-A2ED-4DAD-AF54-3B4E181B93AF")]
[assembly: AssemblyFileVersion("3.1.5.0")]
[assembly: AssemblyCopyright("Copyright © 2021 Alexander Strada")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.1.5.0")]
[module: UnverifiableCode]
namespace RRRCore
{
	public static class Balance
	{
		public static class Tiers
		{
			public static List<string> ProgressionKeys = new string[5] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking" }.ToList();

			public static string ProgressionKey(int tier)
			{
				return ProgressionKeys[tier - 1];
			}
		}

		public static class Enemy
		{
			public static float[] BasicDamageArray = new float[6] { 14f, 25f, 48f, 70f, 110f, 130f };

			public static float[] BasicHealthArray = new float[6] { 30f, 50f, 100f, 150f, 200f, 300f };

			public static float BasicDamage(int tier)
			{
				return BasicDamageArray[tier - 1];
			}

			public static float BasicHealth(int tier)
			{
				return BasicHealthArray[tier - 1];
			}
		}

		public static class Food
		{
			public static readonly List<string> T1 = new string[5] { "CookedMeat", "Honey", "Mushroom", "NeckTailGrilled", "Raspberry" }.ToList();

			public static readonly List<string> T2 = new string[5] { "Blueberries", "Carrot", "CarrotSoup", "MushroomYellow", "QueensJam" }.ToList();

			public static readonly List<string> T3 = new string[3] { "Sausages", "Turnip", "TurnipStew" }.ToList();

			public static readonly List<string> T4 = new string[1] { "" }.ToList();

			public static readonly List<string> T5 = new string[5] { "BloodPudding", "Bread", "Cloudberry", "CookedLoxMeat", "LoxPie" }.ToList();

			private static readonly List<List<string>> Tiers = new List<List<string>>(new List<string>[5] { T1, T2, T3, T4, T5 });

			public static List<string> Exotic = new string[4] { "FishCooked", "FishWraps", "SerpentMeatCooked", "SerpentStew" }.ToList();

			public static List<string> AllAvailableAtTier(int tier)
			{
				List<string> allOut = new List<string>();
				return AllAvailableAtTier(tier, ref allOut);
			}

			public static List<string> AllAvailableAtTier(int tier, ref List<string> allOut)
			{
				for (int i = 0; i < tier; i++)
				{
					allOut.AddRange(Tiers[i]);
				}
				return allOut;
			}
		}
	}
	public static class ConfigsMonsters
	{
		private const string SECTION_MONSTERSENABLED = "MonstersEnabled";

		private static Dictionary<RRRMonsterName, RRRConfig<bool>> Config_MonstersEnabled;

		public static ConfigEntry<string> Config_ExportExistingPrefabs;

		public static bool IsMonsterEnabled(RRRMonsterName monsterName)
		{
			return Config_MonstersEnabled[monsterName].GetValue();
		}

		internal static void Awake()
		{
			Config_MonstersEnabled = new Dictionary<RRRMonsterName, RRRConfig<bool>>();
			foreach (RRRMonsterName item in Util.AllOf<RRRMonsterName>())
			{
				Config_MonstersEnabled.Add(item, RRRConfig.Bind(Plugin.ConfigFile, "MonstersEnabled", item.ToString(), defaultValue: true, RRRMonsterNameData.GetDesc(item)));
			}
			Config_ExportExistingPrefabs = Plugin.ConfigFile.Bind<string>("PrefabTemplateExports", "PrefabNames", "", "Comma-separated list of monster prefab names to export templates to your config folder. Should be able to export prefabs from other mods, but will not export other custom prefabs made with this mod.");
		}

		public static void LateLoadPrefabsMonsters()
		{
			if (Util.IsGameInMainScene())
			{
				if (IsMonsterEnabled(RRRMonsterName.RRR_GDThornweaver))
				{
					GDThornweaver.LateLoadGdThornweaver(RRRPrefabLoader.Clone(GDThornweaver.OriginalName, RRRMonsterName.RRR_GDThornweaver.ToString()));
				}
				if (IsMonsterEnabled(RRRMonsterName.RRR_GhostVengeful))
				{
					GhostVengeful.LateLoadGhostVengeful(RRRPrefabLoader.Clone(GhostVengeful.OriginalName, RRRMonsterName.RRR_GhostVengeful.ToString()));
				}
				if (IsMonsterEnabled(RRRMonsterName.RRR_TrollTosser))
				{
					TrollTosser.LateLoadTrollTosser(RRRPrefabLoader.Clone(TrollTosser.OriginalName, RRRMonsterName.RRR_TrollTosser.ToString()));
				}
				if (IsMonsterEnabled(RRRMonsterName.RRR_Grig))
				{
					Grig.LateLoadGrig();
				}
			}
		}
	}
	public enum RRRMonsterName
	{
		RRR_GDThornweaver,
		RRR_GhostVengeful,
		RRR_TrollTosser,
		RRR_Grig
	}
	public static class RRRMonsterNameData
	{
		public static string GetDesc(RRRMonsterName name)
		{
			return name switch
			{
				RRRMonsterName.RRR_GDThornweaver => "Tier3 Greydwarf Shaman variant. Ranged Specialist.", 
				RRRMonsterName.RRR_GhostVengeful => "Tier3 Ghost variant with increased speed and fire damage.", 
				RRRMonsterName.RRR_TrollTosser => "Tier3 Troll variant. Ranged Specialist.", 
				RRRMonsterName.RRR_Grig => "Tier4 fast melee hunter/chaser. High detection and can teleport to ambush prey.", 
				_ => throw new ArgumentOutOfRangeException("name", name, null), 
			};
		}
	}
	public static class ConfigsNpcs
	{
		private class EnablePlayerAppearanceFeaturesForNpcs : RRRTogglePatch
		{
			public EnablePlayerAppearanceFeaturesForNpcs()
			{
				Description = "Normally, non-players cannot display Hair, Beards, Skin Color, or Hair Color. Only change if you know what you are doing.";
			}

			[HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")]
			private static void Postfix(ref Humanoid __instance, VisEquipment visEq, bool isRagdoll)
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				if (Patch_EnablePlayerAppearanceFeaturesForNpcs.PatchIsEnabled() && visEq.m_isPlayer && !((Character)__instance).IsPlayer())
				{
					visEq.SetBeardItem(__instance.m_beardItem);
					visEq.SetHairItem(__instance.m_hairItem);
					if (isRagdoll)
					{
						VisEquipment component = ((Component)__instance).gameObject.GetComponent<VisEquipment>();
						visEq.SetSkinColor(component.m_skinColor);
						visEq.SetHairColor(component.m_hairColor);
					}
				}
			}
		}

		private const string SECTION_NPCSENABLED = "NpcsEnabled";

		private const string SECTION_OPTIONAL = "Features";

		private static RRRConfig<bool> Config_IsHostilesEnabled;

		public static RRRTogglePatch Patch_EnablePlayerAppearanceFeaturesForNpcs;

		public static bool IsHostilesEnabled()
		{
			return Config_IsHostilesEnabled.GetValue();
		}

		internal static void Awake(Harmony harmony)
		{
			Config_IsHostilesEnabled = RRRConfig.Bind(Plugin.ConfigFile, "NpcsEnabled", "Hostiles", defaultValue: true, "An all-tiers set of hostile NPC mobs.");
			Patch_EnablePlayerAppearanceFeaturesForNpcs = new EnablePlayerAppearanceFeaturesForNpcs().Bind(harmony, Plugin.ConfigFile, "Features");
		}

		public static void LateLoadPrefabsNpcs()
		{
			if (Util.IsGameInMainScene())
			{
				Npc.MakePrefab();
				if (IsHostilesEnabled())
				{
					Hostile.MakePrefabs();
				}
			}
		}
	}
	public static class RRRNpcName
	{
		public const string Npc = "RRR_NPC";

		public const string Hostile = "RRR_Hostile";

		public static string HostileTiered(int tier)
		{
			return string.Format("{0}_T{1}", "RRR_Hostile", tier);
		}
	}
	public class RRRConfig<T>
	{
		private readonly SyncedConfigEntry<T> syncedConfigEntry;

		public RRRConfig(ConfigFile config, string section, string key, T defaultValue, string description)
		{
			syncedConfigEntry = Plugin.ConfigSync.AddConfigEntry<T>(config.Bind<T>(section, key, defaultValue, description));
		}

		public string Key()
		{
			return ((ConfigEntryBase)syncedConfigEntry.SourceConfig).Definition.Key;
		}

		public T GetValue()
		{
			return syncedConfigEntry.Value;
		}
	}
	public static class RRRConfig
	{
		public static RRRConfig<T> Bind<T>(ConfigFile config, string section, string key, T defaultValue, string description)
		{
			return new RRRConfig<T>(config, section, key, defaultValue, description);
		}
	}
	public static class RRRReplaceRefHandler
	{
		private const string TAG_REPLACE_REF = "_RRR_REPLACEREF_";

		private const string TAG_REPLACE_PATH = "_RRR_REPLACEPATH_";

		private const char PATH_DELIMITER = '@';

		public static GameObject ProcessReplaceRefs(GameObject go)
		{
			MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>();
			foreach (MonoBehaviour obj in componentsInChildren)
			{
				ReplaceRefAllEffectLists(obj);
				((CharacterDrop)(((obj is CharacterDrop) ? obj : null)?)).m_drops.ForEach(delegate(Drop d)
				{
					if (d.IsNotNull() && d.m_prefab.IsNotNull())
					{
						d.m_prefab = TryReplaceRef(d.m_prefab);
					}
				});
				ItemDrop val = (ItemDrop)(object)((obj is ItemDrop) ? obj : null);
				if (val != null)
				{
					ReplaceRefAllEffectLists(val.m_itemData.m_shared);
					ReplaceRefAllEffectLists(val.m_itemData.m_shared.m_attack);
					ReplaceRefAllEffectLists(val.m_itemData.m_shared.m_secondaryAttack);
				}
			}
			return go;
		}

		private static void ReplaceRefAllEffectLists(object obj)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			FieldInfo[] fields = obj.GetType().GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType == typeof(EffectList))
				{
					fieldInfo.SetValue(obj, ReplaceRefEffectList((EffectList)fieldInfo.GetValue(obj)));
				}
			}
		}

		private static EffectList ReplaceRefEffectList(this EffectList effectList)
		{
			for (int i = 0; i < effectList.m_effectPrefabs.Length; i++)
			{
				GameObject prefab = effectList.m_effectPrefabs[i].m_prefab;
				if (prefab != null)
				{
					effectList.m_effectPrefabs[i].m_prefab = TryReplaceRef(prefab);
				}
			}
			return effectList;
		}

		private static GameObject TryReplaceRef(GameObject gameObject)
		{
			if (((Object)gameObject).name.StartsWith("_RRR_REPLACEREF_"))
			{
				return ReplaceRef(gameObject);
			}
			if (((Object)gameObject).name.StartsWith("_RRR_REPLACEPATH_"))
			{
				return ReplacePath(gameObject);
			}
			return gameObject;
		}

		private static GameObject ReplaceRef(GameObject replaceRef)
		{
			return GetRef(((Object)replaceRef).name.Substring("_RRR_REPLACEREF_".Length));
		}

		private static GameObject ReplacePath(GameObject replaceRef)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			string[] path = ((Object)replaceRef).name.Substring("_RRR_REPLACEPATH_".Length).Split(new char[1] { '@' });
			if (path.Length == 4)
			{
				GameObject @ref = GetRef(path[0]);
				if (@ref == null)
				{
					return null;
				}
				if (path[1] == "Humanoid")
				{
					MonoBehaviour component = (MonoBehaviour)(object)@ref.GetComponent<Humanoid>();
					FieldInfo fieldInfo = ((object)component).GetType().GetFields().First((FieldInfo fi) => fi.Name == path[2]);
					if ((object)fieldInfo == null || fieldInfo.FieldType != typeof(EffectList))
					{
						return null;
					}
					if (int.TryParse(path[3], out var result))
					{
						return ((EffectList)fieldInfo.GetValue(component)).m_effectPrefabs[result].m_prefab;
					}
					return null;
				}
				return null;
			}
			return null;
		}

		private static GameObject GetRef(string newName)
		{
			GameObject val = ZNetScene.instance.GetPrefab(newName);
			if (val == null)
			{
				val = ObjectDB.instance.GetItemPrefab(newName);
			}
			if (val == null)
			{
				Plugin.log.LogError((object)("Invalid ref '" + newName + "'"));
				return null;
			}
			return val;
		}

		internal static void TryFixSfxAudioMixerGroup(GameObject gameObject)
		{
			AudioSource component = gameObject.GetComponent<AudioSource>();
			if (component != null && component.outputAudioMixerGroup == null)
			{
				GameObject val = RRRPrefabLoader.FindName("sfx_neck_death");
				if (val.IsNotNull())
				{
					component.outputAudioMixerGroup = val.GetComponent<AudioSource>().outputAudioMixerGroup;
				}
				else
				{
					Plugin.log.LogWarning((object)"Couldn't find stock game sound to fix Audio Mixer Group.");
				}
			}
		}
	}
	public static class RRRMobItem
	{
		private static string MakeName(string ownerName, string weaponName, string ownerWeaponId)
		{
			return ownerName + "_" + weaponName + "_" + ownerWeaponId;
		}

		public static GameObject Get(string ownerName, string weaponName, int ownerWeaponId, float damage, string projectileName = null)
		{
			string newName = MakeName(ownerName, weaponName, ownerWeaponId.ToString());
			bool alreadyExisted = false;
			GameObject val = RRRPrefabLoader.CloneRepeatable(ref alreadyExisted, weaponName, newName, regZns: true, regOdb: true);
			if (alreadyExisted)
			{
				return val;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				throw new NullReferenceException("No ItemDrop component in prefab: " + weaponName);
			}
			SharedData shared = component.m_itemData.m_shared;
			shared.m_damages.RetuneDamage(damage);
			if (projectileName.NonEmpty())
			{
				shared.m_ammoType = "";
				shared.m_aiAttackRange = 25f;
				shared.m_aiAttackRangeMin = 0f;
				shared.m_aiAttackMaxAngle = 10f;
				shared.m_attackForce = 15f;
				((DamageTypes)(ref shared.m_damagesPerLevel)).Modify(0f);
				shared.m_attack.m_drawDurationMin = 0f;
				shared.m_attack.m_drawStaminaDrain = 20f;
				shared.m_attack.m_drawAnimationState = "";
				shared.m_secondaryAttack.m_drawDurationMin = 0f;
				shared.m_secondaryAttack.m_drawStaminaDrain = 20f;
				shared.m_secondaryAttack.m_drawAnimationState = "";
				shared.m_attack.m_speedFactor = 0f;
				shared.m_attack.m_speedFactorRotation = 0.5f;
				shared.m_attack.m_attackStartNoise = 20f;
				shared.m_attack.m_attackHitNoise = 30f;
				shared.m_attack.m_projectileVel = 30f;
				shared.m_attack.m_projectileVelMin = 2f;
				shared.m_attack.m_projectileAccuracy = 2f;
				shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab(projectileName);
			}
			return val;
		}

		public static GameObject GetNpcUnarmed(float damage)
		{
			string text = MakeName("RRR_NPC", "Unarmed", $"D{damage}");
			bool alreadyExisted = false;
			GameObject val = RRRPrefabLoader.CloneRepeatable(ref alreadyExisted, ((Component)((Humanoid)ZNetScene.instance.GetPrefab("Player").GetComponent<Player>()).m_unarmedWeapon).gameObject, text, regZns: true, regOdb: true);
			if (alreadyExisted)
			{
				return val;
			}
			SharedData shared = val.GetComponent<ItemDrop>().m_itemData.m_shared;
			shared.m_name = text;
			shared.m_damages.RetuneDamage(damage);
			return val;
		}
	}
	public static class RRRCustomMobDB
	{
		private static List<string> LocalJsons = new List<string>();

		private static List<RRRMobData> CustomMobs = new List<RRRMobData>();

		private static Dictionary<string, RRRMobData> MobDataDict = new Dictionary<string, RRRMobData>();

		private static Dictionary<string, Texture2D> TextureDict = new Dictionary<string, Texture2D>();

		internal static List<GameObject> CustomMobPrefabs = new List<GameObject>();

		internal static List<GameObject> CustomAttackPrefabs = new List<GameObject>();

		internal static bool TryGetTexture(string customTexture, out Texture2D texture)
		{
			return TextureDict.TryGetValue(customTexture, out texture);
		}

		internal static RRRMobData GetMobData(string newPrefabName)
		{
			if (MobDataDict.TryGetValue(newPrefabName, out var value))
			{
				return value;
			}
			Plugin.log.LogWarning((object)("Failed to find MobData for clone " + newPrefabName + ". This is highly unusual!"));
			return null;
		}

		internal static void MakePrefabs()
		{
			CustomMobs.Sort((RRRMobData data1, RRRMobData data2) => data1.sNewPrefabName.CompareTo(data2.sNewPrefabName));
			foreach (RRRMobData customMob in CustomMobs)
			{
				GameObject val = customMob.Make();
				if (val.IsNotNull())
				{
					MobDataDict.Add(customMob.sNewPrefabName, customMob);
					CustomMobPrefabs.Add(val);
				}
			}
			foreach (GameObject customMobPrefab in CustomMobPrefabs)
			{
				Humanoid component = customMobPrefab.GetComponent<Humanoid>();
				if (Object.op_Implicit((Object)(object)component))
				{
					EffectData[] effectPrefabs = ((Character)component).m_hitEffects.m_effectPrefabs;
					for (int i = 0; i < effectPrefabs.Length; i++)
					{
						ProcessPlaceholders(effectPrefabs[i]);
					}
					effectPrefabs = ((Character)component).m_deathEffects.m_effectPrefabs;
					for (int i = 0; i < effectPrefabs.Length; i++)
					{
						ProcessPlaceholders(effectPrefabs[i]);
					}
					effectPrefabs = component.m_consumeItemEffects.m_effectPrefabs;
					for (int i = 0; i < effectPrefabs.Length; i++)
					{
						ProcessPlaceholders(effectPrefabs[i]);
					}
				}
				BaseAI component2 = customMobPrefab.GetComponent<BaseAI>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					EffectData[] effectPrefabs = component2.m_idleSound.m_effectPrefabs;
					for (int i = 0; i < effectPrefabs.Length; i++)
					{
						ProcessPlaceholders(effectPrefabs[i]);
					}
					effectPrefabs = component2.m_alertedEffects.m_effectPrefabs;
					for (int i = 0; i < effectPrefabs.Length; i++)
					{
						ProcessPlaceholders(effectPrefabs[i]);
					}
				}
				MonsterAI component3 = customMobPrefab.GetComponent<MonsterAI>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					EffectData[] effectPrefabs = component3.m_wakeupEffects.m_effectPrefabs;
					for (int i = 0; i < effectPrefabs.Length; i++)
					{
						ProcessPlaceholders(effectPrefabs[i]);
					}
				}
			}
			CustomMobPrefabs.Clear();
			foreach (GameObject customAttackPrefab in CustomAttackPrefabs)
			{
				ItemDrop component4 = customAttackPrefab.GetComponent<ItemDrop>();
				EffectData[] effectPrefabs = component4.m_itemData.m_shared.m_startEffect.m_effectPrefabs;
				for (int i = 0; i < effectPrefabs.Length; i++)
				{
					ProcessPlaceholders(effectPrefabs[i]);
				}
				effectPrefabs = component4.m_itemData.m_shared.m_hitEffect.m_effectPrefabs;
				for (int i = 0; i < effectPrefabs.Length; i++)
				{
					ProcessPlaceholders(effectPrefabs[i]);
				}
				effectPrefabs = component4.m_itemData.m_shared.m_triggerEffect.m_effectPrefabs;
				for (int i = 0; i < effectPrefabs.Length; i++)
				{
					ProcessPlaceholders(effectPrefabs[i]);
				}
			}
			CustomAttackPrefabs.Clear();
		}

		private static void ProcessPlaceholders(EffectData effectData)
		{
			string text = "_PLACEHOLDER_";
			if ((Object)(object)effectData.m_prefab != (Object)null && ((Object)effectData.m_prefab).name.Contains(text))
			{
				string originalName = ((Object)effectData.m_prefab).name.Substring(text.Length);
				Object.Destroy((Object)(object)effectData.m_prefab);
				effectData.m_prefab = RRRPrefabLoader.FindName(originalName);
			}
		}

		public static List<string> Serialize()
		{
			return CustomMobs.Select((RRRMobData c) => JSON.ToNiceJSON(c, Util.JsonParameters)).ToList();
		}

		public static void Deserialize(List<string> serializedMobs)
		{
			CustomMobs.Clear();
			MobDataDict.Clear();
			for (int i = 0; i < serializedMobs.Count; i++)
			{
				string text = serializedMobs[i];
				try
				{
					CustomMobs.Add(JSON.ToObject<RRRMobData>(text, Util.JsonParameters));
				}
				catch (Exception ex)
				{
					LogDeserializationError(text, ex.Message);
				}
			}
		}

		public static void LoadLocalConfigs()
		{
			Plugin.ConfigFile.Reload();
			string[] files = Directory.GetFiles(Paths.ConfigPath, "rrr*.custom.*.json", SearchOption.AllDirectories);
			foreach (string text in files)
			{
				if (!text.Contains("custom.Exported") && !text.Contains("custom.Example"))
				{
					LocalJsons.Add(File.ReadAllText(text));
				}
			}
			Deserialize(LocalJsons);
			LocalJsons.Clear();
		}

		public static void LoadLocalTextures()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			TextureDict.Clear();
			string[] files = Directory.GetFiles(Paths.ConfigPath, "rrrtex.*.png", SearchOption.AllDirectories);
			foreach (string text in files)
			{
				string key = text.Remove(text.Length - 4).Substring(text.IndexOf("rrrtex") + 7);
				Texture2D val = new Texture2D(2, 2);
				byte[] array = File.ReadAllBytes(text);
				ImageConversion.LoadImage(val, array);
				TextureDict.Add(key, val);
			}
		}

		public static void DoExports()
		{
			if (ZNet.instance.IsServer() && !ZNet.instance.IsDedicated())
			{
				DoNpcExports();
				DoMonsterExports();
			}
		}

		private static void DoNpcExports()
		{
			if (ZNet.instance.IsServer() && !ZNet.instance.IsDedicated())
			{
				ExportToFile(ZNetScene.instance.GetPrefab("RRR_NPC"), "Example", isNpc: true);
			}
		}

		private static void DoMonsterExports()
		{
			if (!ZNet.instance.IsServer() || ZNet.instance.IsDedicated())
			{
				return;
			}
			foreach (string item in (from s in ConfigsMonsters.Config_ExportExistingPrefabs.Value.Split(new char[1] { ',' }).ToList()
				select s.Trim() into s
				where !Utility.IsNullOrWhiteSpace(s)
				select s).ToList())
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(item);
				if (prefab.IsNotNull())
				{
					ExportToFile(prefab, "Exported" + item);
				}
			}
			ConfigsMonsters.Config_ExportExistingPrefabs.Value = "";
		}

		private static void ExportToFile(GameObject prefab, string newName, bool isNpc = false)
		{
			if (ZNet.instance.IsServer() && !ZNet.instance.IsDedicated())
			{
				RRRMobData rRRMobData = RRRMobData.Convert(prefab);
				rRRMobData.sOriginalPrefabName = (isNpc ? "RRR_NPC" : ((Object)prefab).name);
				rRRMobData.sNewPrefabName = newName;
				string path = (isNpc ? "rrrnpcs" : "rrrmonsters") + ".custom." + newName + ".json";
				File.WriteAllText(Path.Combine(Paths.ConfigPath, path), JSON.ToNiceJSON(rRRMobData, Util.JsonParameters));
			}
		}

		private static void LogDeserializationError(string mobJson, string exceptionMessage)
		{
			Plugin.log.LogError((object)"--------------------------------------------------------------");
			Plugin.log.LogError((object)"Invalid custom prefab JSON. First 2 lines of broken file:");
			using (StringReader stringReader = new StringReader(mobJson))
			{
				stringReader.ReadLine();
				Plugin.log.LogError((object)stringReader.ReadLine());
				Plugin.log.LogError((object)stringReader.ReadLine());
			}
			Plugin.log.LogError((object)"--------------------------------------------------------------");
			Plugin.log.LogError((object)"If given, number points to exact character index of error:");
			using (StringReader stringReader2 = new StringReader(exceptionMessage))
			{
				Plugin.log.LogError((object)("    " + stringReader2.ReadLine()));
			}
			Plugin.log.LogError((object)"--------------------------------------------------------------");
		}
	}
	public class RRRMobCustomization : MonoBehaviour
	{
		private Humanoid humanoid;

		private MonsterAI monsterAI;

		private RRRMobData mobData;

		public string MobDataNewPrefabName;

		public string FullPrefabName;

		private void Awake()
		{
			humanoid = ((Component)this).GetComponent<Humanoid>();
			monsterAI = ((Component)this).GetComponent<MonsterAI>();
			mobData = RRRCustomMobDB.GetMobData(MobDataNewPrefabName);
		}

		private void Start()
		{
			if (mobData.IsNotNull() && mobData.Category_Special.IsNotNull())
			{
				if (mobData.Category_Special.bCanTame || mobData.Category_Special.bAlwaysTame)
				{
					SetupTameable();
				}
				if (mobData.Category_Special.bSfxNoAlert)
				{
					RemoveSfx(ref ((BaseAI)monsterAI).m_alertedEffects.m_effectPrefabs);
				}
				if (mobData.Category_Special.bSfxNoIdle)
				{
					RemoveSfx(ref ((BaseAI)monsterAI).m_idleSound.m_effectPrefabs);
				}
				if (mobData.Category_Special.bSfxNoHit)
				{
					RemoveSfx(ref ((Character)humanoid).m_hitEffects.m_effectPrefabs);
				}
				if (mobData.Category_Special.bSfxNoDeath)
				{
					RemoveSfx(ref ((Character)humanoid).m_deathEffects.m_effectPrefabs);
				}
			}
		}

		private void SetupTameable()
		{
			Tameable val = ((Component)this).gameObject.AddComponent<Tameable>();
			GameObject prefab = ZNetScene.instance.GetPrefab("Wolf");
			Tameable component = prefab.GetComponent<Tameable>();
			val.m_fedDuration = component.m_fedDuration;
			val.m_tamingTime = component.m_tamingTime;
			bool valueOrDefault = mobData.Category_Special.bFxNoTame.GetValueOrDefault(false);
			if (!valueOrDefault)
			{
				val.m_tamedEffect = component.m_tamedEffect;
				val.m_sootheEffect = component.m_sootheEffect;
				val.m_petEffect = component.m_petEffect;
			}
			val.m_commandable = mobData.Category_Special.bCommandableWhenTame;
			if (mobData.Category_Special.bCanProcreateWhenTame)
			{
				Procreation val2 = ((Component)this).gameObject.AddComponent<Procreation>();
				Procreation component2 = prefab.GetComponent<Procreation>();
				val2.m_updateInterval = component2.m_updateInterval;
				val2.m_pregnancyChance = component2.m_pregnancyChance;
				val2.m_pregnancyDuration = component2.m_pregnancyDuration;
				val2.m_offspring = ZNetScene.instance.GetPrefab(FullPrefabName);
				if (!valueOrDefault)
				{
					val2.m_birthEffects = component2.m_birthEffects;
					val2.m_loveEffects = component2.m_loveEffects;
				}
			}
			if (mobData.Category_Special.bAlwaysTame)
			{
				val.Tame();
			}
		}

		private static void RemoveSfx(ref EffectData[] data)
		{
			data = data.Where((EffectData d) => d.m_prefab.GetComponent<ZSFX>() == null).ToArray();
		}
	}
	public static class RRRModCompat
	{
		public static class Guids
		{
			public const string CustomRaids = "asharppen.valheim.custom_raids";
		}

		public const string ConfigSection = "zOtherMods";
	}
	[BepInPlugin("com.alexanderstrada.rrrcore", "RRRCore", "3.1.5")]
	[HarmonyPatch]
	public class Plugin : BaseUnityPlugin
	{
		private const string GUID = "com.alexanderstrada.rrrcore";

		private const string NAME = "RRRCore";

		internal const string VERSION = "3.1.5";

		internal static AssetBundle MonstersAssets;

		internal static ManualLogSource log;

		internal static ConfigFile ConfigFile;

		internal static ConfigSync ConfigSync;

		internal static CustomSyncedValue<List<string>> Config_CustomMobs;

		internal static bool MissingTextureWarningShown;

		private void Awake()
		{
			log = ((BaseUnityPlugin)this).Logger;
			ConfigFile = ((BaseUnityPlugin)this).Config;
			WarnAboutDeprecatedSubmods();
			ConfigSync = new ConfigSync("com.alexanderstrada.rrrcore")
			{
				DisplayName = "RRRCore",
				CurrentVersion = "3.1.5",
				MinimumRequiredVersion = "3.1.5"
			};
			Config_CustomMobs = new CustomSyncedValue<List<string>>(ConfigSync, "Config_CustomMobs");
			ApplyPatches();
			LoadMonsters();
			LoadNpcs();
		}

		private static void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			Harmony val = new Harmony("com.alexanderstrada.rrrcore");
			MethodInfo methodInfo = AccessTools.Method(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(Game), "RequestRespawn", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(Plugin), "EarlyLoad", (Type[])null, (Type[])null);
			val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo4, 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo4, 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			MethodInfo methodInfo5 = AccessTools.Method(typeof(Plugin), "LateLoadServer", (Type[])null, (Type[])null);
			MethodInfo methodInfo6 = AccessTools.Method(typeof(Plugin), "LateLoadClient", (Type[])null, (Type[])null);
			val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo5, 0, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(methodInfo6, 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void EarlyLoad()
		{
			Grig.EarlyLoadGrig();
		}

		private static void LateLoadServer()
		{
			if (Util.IsGameInMainScene() && ZNet.instance.IsServer())
			{
				RRRCustomMobDB.LoadLocalTextures();
				RRRCustomMobDB.LoadLocalConfigs();
				RRRPrefabLoader.Load();
				Config_CustomMobs.Value = RRRCustomMobDB.Serialize();
				Config_CustomMobs = Config_CustomMobs;
			}
		}

		private static void LateLoadClient()
		{
			if (Game.instance.m_firstSpawn && Util.IsGameInMainScene() && !ZNet.instance.IsServer())
			{
				MissingTextureWarningShown = false;
				RRRCustomMobDB.LoadLocalTextures();
				if (Config_CustomMobs.Value == null)
				{
					log.LogWarning((object)"Did not receive configs from ServerSync in time! This is bad! Connection issues, or extreme transfer size?");
					RRRCustomMobDB.LoadLocalConfigs();
				}
				else
				{
					RRRCustomMobDB.Deserialize(Config_CustomMobs.Value);
				}
				RRRPrefabLoader.Load();
			}
		}

		private void LoadMonsters()
		{
			ConfigsMonsters.Awake();
			MonstersAssets = Util.LoadAssetBundle(typeof(Plugin), "rrrmonstersassets");
			RRRPrefabLoader.LateLoadPrefabs += ConfigsMonsters.LateLoadPrefabsMonsters;
		}

		private void LoadNpcs()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			ConfigsNpcs.Awake(new Harmony("com.alexanderstrada.rrrcore"));
			RRRPrefabLoader.LateLoadPrefabs += ConfigsNpcs.LateLoadPrefabsNpcs;
		}

		private static void WarnAboutDeprecatedSubmods()
		{
			string[] files = Directory.GetFiles(Paths.PluginPath, "*.dll");
			for (int i = 0; i < files.Length; i++)
			{
				string text = Path.GetFileNameWithoutExtension(files[i]).ToLower();
				if (text.Contains("rrrmonsters") || text.Contains("rrrnpcs"))
				{
					string text2 = "HEY, LISTEN! RRR Monsters and NPCs have both been combined into RRR Core! You need to delete RRRNpcs.dll and RRRMonsters.dll from your Bepinex/Plugins folder, or you will get a big nasty red error message for each one (see nasty red error message below!)";
					string text3 = "Found " + text + " in your plugins folder! Delete it!";
					log.LogError((object)"-------------------------");
					log.LogError((object)text2);
					log.LogWarning((object)text2);
					log.LogError((object)text3);
					log.LogWarning((object)text3);
					log.LogError((object)"-------------------------");
				}
			}
		}
	}
	[RequireComponent(typeof(CharacterDrop))]
	public class RRRCustomDrop : MonoBehaviour
	{
		public List<string> options;

		public float chance;

		public float chanceMod;

		public int min;

		public int max;

		public RRRCustomDrop Config(List<string> setOptions, float setChance = 1f, float setChanceMod = 1f, int setMin = 0, int setMax = 1)
		{
			options = setOptions;
			chance = setChance;
			chanceMod = setChanceMod;
			min = setMin;
			max = setMax;
			return this;
		}

		private void Start()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			CharacterDrop component = ((Component)this).gameObject.GetComponent<CharacterDrop>();
			int num = min;
			for (int i = 0; i < max - min; i++)
			{
				if (Random.value <= chance * Mathf.Pow(chanceMod, (float)i))
				{
					num++;
				}
			}
			for (int j = 0; j < num; j++)
			{
				string text = options.RandomMember();
				Drop item = new Drop
				{
					m_prefab = ZNetScene.instance.GetPrefab(text)
				};
				component.m_drops.Add(item);
			}
			Object.Destroy((Object)(object)this);
		}
	}
	public class RRRNpcCustomization : MonoBehaviour
	{
		public bool IsFemale;

		public bool IsRandomGender;

		public bool IsNoBeardIfFemale;

		public List<string> BeardItems;

		public List<string> HairItems;

		public Color SkinColorMin;

		public Color SkinColorMax;

		public Color HairColorMin;

		public Color HairColorMax;

		public float HairValueMin;

		public float HairValueMax;

		private void Awake()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			Humanoid component = ((Component)this).gameObject.GetComponent<Humanoid>();
			VisEquipment component2 = ((Component)this).gameObject.GetComponent<VisEquipment>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null))
			{
				int num = (IsRandomGender ? Mathf.RoundToInt(Random.value) : (IsFemale ? 1 : 0));
				component2.SetModel(num);
				if (num == 0 || !IsNoBeardIfFemale)
				{
					component.m_beardItem = BeardItems.RandomMember();
				}
				component.m_hairItem = HairItems.RandomMember();
				Color val = Color.Lerp(SkinColorMin, SkinColorMax, Random.value);
				component2.SetSkinColor(Utils.ColorToVec3(val));
				Color val2 = Color.Lerp(HairColorMin, HairColorMax, Random.value) * Mathf.Lerp(HairValueMin, HairValueMax, Random.value);
				component2.SetHairColor(Utils.ColorToVec3(val2));
				component.SetupEquipment();
			}
		}
	}
	public static class RRRPluginGuids
	{
		public const string RRRCore = "com.alexanderstrada.rrrcore";

		public static string FromName(string pluginName)
		{
			if (pluginName == "RRRCore")
			{
				return "com.alexanderstrada.rrrcore";
			}
			throw new Exception("PluginName " + pluginName + " had no corresponding GUID.");
		}
	}
	public static class RRRPluginNames
	{
		public const string RRRCore = "RRRCore";

		public static string FromGuid(string pluginGuid)
		{
			if (pluginGuid == "com.alexanderstrada.rrrcore")
			{
				return "RRRCore";
			}
			throw new Exception("PluginGuid " + pluginGuid + " had no corresponding name.");
		}
	}
	public static class RRRPrefabLoader
	{
		public delegate void LateLoadPrefabsDelegate();

		public delegate void LateLoadCompleteDelegate();

		private const string ParentName = "RRRCore_StasisParentLate";

		private static readonly List<GameObject> PrefabsToZns;

		private static readonly List<GameObject> PrefabsToOdb;

		private static bool BuildComplete;

		public static GameObject StasisParent { get; private set; }

		public static event LateLoadPrefabsDelegate LateLoadPrefabs;

		public static event LateLoadCompleteDelegate LateLoadComplete;

		static RRRPrefabLoader()
		{
			PrefabsToZns = new List<GameObject>();
			PrefabsToOdb = new List<GameObject>();
			EmptySetup();
		}

		internal static void EmptySetup()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if ((Object)(object)StasisParent != (Object)null)
			{
				Object.Destroy((Object)(object)StasisParent);
			}
			StasisParent = new GameObject("RRRCore_StasisParentLate");
			Object.DontDestroyOnLoad((Object)(object)StasisParent);
			StasisParent.SetActive(false);
			PrefabsToZns.Clear();
			PrefabsToOdb.Clear();
			BuildComplete = false;
		}

		internal static GameObject Remove(string prefabName)
		{
			GameObject result = null;
			foreach (GameObject prefabsToZn in PrefabsToZns)
			{
				if (((Object)prefabsToZn).name == prefabName)
				{
					result = prefabsToZn;
					PrefabsToZns.Remove(prefabsToZn);
					break;
				}
			}
			foreach (GameObject item in PrefabsToOdb)
			{
				if (((Object)item).name == prefabName)
				{
					result = item;
					PrefabsToOdb.Remove(item);
					break;
				}
			}
			return result;
		}

		internal static void Load()
		{
			EmptySetup();
			RRRPrefabLoader.LateLoadPrefabs?.Invoke();
			if (Util.IsGameInMainScene())
			{
				RRRCustomMobDB.MakePrefabs();
				foreach (GameObject prefabsToZn in PrefabsToZns)
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefabsToZn).name);
					ZNetScene.instance.m_prefabs.Add(prefabsToZn);
					ZNetScene.instance.m_namedPrefabs.Add(stableHashCode, prefabsToZn);
				}
				if (ZNet.instance.IsServer() && !ZNet.instance.IsDedicated())
				{
					RRRCustomMobDB.DoExports();
				}
			}
			foreach (GameObject item in PrefabsToOdb)
			{
				ObjectDB.instance.m_items.Add(item);
			}
			if (PrefabsToOdb.NonEmpty())
			{
				ObjectDB.instance.UpdateItemHashes();
			}
			PrefabsToZns.Clear();
			PrefabsToOdb.Clear();
			BuildComplete = true;
			RRRPrefabLoader.LateLoadComplete?.Invoke();
		}

		public static void Add(GameObject gameObject, bool regZns = true, bool regOdb = false)
		{
			if (BuildComplete)
			{
				throw new Exception("Tried to call Add after Build. Object name: '" + ((Object)gameObject).name + "'");
			}
			if (FindName(((Object)gameObject).name).IsNotNull())
			{
				throw new Exception("There is already a prefab named: '" + ((Object)gameObject).name + "'");
			}
			RRRReplaceRefHandler.TryFixSfxAudioMixerGroup(gameObject);
			if (regZns)
			{
				PrefabsToZns.Add(gameObject);
			}
			if (regOdb)
			{
				PrefabsToOdb.Add(gameObject);
			}
		}

		public static GameObject Clone(string originalName, string newName, bool regZns = true, bool regOdb = false)
		{
			if (BuildComplete)
			{
				throw new Exception("Tried to call Clone after Build. NewName: '" + newName + "'");
			}
			GameObject obj = FindName(originalName);
			if ((Object)(object)obj == (Object)null)
			{
				throw new NullReferenceException("No such original prefab: " + originalName);
			}
			return Clone(obj, newName, regZns, regOdb);
		}

		public static GameObject Clone(GameObject originalPrefab, string newName, bool regZns = true, bool regOdb = false)
		{
			if (BuildComplete)
			{
				throw new Exception("Tried to call Clone after Build. NewName: '" + newName + "'");
			}
			if (PrefabsToZns.ExistsName(newName) || Object.op_Implicit((Object)(object)ZNetScene.instance.GetPrefab(newName)) || PrefabsToOdb.ExistsName(newName) || Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(newName)))
			{
				throw new Exception("Tried to Clone prefab, but name already exists: " + newName);
			}
			GameObject val = Object.Instantiate<GameObject>(originalPrefab, StasisParent.transform);
			((Object)val).name = newName;
			if (regZns)
			{
				PrefabsToZns.Add(val);
			}
			if (regOdb)
			{
				PrefabsToOdb.Add(val);
			}
			return val;
		}

		public static GameObject CloneRepeatable(ref bool alreadyExisted, string originalName, string newName, bool regZns = true, bool regOdb = false)
		{
			if (BuildComplete)
			{
				throw new Exception("Tried to call CloneRepeatable after Build. NewName: '" + newName + "'");
			}
			GameObject val = FindName(originalName);
			if ((Object)(object)val == (Object)null)
			{
				throw new NullReferenceException("No such original prefab: " + originalName);
			}
			return CloneRepeatable(ref alreadyExisted, val, newName, regZns, regOdb);
		}

		public static GameObject CloneRepeatable(ref bool alreadyExisted, GameObject originalPrefab, string newName, bool regZns = true, bool regOdb = false)
		{
			if (BuildComplete)
			{
				throw new Exception("Tried to call CloneRepeatable after Build. NewName: '" + newName + "'");
			}
			for (int i = 0; i < StasisParent.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)StasisParent.transform.GetChild(i)).gameObject;
				if (((Object)gameObject).name == newName)
				{
					alreadyExisted = true;
					return gameObject;
				}
			}
			alreadyExisted = false;
			return Clone(originalPrefab, newName, regZns, regOdb);
		}

		internal static GameObject FindName(string originalName)
		{
			GameObject val = ZNetScene.instance.GetPrefab(originalName);
			if ((Object)(object)val == (Object)null)
			{
				val = ObjectDB.instance.GetItemPrefab(originalName);
			}
			if ((Object)(object)val == (Object)null)
			{
				val = PrefabsToZns.Find((GameObject go) => ((Object)go).name == originalName);
			}
			if ((Object)(object)val == (Object)null)
			{
				val = PrefabsToOdb.Find((GameObject go) => ((Object)go).name == originalName);
			}
			return val;
		}
	}
	public class RRRTogglePatch
	{
		public const string Warn = "Only change if you know what you are doing.";

		public const string DefaultDesc = "<Description Unspecified>";

		public string Description = "<Description Unspecified>";

		private RRRConfig<bool> LocalValue;

		public bool PatchIsEnabled()
		{
			return LocalValue.GetValue();
		}

		public RRRTogglePatch Bind(Harmony harmony, ConfigFile config, string section, bool defaultValue = true)
		{
			harmony.PatchAll(GetType());
			LocalValue = RRRConfig.Bind(config, section, GetType().Name, defaultValue, Description);
			return this;
		}
	}
	public static class Util
	{
		public static readonly JSONParameters JsonParameters = new JSONParameters
		{
			EnableAnonymousTypes = true
		};

		public static List<T> AllOf<T>()
		{
			return Enum.GetValues(typeof(T)).OfType<T>().ToList();
		}

		public static bool IsGameInMainScene()
		{
			return (Object)(object)ZNetScene.instance != (Object)null;
		}

		public static bool DoesPluginExist(string pluginGuid)
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				if (pluginInfo.Value.Metadata.GUID == pluginGuid)
				{
					return true;
				}
			}
			return false;
		}

		public static string GetPluginPath(Type modPluginType)
		{
			return Path.GetDirectoryName(modPluginType.Assembly.Location);
		}

		public static AssetBundle LoadAssetBundle(Type modPluginType, string bundleName)
		{
			Assembly assembly = modPluginType.Assembly;
			return AssetBundle.LoadFromStream(assembly.GetManifestResourceStream(assembly.GetName().Name + "." + bundleName));
		}

		public static bool IsNotNull(this object type)
		{
			return type != null;
		}

		public static bool IsEmpty(this string s)
		{
			return string.IsNullOrEmpty(s);
		}

		public static bool NonEmpty(this string s)
		{
			return !string.IsNullOrEmpty(s);
		}

		public static string TrimCloneTag(this string s)
		{
			if (!s.EndsWith("(Clone)"))
			{
				return s;
			}
			return s.Substring(0, s.Length - "(Clone)".Length);
		}

		public static (string left, string right) SplitOnFirst(this string s, string delimiter)
		{
			if (Utility.IsNullOrWhiteSpace(s))
			{
				return (null, null);
			}
			int num = s.IndexOf(delimiter, StringComparison.Ordinal);
			if (num == -1)
			{
				return (s, null);
			}
			string item = s.Remove(num);
			string item2 = s.Substring(num + 1);
			return (item, item2);
		}

		public static bool IsEmpty<T>(this IEnumerable<T> l)
		{
			return l.Count() == 0;
		}

		public static bool NonEmpty<T>(this List<T> l)
		{
			return l.Count > 0;
		}

		public static bool IsEmpty<K, V>(this Dictionary<K, V> d)
		{
			return d.Count == 0;
		}

		public static bool NonEmpty<K, V>(this Dictionary<K, V> d)
		{
			return d.Count > 0;
		}

		public static T RandomMember<T>(this List<T> l)
		{
			return l[Random.Range(0, l.Count)];
		}

		public static bool ExistsName(this IEnumerable<GameObject> self, string name)
		{
			foreach (GameObject item in self)
			{
				if (((Object)item).name == name)
				{
					return true;
				}
			}
			return false;
		}

		public static void RetuneDamage(this ref DamageTypes damageTypes, float newTotal, float chop = 0f, float pickaxe = 0f)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			float num = ((DamageTypes)(ref damageTypes)).GetTotalPhysicalDamage() + ((DamageTypes)(ref damageTypes)).GetTotalElementalDamage();
			List<Tuple<FieldInfo, float>> list = new List<Tuple<FieldInfo, float>>();
			FieldInfo[] fields = ((object)damageTypes).GetType().GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.Name == "m_chop") && !(fieldInfo.Name == "m_pickaxe"))
				{
					float num2 = (float)fieldInfo.GetValue(damageTypes);
					if (num2 > 0f)
					{
						list.Add(new Tuple<FieldInfo, float>(fieldInfo, num2));
					}
				}
			}
			object obj = damageTypes;
			foreach (var (fieldInfo3, num4) in list)
			{
				fieldInfo3.SetValue(obj, newTotal * (num4 / num));
			}
			damageTypes = (DamageTypes)obj;
			damageTypes.m_chop = chop;
			damageTypes.m_pickaxe = pickaxe;
		}

		public static List<byte[]> SplitByteArray(byte[] source, int chunkSize = 500000)
		{
			List<byte[]> list = new List<byte[]>();
			int num = source.Length;
			int num2;
			for (int i = 0; i < num; i += num2)
			{
				num2 = Math.Min(chunkSize, num - i);
				byte[] array = new byte[num2];
				Array.Copy(source, i, array, 0, num2);
				list.Add(array);
			}
			return list;
		}

		public static byte[] ConcatenateByteArrays(List<byte[]> arrays)
		{
			byte[] array = new byte[arrays.Sum((byte[] arr) => arr.Length)];
			int num = 0;
			foreach (byte[] array2 in arrays)
			{
				Array.Copy(array2, 0, array, num, array2.Length);
				num += array2.Length;
			}
			return array;
		}
	}
	public static class RRRMobWeaponFactory
	{
		private static string MakeName(string ownerName, string weaponName, string animName = null, string projName = null, string attackInterval = null)
		{
			return ownerName + "@" + weaponName + "@" + animName + "@" + projName + "@" + attackInterval;
		}

		public static GameObject Get(GameObject owner, string weaponName, bool isNpc = false, RRRMobDataUtil.DamageTypes damageByType = null, float? squishTotalDamage = null, string animationName = null, string projectileName = null, float? attackInterval = null, string forceName = null)
		{
			//IL_00ed: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Invalid comparison between Unknown and I4
			string text = forceName ?? MakeName(((Object)owner).name, weaponName, animationName, projectileName, attackInterval?.ToString());
			bool alreadyExisted = false;
			GameObject val = RRRPrefabLoader.CloneRepeatable(ref alreadyExisted, weaponName, text, regZns: true, regOdb: true);
			if (alreadyExisted)
			{
				return val;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				throw new NullReferenceException("No ItemDrop component in prefab: " + weaponName);
			}
			SharedData shared = component.m_itemData.m_shared;
			shared.m_name = text;
			shared.m_useDurability = false;
			if (!Utility.IsNullOrWhiteSpace(shared.m_setName))
			{
				shared.m_setName = shared.m_setName + "_rrr_" + ((Object)owner).name;
			}
			if (!Utility.IsNullOrWhiteSpace(shared.m_attack.m_attackOriginJoint) && Utils.FindChild(owner.transform, shared.m_attack.m_attackOriginJoint, (IterativeSearchType)0) == null)
			{
				shared.m_attack.m_attackOriginJoint = "";
			}
			if (damageByType.IsNotNull())
			{
				shared.m_damages = damageByType.Make();
			}
			if (squishTotalDamage.HasValue)
			{
				shared.m_damages.RetuneDamage(squishTotalDamage.Value);
			}
			if (!Utility.IsNullOrWhiteSpace(animationName))
			{
				shared.m_attack.m_attackAnimation = animationName;
			}
			if ((int)shared.m_attack.m_attackType == 2)
			{
				if (projectileName.IsNotNull() || shared.m_attack.m_attackProjectile == null)
				{
					shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab(Utility.IsNullOrWhiteSpace(projectileName) ? "draugr_bow_projectile" : projectileName);
				}
				if (isNpc)
				{
					shared.m_ammoType = "";
					shared.m_aiAttackRange = 25f;
					shared.m_aiAttackRangeMin = 0f;
					shared.m_aiAttackMaxAngle = 10f;
					shared.m_attackForce = 15f;
					shared.m_attack.m_drawDurationMin = 0f;
					shared.m_attack.m_drawStaminaDrain = 20f;
					shared.m_attack.m_drawAnimationState = "";
					shared.m_secondaryAttack.m_drawDurationMin = 0f;
					shared.m_secondaryAttack.m_drawStaminaDrain = 20f;
					shared.m_secondaryAttack.m_drawAnimationState = "";
					shared.m_attack.m_bowDraw = false;
					shared.m_attack.m_speedFactor = 0f;
					shared.m_attack.m_speedFactorRotation = 0.5f;
					shared.m_attack.m_attackStartNoise = 20f;
					shared.m_attack.m_attackHitNoise = 30f;
					shared.m_attack.m_projectileVel = 30f;
					shared.m_attack.m_projectileVelMin = 2f;
					shared.m_attack.m_projectileAccuracy = 2f;
					ItemDrop component2 = shared.m_attack.m_attackProjectile.GetComponent<ItemDrop>();
					if (component2.IsNotNull())
					{
						((DamageTypes)(ref component2.m_itemData.m_shared.m_damages)).Modify(0f);
						((DamageTypes)(ref component2.m_itemData.m_shared.m_damagesPerLevel)).Modify(0f);
					}
				}
			}
			if (attackInterval.HasValue)
			{
				shared.m_aiAttackInterval = attackInterval.Value;
			}
			return val;
		}

		public static GameObject GetNpcUnarmed(string ownerName, RRRMobDataUtil.DamageTypes damageByType = null, float? squishTotalDamage = null)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			string text = MakeName(ownerName, "npcunarmed");
			bool alreadyExisted = false;
			GameObject val = RRRPrefabLoader.CloneRepeatable(ref alreadyExisted, ((Component)((Humanoid)ZNetScene.instance.GetPrefab("Player").GetComponent<Player>()).m_unarmedWeapon).gameObject, text, regZns: true, regOdb: true);
			if (alreadyExisted)
			{
				return val;
			}
			SharedData shared = val.GetComponent<ItemDrop>().m_itemData.m_shared;
			shared.m_name = text;
			if (damageByType.IsNotNull())
			{
				shared.m_damages = damageByType.Make();
			}
			if (squishTotalDamage.HasValue)
			{
				shared.m_damages.RetuneDamage(squishTotalDamage.Value);
			}
			return val;
		}
	}
}
namespace RRRCore.prefabs._0_2_0
{
	public class RRRCfgAppearance
	{
		public RRRMobDataUtil.Vector3 vScale = RRRMobDataUtil.one;

		public RRRMobDataUtil.Color cTintColor;

		public RRRMobDataUtil.Color cTintItems;

		public RRRMobDataUtil.Color cBodySmoke;

		public RRRMobDataUtil.Color cBodyFlames;

		public string sCustomTexture;

		internal static bool MakeAppearance(GameObject clone, RRRCfgAppearance cA)
		{
			if (cA.vScale.IsNotNull())
			{
				DoScale(clone, cA);
			}
			SkinnedMeshRenderer[] componentsInChildren = clone.GetComponentsInChildren<SkinnedMeshRenderer>();
			foreach (SkinnedMeshRenderer smr in componentsInChildren)
			{
				EditSmr(clone, cA, smr);
			}
			if (cA.cTintItems.IsNotNull())
			{
				TintItems(clone, cA);
			}
			DoRagdoll(clone, cA);
			return true;
		}

		private static void EditSmr(GameObject clone, RRRCfgAppearance cA, SkinnedMeshRenderer smr)
		{
			//IL_005b: 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_002d: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (!Utility.IsNullOrWhiteSpace(cA.sCustomTexture))
			{
				if (RRRCustomMobDB.TryGetTexture(cA.sCustomTexture, out var texture))
				{
					((Renderer)smr).sharedMaterial = new Material(((Renderer)smr).sharedMaterial);
					((Renderer)smr).sharedMaterial.mainTexture = (Texture)(object)texture;
				}
				else
				{
					DoMissingTextureError(clone, cA);
				}
			}
			if (cA.cTintColor.IsNotNull())
			{
				((Renderer)smr).material.color = cA.cTintColor.Make();
			}
			if (cA.cBodySmoke.IsNotNull())
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)ZNetScene.instance.GetPrefab("Ghost").GetComponentsInChildren<ParticleSystem>().First((ParticleSystem w) => ((Object)((Component)w).gameObject).name == "black_smoke")).gameObject, ((Component)smr).transform);
				if (val.IsNotNull())
				{
					ParticleSystem component = val.GetComponent<ParticleSystem>();
					if (component.IsNotNull())
					{
						ShapeModule shape = component.shape;
						((ShapeModule)(ref shape)).skinnedMeshRenderer = smr;
						((Component)component).GetComponent<Renderer>().material.color = cA.cBodySmoke.Make();
					}
				}
			}
			if (!cA.cBodyFlames.IsNotNull())
			{
				return;
			}
			ParticleSystem[] componentsInChildren = ZNetScene.instance.GetPrefab("Surtling").GetComponentsInChildren<ParticleSystem>();
			GameObject val2 = Object.Instantiate<GameObject>(((Component)componentsInChildren.First((ParticleSystem w) => ((Object)((Component)w).gameObject).name == "flames")).gameObject, ((Component)smr).transform);
			GameObject val3 = Object.Instantiate<GameObject>(((Component)componentsInChildren.First((ParticleSystem w) => ((Object)((Component)w).gameObject).name == "flames_world")).gameObject, ((Component)smr).transform);
			if (val2.IsNotNull() && val3.IsNotNull())
			{
				ParticleSystem component2 = val2.GetComponent<ParticleSystem>();
				if (component2.IsNotNull())
				{
					DoFlames(component2, smr, cA);
				}
				ParticleSystem component3 = val3.GetComponent<ParticleSystem>();
				if (component3.IsNotNull())
				{
					DoFlames(component3, smr, cA);
				}
			}
		}

		private static void DoMissingTextureError(GameObject clone, RRRCfgAppearance cA)
		{
			if (!Plugin.MissingTextureWarningShown && !ZNet.instance.IsServer())
			{
				Plugin.MissingTextureWarningShown = true;
				Plugin.log.LogError((object)"Textures do not sync, as Valheim's networking is not suitable for large file transfers.");
				Plugin.log.LogError((object)"Ask the admin of your server to provide them as part of your mod pack or server pack.");
			}
			Plugin.log.LogError((object)("Texture " + cA.sCustomTexture + " for prefab " + ((Object)clone).name + " not found in Configs folder. Using default instead."));
		}

		private static void DoScale(GameObject clone, RRRCfgAppearance cA)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			Vector3 localScale = clone.transform.localScale;
			Vector3 val = cA.vScale.Make();
			localScale.x *= val.x;
			localScale.y *= val.y;
			localScale.z *= val.z;
			clone.transform.localScale = localScale;
		}

		private static void DoFlames(ParticleSystem fwps, SkinnedMeshRenderer smr, RRRCfgAppearance cA)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			MainModule main = fwps.main;
			MinMaxCurve val = ((MainModule)(ref main)).startSize;
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(((MinMaxCurve)(ref val)).constant / 100f);
			val = ((MainModule)(ref main)).startSpeed;
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(((MinMaxCurve)(ref val)).constant / 100f);
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(cA.cBodyFlames.Make());
			ShapeModule shape = fwps.shape;
			((ShapeModule)(ref shape)).skinnedMeshRenderer = smr;
		}

		private static void DoRagdoll(GameObject clone, RRRCfgAppearance cA)
		{
			Humanoid val = default(Humanoid);
			if (!clone.TryGetComponent<Humanoid>(ref val))
			{
				return;
			}
			for (int i = 0; i < ((Character)val).m_deathEffects.m_effectPrefabs.Length; i++)
			{
				EffectData val2 = ((Character)val).m_deathEffects.m_effectPrefabs[i];
				if (Object.op_Implicit((Object)(object)val2.m_prefab.GetComponent<Ragdoll>()))
				{
					GameObject val3 = RRRPrefabLoader.Clone(val2.m_prefab, ((Object)clone).name + "_ragdoll");
					((Character)val).m_deathEffects.m_effectPrefabs[i].m_prefab = val3;
					if (cA.vScale.IsNotNull())
					{
						DoScale(val3, cA);
					}
					SkinnedMeshRenderer[] componentsInChildren = val3.GetComponentsInChildren<SkinnedMeshRenderer>();
					foreach (SkinnedMeshRenderer smr in componentsInChildren)
					{
						EditSmr(val3, cA, smr);
					}
					break;
				}
			}
		}

		private static void TintItems(GameObject clone, RRRCfgAppearance cA)
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			Humanoid component = clone.GetComponent<Humanoid>();
			if (!component.IsNotNull())
			{
				return;
			}
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			hashSet.UnionWith(component.m_defaultItems);
			hashSet.UnionWith(component.m_randomWeapon);
			hashSet.UnionWith(component.m_randomArmor);
			hashSet.UnionWith(component.m_randomShield);
			ItemSet[] randomSets = component.m_randomSets;
			foreach (ItemSet val in randomSets)
			{
				hashSet.UnionWith(val.m_items);
			}
			foreach (Renderer item in hashSet.Where((GameObject i) => i.IsNotNull()).SelectMany((GameObject i) => i.GetComponentsInChildren<Renderer>(true)))
			{
				Material[] materials = item.materials;
				for (int j = 0; j < materials.Length; j++)
				{
					materials[j].color = cA.cTintItems.Make();
				}
			}
		}
	}
	public class RRRCfgBaseAI
	{
		public float? fViewRange = 50f;

		public float? fViewAngle = 90f;

		public float? fHearRange = 9999f;

		public List<string> aAlertedEffects;

		public List<string> aIdleEffects;

		public float? fIdleEffectsInterval;

		public float? fIdleEffectsChance;

		public AgentType sPathAgentType = (AgentType)1;

		public float? fRandomCircleInterval = 2f;

		public float? fRandomMoveInterval = 5f;

		public float? fRandomMoveRange = 4f;

		public bool? bRandomFly;

		public float? fChanceToTakeoff;

		public float? fChanceToLand;

		public float? fGroundDuration;

		public float? fAirDuration;

		public float? fMaxLandAltitude;

		public float? fFlyAltitudeMin;

		public float? fFlyAltitudeMax;

		public float? fTakeoffTime;

		public bool? bAvoidFire = false;

		public bool? bAfraidOfFire = false;

		public bool? bAvoidWater = true;

		public string sSpawnMessage = "";

		public string sDeathMessage = "";

		internal static bool MakeBaseAI(GameObject clone, RRRCfgBaseAI cB)
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			BaseAI component = clone.GetComponent<BaseAI>();
			if (component == null)
			{
				RRRMobData.FailMake("No BaseAI component in '" + ((Object)clone).name + "'.", ((Object)clone).name);
				return false;
			}
			if (cB.fViewRange.HasValue)
			{
				component.m_viewRange = cB.fViewRange.Value;
			}
			if (cB.fViewAngle.HasValue)
			{
				component.m_viewAngle = cB.fViewAngle.Value;
			}
			if (cB.fHearRange.HasValue)
			{
				component.m_hearRange = cB.fHearRange.Value;
			}
			if (cB.aAlertedEffects.IsNotNull())
			{
				RRRMobDataUtil.DoEffectsList(cB.aAlertedEffects, ref component.m_alertedEffects);
			}
			if (cB.aIdleEffects.IsNotNull())
			{
				RRRMobDataUtil.DoEffectsList(cB.aIdleEffects, ref component.m_idleSound);
			}
			if (cB.fIdleEffectsInterval.HasValue)
			{
				component.m_idleSoundInterval = cB.fIdleEffectsInterval.Value;
			}
			if (cB.fIdleEffectsChance.HasValue)
			{
				component.m_idleSoundChance = cB.fIdleEffectsChance.Value;
			}
			if (cB.sPathAgentType.IsNotNull())
			{
				component.m_pathAgentType = cB.sPathAgentType;
			}
			if (cB.fRandomCircleInterval.HasValue)
			{
				component.m_randomCircleInterval = cB.fRandomCircleInterval.Value;
			}
			if (cB.fRandomMoveInterval.HasValue)
			{
				component.m_randomMoveInterval = cB.fRandomMoveInterval.Value;
			}
			if (cB.fRandomMoveRange.HasValue)
			{
				component.m_randomMoveRange = cB.fRandomMoveRange.Value;
			}
			if (cB.bRandomFly.HasValue)
			{
				component.m_randomFly = cB.bRandomFly.Value;
			}
			if (cB.fChanceToTakeoff.HasValue)
			{
				component.m_chanceToTakeoff = cB.fChanceToTakeoff.Value;
			}
			if (cB.fChanceToLand.HasValue)
			{
				component.m_chanceToLand = cB.fChanceToLand.Value;
			}
			if (cB.fGroundDuration.HasValue)
			{
				component.m_groundDuration = cB.fGroundDuration.Value;
			}
			if (cB.fAirDuration.HasValue)
			{
				component.m_airDuration = cB.fAirDuration.Value;
			}
			if (cB.fMaxLandAltitude.HasValue)
			{
				component.m_maxLandAltitude = cB.fMaxLandAltitude.Value;
			}
			if (cB.fFlyAltitudeMin.HasValue)
			{
				component.m_flyAltitudeMin = cB.fFlyAltitudeMin.Value;
			}
			if (cB.fFlyAltitudeMax.HasValue)
			{
				component.m_flyAltitudeMax = cB.fFlyAltitudeMax.Value;
			}
			if (cB.fTakeoffTime.HasValue)
			{
				component.m_takeoffTime = cB.fTakeoffTime.Value;
			}
			if (cB.bAvoidFire.HasValue)
			{
				component.m_avoidFire = cB.bAvoidFire.Value;
			}
			if (cB.bAfraidOfFire.HasValue)
			{
				component.m_afraidOfFire = cB.bAfraidOfFire.Value;
			}
			if (cB.bAvoidWater.HasValue)
			{
				component.m_avoidWater = cB.bAvoidWater.Value;
			}
			if (cB.sSpawnMessage.IsNotNull())
			{
				component.m_spawnMessage = cB.sSpawnMessage;
			}
			if (cB.sDeathMessage.IsNotNull())
			{
				component.m_deathMessage = cB.sDeathMessage;
			}
			return true;
		}

		internal static void ConvertBaseAI(GameObject prefab, RRRMobData output)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			BaseAI component = prefab.GetComponent<BaseAI>();
			if (component.IsNotNull())
			{
				output.Category_BaseAI = new RRRCfgBaseAI();
				RRRCfgBaseAI category_BaseAI = output.Category_BaseAI;
				category_BaseAI.fViewRange = component.m_viewRange;
				category_BaseAI.fViewAngle = component.m_viewAngle;
				category_BaseAI.fHearRange = component.m_hearRange;
				category_BaseAI.aAlertedEffects = component.m_alertedEffects.m_effectPrefabs.Select((EffectData p) => ((Object)p.m_prefab).name).ToList();
				category_BaseAI.aIdleEffects = component.m_idleSound.m_effectPrefabs.Select((EffectData p) => ((Object)p.m_prefab).name).ToList();
				category_BaseAI.fIdleEffectsInterval = component.m_idleSoundInterval;
				category_BaseAI.fIdleEffectsChance = component.m_idleSoundChance;
				category_BaseAI.sPathAgentType = component.m_pathAgentType;
				category_BaseAI.fRandomCircleInterval = component.m_randomCircleInterval;
				category_BaseAI.fRandomMoveInterval = component.m_randomMoveInterval;
				category_BaseAI.fRandomMoveRange = component.m_randomMoveRange;
				category_BaseAI.bRandomFly = component.m_randomFly;
				category_BaseAI.fChanceToTakeoff = component.m_chanceToTakeoff;
				category_BaseAI.fChanceToLand = component.m_chanceToLand;
				category_BaseAI.fGroundDuration = component.m_groundDuration;
				category_BaseAI.fAirDuration = component.m_airDuration;
				category_BaseAI.fMaxLandAltitude = component.m_maxLandAltitude;
				category_BaseAI.fFlyAltitudeMin = component.m_flyAltitudeMin;
				category_BaseAI.fFlyAltitudeMax = component.m_flyAltitudeMax;
				category_BaseAI.fTakeoffTime = component.m_takeoffTime;
				category_BaseAI.bAvoidFire = component.m_avoidFire;
				category_BaseAI.bAfraidOfFire = component.m_afraidOfFire;
				category_BaseAI.bAvoidWater = component.m_avoidWater;
				category_BaseAI.sSpawnMessage = component.m_spawnMessage;
				category_BaseAI.sDeathMessage = component.m_deathMessage;
			}
		}
	}
	public class RRRCfgCharacter
	{
		public string sName = "Jimmy, Blacksmith Extraordinaire";

		public Faction sFaction = (Faction)1;

		public bool? bBoss = false;

		public string sBossEvent = "";

		public string sDefeatSetGlobalKey = "killed_jimmy";

		public float? fMoveSpeedMulti = 1f;

		public bool? bToleratesWater = true;

		public bool? bToleratesFire = false;

		public bool? bToleratesSmoke = true;

		public bool? bStaggerWhenBlocked;

		public float? fHealth = 10f;

		public DamageModifiers dDamageTaken;

		internal static bool MakeCharacter(GameObject clone, RRRCfgCharacter cC)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_004c: Invalid comparison between Unknown and I4
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			Character component = clone.GetComponent<Character>();
			if (component == null)
			{
				RRRMobData.FailMake("No Character component in '" + ((Object)clone).name + "'.", ((Object)clone).name);
				return false;
			}
			component.m_name = cC.sName;
			component.m_faction = cC.sFaction;
			if ((int)component.m_faction == -1)
			{
				RRRMobData.FailMake($"Unknown Faction '{component.m_faction}' for '{((Object)clone).name}'.", ((Object)clone).name);
				return false;
			}
			if (cC.bBoss.HasValue)
			{
				component.m_boss = cC.bBoss.Value;
			}
			if (cC.sBossEvent.IsNotNull())
			{
				component.m_bossEvent = cC.sBossEvent;
			}
			if (cC.sDefeatSetGlobalKey.IsNotNull())
			{
				component.m_defeatSetGlobalKey = cC.sDefeatSetGlobalKey;
			}
			if (cC.fMoveSpeedMulti.HasValue)
			{
				component.m_crouchSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_walkSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_speed *= cC.fMoveSpeedMulti.Value;
				component.m_turnSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_runSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_runTurnSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_flySlowSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_flyFastSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_flyTurnSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_acceleration *= cC.fMoveSpeedMulti.Value;
				component.m_airControl *= cC.fMoveSpeedMulti.Value;
				component.m_swimSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_swimTurnSpeed *= cC.fMoveSpeedMulti.Value;
				component.m_swimAcceleration *= cC.fMoveSpeedMulti.Value;
			}
			if (cC.bToleratesWater.HasValue)
			{
				component.m_tolerateWater = cC.bToleratesWater.Value;
			}
			if (cC.bToleratesSmoke.HasValue)
			{
				component.m_tolerateSmoke = cC.bToleratesSmoke.Value;
			}
			if (cC.bStaggerWhenBlocked.HasValue)
			{
				component.m_staggerWhenBlocked = cC.bStaggerWhenBlocked.Value;
			}
			if (cC.fHealth.HasValue)
			{
				component.m_health = cC.fHealth.Value;
			}
			if (cC.dDamageTaken.IsNotNull())
			{
				component.m_damageModifiers = cC.dDamageTaken;
			}
			return true;
		}

		internal static void ConvertCharacter(GameObject prefab, RRRMobData output)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			Character component = prefab.GetComponent<Character>();
			if (component.IsNotNull())
			{
				output.Category_Character = new RRRCfgCharacter();
				RRRCfgCharacter category_Character = output.Category_Character;
				category_Character.sName = component.m_name;
				category_Character.sFaction = component.m_faction;
				category_Character.bBoss = component.m_boss;
				category_Character.sBossEvent = component.m_bossEvent;
				category_Character.sDefeatSetGlobalKey = component.m_defeatSetGlobalKey;
				category_Character.fMoveSpeedMulti = 1f;
				category_Character.bToleratesWater = component.m_tolerateWater;
				category_Character.bToleratesSmoke = component.m_tolerateSmoke;
				category_Character.fHealth = component.m_health;
				category_Character.dDamageTaken = component.m_damageModifiers;
			}
			else
			{
				output.Category_Character = null;
			}
		}
	}
	public class RRRCfgCharacterDrop
	{
		public bool bReplaceOriginalDrops;

		public List<RRRMobDataUtil.Drop> drDrops = new List<RRRMobDataUtil.Drop>
		{
			new RRRMobDataUtil.Drop(),
			new RRRMobDataUtil.Drop()
		};

		internal static bool MakeCharacterDrop(GameObject clone, RRRCfgCharacterDrop cD)
		{
			CharacterDrop component = clone.GetComponent<CharacterDrop>();
			if (component == null)
			{
				RRRMobData.FailMake("No CharacterDrop component in '" + ((Object)clone).name + "'.", ((Object)clone).name);
				return false;
			}
			if (cD.bReplaceOriginalDrops)
			{
				component.m_drops.Clear();
			}
			component.m_drops.AddRange(cD.drDrops.Select((RRRMobDataUtil.Drop drop) => drop.Make()));
			return true;
		}

		internal static void ConvertCharacterDrop(GameObject prefab, RRRMobData output)
		{
			CharacterDrop component = prefab.GetComponent<CharacterDrop>();
			if (component.IsNotNull())
			{
				output.Category_CharacterDrop = new RRRCfgCharacterDrop();
				RRRCfgCharacterDrop category_CharacterDrop = output.Category_CharacterDrop;
				category_CharacterDrop.bReplaceOriginalDrops = true;
				category_CharacterDrop.drDrops = component.m_drops.Select(RRRMobDataUtil.Drop.Unmake).ToList();
			}
		}
	}
	public class RRRCfgHumanoid
	{
		internal class ParseItemWrapper
		{
			public GameObject GameObject;

			public string AnimationName;

			public string ProjectileName;

			public float? AttackInterval;

			public ParseItemWrapper(GameObject gameObject = null, string animationName = null, string projectileName = null, string attackInterval = null)
			{
				GameObject = gameObject;
				AnimationName = animationName;
				ProjectileName = projectileName;
				if (!Utility.IsNullOrWhiteSpace(attackInterval) && float.TryParse(attackInterval, out var result))
				{
					AttackInterval = result;
				}
			}
		}

		public RRRMobDataUtil.DamageTypes dtAttackDamageOverride;

		public float? fAttackDamageTotalOverride;

		public string sAttackProjectileOverride = "";

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

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

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

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

		public List<RRRMobDataUtil.RandomSet> aaRandomSets = new List<RRRMobDataUtil.RandomSet>
		{
			new RRRMobDataUtil.RandomSet(),
			new RRRMobDataUtil.RandomSet()
		};

		public List<string> aHitEffects;

		public List<string> aDeathEffects;

		public List<string> aConsumeItemEffects;

		public List<RRRMobDataUtil.CustomAttack> aAdvancedCustomAttacks;

		internal static bool MakeHumanoid(GameObject clone, bool isNpc, RRRCfgHumanoid cH)
		{
			Humanoid component = clone.GetComponent<Humanoid>();
			if (component == null)
			{
				RRRMobData.FailMake("No Humanoid component in '" + ((Object)clone).name + "'.", ((Object)clone).name);
				return false;
			}
			List<GameObject> list = new List<GameObject>();
			if (cH.aAdvancedCustomAttacks.IsNotNull())
			{
				list.AddRange(cH.aAdvancedCustomAttacks.Select((RRRMobDataUtil.CustomAttack t, int i) => t.Make(clone, isNpc, i)));
				RRRCustomMobDB.CustomAttackPrefabs.AddRange(list);
			}
			if (cH.aDefaultItems.IsNotNull())
			{
				if (!ParseItemList(clone, cH.aDefaultItems, list, out var items))
				{
					return false;
				}
				List<GameObject> list2 = ApplyAttackOverrides(clone, cH, isNpc, items);
				component.m_defaultItems = list2.ToArray();
			}
			if (cH.aRandomWeapon.IsNotNull())
			{
				if (!ParseItemList(clone, cH.aRandomWeapon, list, out var items2))
				{
					return false;
				}
				List<GameObject> list3 = ApplyAttackOverrides(clone, cH, isNpc, items2);
				component.m_randomWeapon = list3.ToArray();
			}
			if (cH.aRandomArmor.IsNotNull())
			{
				if (!ParseItemList(clone, cH.aRandomArmor, list, out var items3))
				{
					return false;
				}
				List<GameObject> list4 = ApplyAttackOverrides(clone, cH, isNpc, items3);
				component.m_randomArmor = list4.ToArray();
			}
			if (cH.aRandomShield.IsNotNull())
			{
				if (!ParseItemList(clone, cH.aRandomShield, list, out var items4))
				{
					return false;
				}
				List<GameObject> list5 = ApplyAttackOverrides(clone, cH, isNpc, items4);
				component.m_randomShield = list5.ToArray();
			}
			if (cH.aaRandomSets.IsNotNull())
			{
				List<GameObject[]> list6 = new List<GameObject[]>();
				foreach (List<string> item in cH.aaRandomSets.Select((RRRMobDataUtil.RandomSet a) => a.aSetItems))
				{
					if (!ParseItemList(clone, item, list, out var items5))
					{
						return false;
					}
					List<GameObject> list7 = ApplyAttackOverrides(clone, cH, isNpc, items5.ToList());
					if (items5.NonEmpty())
					{
						list6.Add(list7.ToArray());
					}
				}
				component.m_randomSets = ((IEnumerable<GameObject[]>)list6).Select((Func<GameObject[], ItemSet>)((GameObject[] s) => new ItemSet
				{
					m_items = s
				})).ToArray();
			}
			if (cH.aHitEffects.IsNotNull())
			{
				RRRMobDataUtil.DoEffectsList(cH.aHitEffects, ref ((Character)component).m_hitEffects);
			}
			if (cH.aDeathEffects.IsNotNull())
			{
				RRRMobDataUtil.DoEffectsList(cH.aDeathEffects, ref ((Character)component).m_deathEffects);
			}
			if (cH.aConsumeItemEffects.IsNotNull())
			{
				RRRMobDataUtil.DoEffectsList(cH.aConsumeItemEffects, ref component.m_consumeItemEffects);
			}
			if (isNpc)
			{
				AddNpcUnarmedAttack(clone, cH, component);
			}
			return true;
		}

		internal static bool ParseItemList(GameObject clone, List<string> itemCodes, List<GameObject> customAttacks, out List<ParseItemWrapper> items)
		{
			items = new List<ParseItemWrapper>();
			if (itemCodes == null)
			{
				return true;
			}
			foreach (string itemCode in itemCodes)
			{
				if (Utility.IsNullOrWhiteSpace(itemCode))
				{
					items.Add(null);
					return true;
				}
				if (customAttacks.IsNotNull() && itemCode.IndexOf("@") == 0 && int.TryParse(itemCode.Substring(1), out var result))
				{
					items.Add(new ParseItemWrapper(customAttacks[result - 1]));
					continue;
				}
				(string left, string right) tuple = itemCode.SplitOnFirst("@");
				string item = tuple.left;
				(string left, string right) tuple2 = tuple.right.SplitOnFirst("@");
				string item2 = tuple2.left;
				(string left, string right) tuple3 = tuple2.right.SplitOnFirst("@");
				string item3 = tuple3.left;
				string item4 = tuple3.right;
				GameObject val = RRRPrefabLoader.FindName(item);
				if ((Object)(object)val == (Object)null)
				{
					RRRMobData.FailMake("Unknown Item '" + item + "' for '" + ((Object)clone).name + "'.", ((Object)clone).name);
					return false;
				}
				items.Add(new ParseItemWrapper(val, item2, item3, item4));
			}
			return true;
		}

		internal static List<GameObject> ApplyAttackOverrides(GameObject owner, RRRCfgHumanoid cH, bool isNpc, List<ParseItemWrapper> items)
		{
			List<GameObject> list = new List<GameObject>();
			foreach (ParseItemWrapper item in items)
			{
				if (item == null)
				{
					list.Add(null);
					continue;
				}
				GameObject val = item.GameObject;
				string projectileName = (Utility.IsNullOrWhiteSpace(item.ProjectileName) ? cH.sAttackProjectileOverride : item.ProjectileName);
				if (val.GetComponent<ItemDrop>().IsNotNull())
				{
					val = RRRMobWeaponFactory.Get(owner, ((Object)val).name, isNpc, cH.dtAttackDamageOverride, cH.fAttackDamageTotalOverride, item.AnimationName, projectileName, item.AttackInterval);
				}
				list.Add(val);
			}
			return list;
		}

		internal static void AddNpcUnarmedAttack(GameObject clone, RRRCfgHumanoid cH, Humanoid h)
		{
			GameObject val = null;
			val = ((!cH.dtAttackDamageOverride.IsNotNull() && !cH.fAttackDamageTotalOverride.HasValue) ? RRRMobWeaponFactory.GetNpcUnarmed("RRR_NPC") : RRRMobWeaponFactory.GetNpcUnarmed(((Object)clone).name, cH.dtAttackDamageOverride, cH.fAttackDamageTotalOverride));
			h.m_unarmedWeapon = val.GetComponent<ItemDrop>();
		}

		internal static void ConvertHumanoid(GameObject prefab, RRRMobData output)
		{
			Humanoid component = prefab.GetComponent<Humanoid>();
			if (!component.IsNotNull())
			{
				return;
			}
			output.Category_Humanoid = new RRRCfgHumanoid();
			RRRCfgHumanoid category_Humanoid = output.Category_Humanoid;
			category_Humanoid.dtAttackDamageOverride = new RRRMobDataUtil.DamageTypes();
			category_Humanoid.fAttackDamageTotalOverride = null;
			category_Humanoid.sAttackProjectileOverride = null;
			category_Humanoid.aDefaultItems = component.m_defaultItems.Select((GameObject go) => (!go.IsNotNull()) ? "" : ((Object)go).name).ToList();
			category_Humanoid.aRandomWeapon = component.m_randomWeapon.Select((GameObject go) => (!go.IsNotNull()) ? "" : ((Object)go).name).ToList();
			category_Humanoid.aRandomArmor = component.m_randomArmor.Select((GameObject go) => (!go.IsNotNull()) ? "" : ((Object)go).name).ToList();
			category_Humanoid.aRandomShield = component.m_randomShield.Select((GameObject go) => (!go.IsNotNull()) ? "" : ((Object)go).name).ToList();
			category_Humanoid.aaRandomSets = component.m_randomSets.Select((ItemSet set) => RRRMobDataUtil.RandomSet.Unmake(set.m_items.Select((GameObject go) => (!go.IsNotNull()) ? "" : ((Object)go).name).ToList())).ToList();
			category_Humanoid.aHitEffects = ((Character)component).m_hitEffects.m_effectPrefabs.Select((EffectData p) => ((Object)p.m_prefab).name).ToList();
			category_Humanoid.aDeathEffects = ((Character)component).m_deathEffects.m_effectPrefabs.Select((EffectData p) => ((Object)p.m_prefab).name).ToList();
			category_Humanoid.aConsumeItemEffects = component.m_consumeItemEffects.m_effectPrefabs.Select((EffectData p) => ((Object)p.m_prefab).name).ToList();
		}
	}
	public class RRRCfgMonsterAI
	{
		public float? fAlertRange = 9999f;

		public bool? bFleeIfHurtWhenTargetCantBeReached = true;

		public bool? bFleeIfNotAlerted = true;

		public float? fFleeIfLowHealth = 0f;

		public bool? bCirculateWhileCharging = false;

		public bool? bCirculateWhileChargingFlying = false;

		public bool? bEnableHuntPlayer = false;

		public bool? bAttackPlayerObjects = true;

		public bool? bAttackPlayerObjectsWhenAlerted;

		public float? fInterceptTimeMax = 0f;

		public float? fInterceptTimeMin = 0f;

		public float? fMaxChaseDistance = 0f;

		public float? fMinAttackInterval = 0f;

		public float? fCircleTargetInterval = 0f;

		public float? fCircleTargetDuration = 0f;

		public float? fCircleTargetDistance = 0f;

		public bool? bSleeping;

		public bool? bNoiseWakeup;

		public float? fNoiseRangeScale;

		public float? fWakeupRange;

		public List<string> aWakeupEffects;

		public bool? bAvoidLand;

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

		public float? fConsumeRange = 2f;

		public float? fConsumeSearchRange = 5f;

		public float? fConsumeSearchInterval = 10f;

		public float? fConsumeHeal = 0f;

		internal static bool MakeMonsterAI(GameObject clone, RRRCfgMonsterAI cM)
		{
			MonsterAI component = clone.GetComponent<MonsterAI>();
			if (component == null)
			{
				RRRMobData.FailMake("No Monster component in '" + ((Object)clone).name + "'.", ((Object)clone).name);
				return false;
			}
			if (cM.fAlertRange.HasValue)
			{
				component.m_alertRange = cM.fAlertRange.Value;
			}
			if (cM.bFleeIfHurtWhenTargetCantBeReached.HasValue)
			{
				component.m_fleeIfHurtWhenTargetCantBeReached = cM.bFleeIfHurtWhenTargetCantBeReached.Value;
			}
			if (cM.bFleeIfNotAlerted.HasValue)
			{
				component.m_fleeIfNotAlerted = cM.bFleeIfNotAlerted.Value;
			}
			if (cM.fFleeIfLowHealth.HasValue)
			{
				component.m_fleeIfLowHealth = cM.fFleeIfLowHealth.Value;
			}
			if (cM.bCirculateWhileCharging.HasValue)
			{
				component.m_circulateWhileCharging = cM.bCirculateWhileCharging.Value;
			}
			if (cM.bCirculateWhileChargingFlying.HasValue)
			{
				component.m_circulateWhileChargingFlying = cM.bCirculateWhileChargingFlying.Value;
			}
			if (cM.bEnableHuntPlayer.HasValue)
			{
				component.m_enableHuntPlayer = cM.bEnableHuntPlayer.Value;
			}
			if (cM.bAttackPlayerObjects.HasValue)
			{
				component.m_attackPlayerObjects = cM.bAttackPlayerObjects.Value;
			}
			if (cM.fInterceptTimeMax.HasValue)
			{
				component.m_interceptTimeMax = cM.fInterceptTimeMax.Value;
			}
			if (cM.fInterceptTimeMin.HasValue)
			{
				component.m_interceptTimeMin = cM.fInterceptTimeMin.Value;
			}
			if (cM.fMaxChaseDistance.HasValue)
			{
				component.m_maxChaseDistance = cM.fMaxChaseDistance.Value;
			}
			if (cM.fMinAttackInterval.HasValue)
			{
				component.m_minAttackInterval = cM.fMinAttackInterval.Value;
			}
			if (cM.fCircleTargetInterval.HasValue)
			{
				component.m_circleTargetInterval = cM.fCircleTargetInterval.Value;
			}
			if (cM.fCircleTargetDuration.HasValue)
			{
				component.m_circleTargetDuration = cM.fCircleTargetDuration.Value;
			}
			if (cM.fCircleTargetDistance.HasValue)
			{
				component.m_circleTargetDistance = cM.fCircleTargetDistance.Value;
			}
			if (cM.bSleeping.HasValue)
			{
				component.m_sleeping = cM.bSleeping.Value;
			}
			if (cM.bNoiseWakeup.HasValue)
			{
				component.m_noiseWakeup = cM.bNoiseWakeup.Value;
			}
			if (cM.fWakeupRange.HasValue)
			{
				component.m_wakeupRange = cM.fWakeupRange.Value;
			}
			if (cM.aWakeupEffects.IsNotNull())
			{
				RRRMobDataUtil.DoEffectsList(cM.aWakeupEffects, ref component.m_wakeupEffects);
			}
			if (cM.bAvoidLand.HasValue)
			{
				component.m_avoidLand = cM.bAvoidLand.Value;
			}
			if (!RRRCfgHumanoid.ParseItemList(clone, cM.aConsumeItems, null, out var items))
			{
				return false;
			}
			component.m_consumeItems = items.Select((RRRCfgHumanoid.ParseItemWrapper i) => i.GameObject.GetComponent<ItemDrop>()).ToList();
			if (cM.fConsumeRange.HasValue)
			{
				component.m_consumeRange = cM.fConsumeRange.Value;
			}
			if (cM.fConsumeSearchRange.HasValue)
			{
				component.m_consumeSearchRange = cM.fConsumeSearchRange.Value;
			}
			if (cM.fConsumeSearchInterval.HasValue)
			{
				component.m_consumeSearchInterval = cM.fConsumeSearchInterval.Value;
			}
			return true;
		}

		internal static void ConvertMonsterAI(GameObject prefab, RRRMobData output)
		{
			MonsterAI component = prefab.GetComponent<MonsterAI>();
			if (component.IsNotNull())
			{
				output.Category_MonsterAI = new RRRCfgMonsterAI();
				RRRCfgMonsterAI category_MonsterAI = output.Category_MonsterAI;
				category_MonsterAI.fAlertRange = component.m_alertRange;
				category_MonsterAI.bFleeIfHurtWhenTargetCantBeReached = component.m_fleeIfHurtWhenTargetCantBeReached;
				category_MonsterAI.bFleeIfNotAlerted = component.m_fleeIfNotAlerted;
				category_MonsterAI.fFleeIfLowHealth = component.m_fleeIfLowHealth;
				category_MonsterAI.bCirculateWhileCharging = component.m_circulateWhileCharging;
				category_MonsterAI.bCirculateWhileChargingFlying = component.m_circulateWhileChargingFlying;
				category_MonsterAI.bEnableHuntPlayer = component.m_enableHuntPlayer;
				category_MonsterAI.bAttackPlayerObjects = component.m_attackPlayerObjects;
				category_MonsterAI.fInterceptTimeMax = component.m_interceptTimeMax;
				category_MonsterAI.fInterceptTimeMin = component.m_interceptTimeMin;
				category_MonsterAI.fMaxChaseDistance = component.m_maxChaseDistance;
				category_MonsterAI.fMinAttackInterval = component.m_minAttackInterval;
				category_MonsterAI.fCircleTargetInterval = component.m_circleTargetInterval;
				category_MonsterAI.fCircleTargetDuration = component.m_circleTargetDuration;
				category_MonsterAI.fCircleTargetDistance = component.m_circleTargetDistance;
				category_MonsterAI.bSleeping = component.m_sleeping;
				category_MonsterAI.bNoiseWakeup = component.m_noiseWakeup;
				category_MonsterAI.fWakeupRange = component.m_wakeupRange;
				category_MonsterAI.aWakeupEffects = component.m_wakeupEffects.m_effectPrefabs.Select((EffectData p) => ((Object)p.m_prefab).name).ToList();
				category_MonsterAI.bAvoidLand = component.m_avoidLand;
				category_MonsterAI.aConsumeItems = component.m_consumeItems.Select((ItemDrop id) => (!id.IsNotNull()) ? "" : ((Object)((Component)id).gameObject).name).ToList();
				category_MonsterAI.fConsumeRange = component.m_consumeRange;
				category_MonsterAI.fConsumeSearchRange = component.m_consumeSearchRange;
				category_MonsterAI.fConsumeSearchInterval = component.m_consumeSearchInterval;
			}
		}
	}
	public class RRRCfgNpcOnly
	{
		public bool bIsFemale;

		public bool bRandomGender;

		public bool? bNoBeardIfFemale = false;

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

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

		public RRRMobDataUtil.Color cSkinColorMin = new RRRMobDataUtil.Color();

		public RRRMobDataUtil.Color cSkinColorMax = new RRRMobDataUtil.Color();

		public RRRMobDataUtil.Color cHairColorMin = new RRRMobDataUtil.Color();

		public RRRMobDataUtil.Color cHairColorMax = new RRRMobDataUtil.Color();

		public float fHairValueMin = 0.5f;

		public float fHairValueMax = 0.5f;

		internal static bool MakeNpc(GameObject clone, RRRCfgNpcOnly cN)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			RRRNpcCustomization component = clone.GetComponent<RRRNpcCustomization>();
			if (component == null)
			{
				RRRMobData.FailMake("No RRRNpcCustomization component in '" + ((Object)clone).name + "'.", ((Object)clone).name);
				return false;
			}
			component.IsFemale = cN.bIsFemale;
			component.IsRandomGender = cN.bRandomGender;
			component.IsNoBeardIfFemale = cN.bNoBeardIfFemale.GetValueOrDefault(false);
			component.BeardItems = cN.aBeardIds;
			component.HairItems = cN.aHairIds;
			component.HairColorMin = cN.cHairColorMin.Make();
			component.HairColorMax = cN.cHairColorMax.Make();
			component.SkinColorMin = cN.cSkinColorMin.Make();
			component.SkinColorMax = cN.cSkinColorMax.Make();
			component.HairValueMin = cN.fHairValueMin;
			component.HairValueMax = cN.fHairValueMax;
			return true;
		}

		internal static GameObject InitNpc(string fullNewName)
		{
			GameObject obj = RRRPrefabLoader.Clone("Goblin", fullNewName);
			Npc.DesignNpcBase(obj);
			return obj;
		}

		internal static void ConvertNpc(GameObject prefab, RRRMobData output)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			RRRNpcCustomization component = prefab.GetComponent<RRRNpcCustomization>();
			if (component.IsNotNull())
			{
				output.Category_NpcOnly = new RRRCfgNpcOnly();
				RRRCfgNpcOnly category_NpcOnly = output.Category_NpcOnly;
				category_NpcOnly.bIsFemale = component.IsFemale;
				category_NpcOnly.bRandomGender = component.IsRandomGender;
				category_NpcOnly.aBeardIds = component.BeardItems;
				category_NpcOnly.aHairIds = component.HairItems;
				category_NpcOnly.cHairColorMin = RRRMobDataUtil.Color.Unmake(component.HairColorMin);
				category_NpcOnly.cHairColorMax = RRRMobDataUtil.Color.Unmake(component.HairColorMax);
				category_NpcOnly.cSkinColorMin = RRRMobDataUtil.Color.Unmake(component.SkinColorMin);
				category_NpcOnly.cSkinColorMax = RRRMobDataUtil.Color.Unmake(component.SkinColorMax);
				category_NpcOnly.fHairValueMin = component.HairValueMin;
				category_NpcOnly.fHairValueMax = component.HairValueMax;
			}
			else
			{
				output.Category_NpcOnly = null;
			}
		}
	}
	public class RRRCfgSpecial
	{
		public bool bCanTame;

		public bool bAlwaysTame;

		public bool bCommandableWhenTame;

		public bool bCanProcreateWhenTame;

		public bool? bFxNoTame = false;

		public bool bSfxNoAlert;

		public bool bSfxNoIdle;

		public bool bSfxNoHit;

		public bool bSfxNoDeath;
	}
	public static class RRRMobDataUtil
	{
		public class CustomAttack
		{
			public string sOriginalPrefabName = "";

			public string sTargetAnim;

			public float? fAIAttackInterval;

			public float? fAIAttackRange;

			public float? fAIAttackRangeMin;

			public float? fAIAttackMaxAngle;

			public bool? bAIPrioritized;

			public string sAITargetType;

			public bool? bBlockable;

			public bool? bDodgeable;

			public bool? bForceAttackChainZero;

			public bool? bUseCharacterFacing;

			public float? fAttackRange;

			public float? fAttackHeight;

			public float? fAttackRayWidth;

			public string sAttackStatusEffect;

			public DamageTypes dtAttackDamageOverride;

			public float? fAttackDamageTotalOverride;

			public string sAttackProjectileOverride;

			public List<string> aStartEffects;

			public List<string> aHitEffects;

			public List<string> aTriggerEffects;

			public GameObject Make(GameObject clone, bool isNpc, int id)
			{
				//IL_01af: 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)
				GameObject obj = RRRMobWeaponFactory.Get(clone, sOriginalPrefabName, isNpc, dtAttackDamageOverride, fAttackDamageTotalOverride, sTargetAnim, sAttackProjectileOverride, fAIAttackInterval, $"{((Object)clone).name}_Custom_{sOriginalPrefabName}_{id}");
				SharedData shared = obj.GetComponent<ItemDrop>().m_itemData.m_shared;
				Attack attack = shared.m_attack;
				if (bAIPrioritized.HasValue)
				{
					shared.m_aiPrioritized = bAIPrioritized.Value;
				}
				if (fAIAttackRange.HasValue)
				{
					shared.m_aiAttackRange = fAIAttackRange.Value;
				}
				if (fAIAttackRangeMin.HasValue)
				{
					shared.m_aiAttackRangeMin = fAIAttackRangeMin.Value;
				}
				if (fAIAttackMaxAngle.HasValue)
				{
					shared.m_aiAttackMaxAngle = fAIAttackMaxAngle.Value;
				}
				if (bBlockable.HasValue)
				{
					shared.m_blockable = bBlockable.Value;
				}
				if (bDodgeable.HasValue)
				{
					shared.m_dodgeable = bDodgeable.Value;
				}
				if (bForceAttackChainZero.HasValue)
				{
					attack.m_attackChainLevels = 0;
				}
				if (bUseCharacterFacing.HasValue)
				{
					attack.m_useCharacterFacing = bUseCharacterFacing.Value;
				}
				if (fAttackRange.HasValue)
				{
					attack.m_attackRange = fAttackRange.Value;
				}
				if (fAttackHeight.HasValue)
				{
					attack.m_attackHeight = fAttackHeight.Value;
				}
				if (fAttackRayWidth.HasValue)
				{
					attack.m_attackRayWidth = fAttackRayWidth.Value;
				}
				if (Enum.TryParse<AiTarget>(sAITargetType, out AiTarget result))
				{
					shared.m_aiTargetType = result;
				}
				if (sAttackStatusEffect.IsNotNull())
				{
					shared.m_attackStatusEffect = ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(sAttackStatusEffect));
				}
				DoEffectsList(aStartEffects, ref shared.m_startEffect);
				DoEffectsList(aHitEffects, ref shared.m_hitEffect);
				DoEffectsList(aTriggerEffects, ref shared.m_triggerEffect);
				return obj;
			}
		}

		public class Color
		{
			public float fRed = 0.5f;

			public float fGreen = 0.5f;

			public float fBlue = 0.5f;

			public Color Make()
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				return new Color(fRed, fGreen, fBlue);
			}

			public static Color Unmake(Color c)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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)
				return new Color
				{
					fRed = c.r,
					fGreen = c.g,
					fBlue = c.b
				};
			}
		}

		public class Vector3
		{
			public float fX;

			public float fY;

			public float fZ;

			public Vector3 Make()
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				return new Vector3(fX, fY, fZ);
			}

			public static Vector3 Unmake(Vector3 v)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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)
				return new Vector3
				{
					fX = v.x,
					fY = v.y,
					fZ = v.z
				};
			}
		}

		public class RandomSet
		{
			public List<string> aSetItems = new List<string> { "", "" };

			public static RandomSet Unmake(List<string> list)
			{
				return new RandomSet
				{
					aSetItems = list
				};
			}
		}

		public class DamageTypes
		{
			public float fDamage;

			public float fBlunt;

			public float fSlash;

			public float fPierce;

			public float fChop;

			public float fPickaxe;

			public float fFire;

			public float fFrost;

			public float fLightning;

			public float fPoison;

			public float fSpirit;

			public DamageTypes Make()
			{
				//IL_0002: 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)
				DamageTypes result = default(DamageTypes);
				result.m_damage = fDamage;
				result.m_blunt = fBlunt;
				result.m_slash = fSlash;
				result.m_pierce = fPierce;
				result.m_chop = fChop;
				result.m_pickaxe = fPickaxe;
				result.m_fire = fFire;
				result.m_frost = fFrost;
				result.m_lightning = fLightning;
				result.m_poison = fPoison;
				result.m_spirit = fSpirit;
				return result;
			}

			public static DamageTypes Unmake(DamageTypes dt)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: 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)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				return new DamageTypes
				{
					fDamage = dt.m_damage,
					fBlunt = dt.m_blunt,
					fSlash = dt.m_slash,
					fPierce = dt.m_pierce,
					fChop = dt.m_chop,
					fPickaxe = dt.m_pickaxe,
					fFire = dt.m_fire,
					fFrost = dt.m_frost,
					fLightning = dt.m_lightning,
					fPoison = dt.m_poison,
					fSpirit = dt.m_spirit
				};
			}
		}

		public class Drop
		{
			public string sPrefabName = "";

			public int iAmountMin = 1;

			public int iAmountMax = 1;

			public float fChance = 0.5f;

			public bool bOnePerPlayer;

			public bool bLevelMultiplier;

			public Drop Make()
			{
				//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_001b: 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_0033: 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_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Expected O, but got Unknown
				return new Drop
				{
					m_prefab = ObjectDB.instance.GetItemPrefab(sPrefabName),
					m_amountMin = iAmountMin,
					m_amountMax = iAmountMax,
					m_chance = fChance,
					m_onePerPlayer = bOnePerPlayer,
					m_levelMultiplier = bLevelMultiplier
				};
			}

			public static Drop Unmake(Drop d)
			{
				return new Drop
				{
					sPrefabName = ((Object)d.m_prefab).name,
					iAmountMin = d.m_amountMin,
					iAmountMax = d.m_amountMax,
					fChance = d.m_chance,
					bOnePerPlayer = d.m_onePerPlayer,
					bLevelMultiplier = d.m_levelMultiplier
				};
			}
		}

		public const string DelayedLookupNamePrefix = "_PLACEHOLDER_";

		public static readonly Vector3 zero = Vector3.Unmake(Vector3.zero);

		public static readonly Vector3 one = Vector3.Unmake(Vector3.one);

		public const string ConfigFormatVersion_0_2_0 = "0.2.0";

		public static void DoEffectsList(List<string> names, ref EffectList targetList)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			if (names == null)
			{
				return;
			}
			targetList = new EffectList
			{
				m_effectPrefabs = names.Select(delegate(string s)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Expected O, but got Unknown
					//IL_002c: Unknown result type (might be due to invali