Decompiled source of FireflyOfTheDeath v1.2.0

FireflyOfTheDeath.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace FireflyOfTheDeath;

[BepInPlugin("alkin.FireflyOfTheDeath", "Firefly of the Death", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(ZNetView), "Awake")]
	private static class ZNetViewAwakePrefabInit
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !PrefabInit;
		}
	}

	[HarmonyPatch(typeof(ZSyncTransform), "Awake")]
	private static class ZSyncTransformAwakePrefabInit
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !PrefabInit;
		}
	}

	[HarmonyPatch(typeof(ZSyncTransform), "OnEnable")]
	private static class ZSyncTransformEnablePrefabInit
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !PrefabInit;
		}
	}

	[HarmonyPatch(typeof(ItemDrop), "Awake")]
	private static class ItemDropAwakePrefabInit
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !PrefabInit;
		}
	}

	[HarmonyPatch(typeof(ItemDrop), "Start")]
	private static class ItemDropStartPrefabInit
	{
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !PrefabInit;
		}
	}

	[HarmonyPatch]
	private static class SEManAddStatusEffectPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return AccessTools.GetDeclaredMethods(typeof(SEMan)).FindAll((MethodInfo method) => method.Name == "AddStatusEffect");
		}

		private static void Prefix(SEMan __instance, object[] __args)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (__instance == null || __args == null || __args.Length == 0)
			{
				return;
			}
			int num = 0;
			object obj = __args[0];
			if (obj is int)
			{
				num = (int)obj;
			}
			else if (obj is StatusEffect)
			{
				StatusEffect val = (StatusEffect)obj;
				if (((Object)val).name == "FireflyOfTheDeath")
				{
					num = SE_FireflyOfDeath.StatusEffectHash;
				}
				else if (((Object)val).name == "Firefly")
				{
					num = StringExtensionMethods.GetStableHashCode("Firefly");
				}
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode("Firefly");
			int statusEffectHash = SE_FireflyOfDeath.StatusEffectHash;
			if (num == statusEffectHash)
			{
				__instance.RemoveStatusEffect(stableHashCode, true);
				__instance.RemoveStatusEffect(statusEffectHash, true);
			}
			else if (num == stableHashCode)
			{
				__instance.RemoveStatusEffect(statusEffectHash, true);
				__instance.RemoveStatusEffect(stableHashCode, true);
			}
		}
	}

	public const string PluginId = "alkin.FireflyOfTheDeath";

	public const string PluginName = "Firefly of the Death";

	public const string Version = "1.2.0";

	internal static Plugin Instance;

	internal static readonly Harmony Harmony = new Harmony("alkin.FireflyOfTheDeath");

	internal static ConfigEntry<int> ItemStackSize;

	internal static ConfigEntry<string> ItemCraftingStation;

	internal static ConfigEntry<int> ItemMinStationLevel;

	internal static ConfigEntry<int> StatusEffectDuration;

	internal static ConfigEntry<string> ItemRecipe;

	internal static ConfigEntry<float> ItemWeight;

	internal static ConfigEntry<Color> LightColor;

	internal static ConfigEntry<float> LightIntensityOutdoors;

	internal static ConfigEntry<float> LightRangeOutdoors;

	internal static ConfigEntry<float> LightShadowsOutdoors;

	internal static ConfigEntry<float> LightIntensityIndoors;

	internal static ConfigEntry<float> LightRangeIndoors;

	internal static ConfigEntry<float> LightShadowsIndoors;

	internal static ConfigEntry<bool> ShowLightSource;

	internal static ConfigEntry<bool> ShowLightFlare;

	internal static GameObject RootObject;

	internal static GameObject RootPrefabs;

	internal static GameObject ItemPrefab;

	internal static GameObject BallPrefab;

	internal static bool PrefabInit;

	private void Awake()
	{
		Instance = this;
		BindConfig();
		Harmony.PatchAll();
		Game.isModded = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Firefly of the Death 1.2.0 loaded.");
	}

	private void OnDestroy()
	{
		Harmony.UnpatchSelf();
		Instance = null;
	}

	private void BindConfig()
	{
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		ItemStackSize = ((BaseUnityPlugin)this).Config.Bind<int>("Item", "Stack size", 20, "How many items in stack");
		ItemCraftingStation = ((BaseUnityPlugin)this).Config.Bind<string>("Item", "Crafting station", "$piece_workbench", "Station to craft item. Leave empty to craft with hands");
		ItemMinStationLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Item", "Crafting station level", 3, "Minimum level of station required to craft");
		StatusEffectDuration = ((BaseUnityPlugin)this).Config.Bind<int>("Item", "Duration", 300, "Duration of status effect");
		ItemRecipe = ((BaseUnityPlugin)this).Config.Bind<string>("Item", "Recipe", "Dandelion:1,GreydwarfEye:1,Resin:2", "Item recipe");
		ItemWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Item", "Weight", 0.5f, "Item weight");
		LightColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Light", "Color", new Color(0.72f, 0.02f, 0.02f), "Color of firefly light");
		LightIntensityOutdoors = ((BaseUnityPlugin)this).Config.Bind<float>("Light - Outdoors", "Intensity", 1f, "Intensity of light");
		LightRangeOutdoors = ((BaseUnityPlugin)this).Config.Bind<float>("Light - Outdoors", "Range", 15f, "Range of light");
		LightShadowsOutdoors = ((BaseUnityPlugin)this).Config.Bind<float>("Light - Outdoors", "Shadows strength", 0.8f, "Strength of shadows");
		LightIntensityIndoors = ((BaseUnityPlugin)this).Config.Bind<float>("Light - Indoors", "Intensity", 0.8f, "Intensity of light");
		LightRangeIndoors = ((BaseUnityPlugin)this).Config.Bind<float>("Light - Indoors", "Range", 10f, "Range of light");
		LightShadowsIndoors = ((BaseUnityPlugin)this).Config.Bind<float>("Light - Indoors", "Shadows strength", 0.9f, "Strength of shadows");
		ShowLightSource = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "Show point of light source", false, "Show floating point of light. Restart to see changes.");
		ShowLightFlare = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "Show flare around light source", false, "Show flare surrounding point of light. Restart to see changes.");
		ItemCraftingStation.SettingChanged += delegate
		{
			DeathFireflyItem.SetRecipe();
		};
		ItemMinStationLevel.SettingChanged += delegate
		{
			DeathFireflyItem.SetRecipe();
		};
		ItemWeight.SettingChanged += delegate
		{
			DeathFireflyItem.PatchItemOnConfigChange();
		};
		ItemStackSize.SettingChanged += delegate
		{
			DeathFireflyItem.PatchItemOnConfigChange();
		};
	}

	internal static GameObject InitPrefabClone(GameObject source, string name)
	{
		InitRootObject();
		Transform val = RootPrefabs.transform.Find(name);
		if (Object.op_Implicit((Object)(object)val))
		{
			return ((Component)val).gameObject;
		}
		PrefabInit = true;
		GameObject val2;
		try
		{
			val2 = Object.Instantiate<GameObject>(source, RootPrefabs.transform, false);
		}
		finally
		{
			PrefabInit = false;
		}
		((Object)val2).name = name;
		return val2;
	}

	private static void InitRootObject()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)RootObject))
		{
			RootObject = (GameObject)(((object)GameObject.Find("_fireflyDeathRoot")) ?? ((object)new GameObject("_fireflyDeathRoot")));
		}
		Object.DontDestroyOnLoad((Object)(object)RootObject);
		if (!Object.op_Implicit((Object)(object)RootPrefabs))
		{
			Transform val = RootObject.transform.Find("Prefabs");
			RootPrefabs = (GameObject)(Object.op_Implicit((Object)(object)val) ? ((object)((Component)val).gameObject) : ((object)new GameObject("Prefabs")));
			if (!Object.op_Implicit((Object)(object)val))
			{
				RootPrefabs.transform.SetParent(RootObject.transform, false);
			}
			RootPrefabs.SetActive(false);
		}
	}
}
internal static class DeathFireflyItem
{
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	private static class ObjectDBAwake
	{
		private static void Postfix(ObjectDB __instance)
		{
			if (__instance.m_items.Count != 0 && Object.op_Implicit((Object)(object)__instance.GetItemPrefab("Wood")))
			{
				RegisterPrefab();
			}
		}
	}

	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	private static class ObjectDBCopy
	{
		private static void Postfix(ObjectDB __instance)
		{
			if (__instance.m_items.Count != 0 && Object.op_Implicit((Object)(object)__instance.GetItemPrefab("Wood")))
			{
				RegisterPrefab();
			}
		}
	}

	[HarmonyPatch(typeof(FejdStartup), "OnDestroy")]
	private static class FejdDestroy
	{
		private static void Prefix()
		{
			ClearReferences();
		}
	}

	internal const string ItemName = "FireflyOfTheDeath";

	internal const string ItemToken = "$item_firefly_death";

	internal const string DescriptionToken = "$item_firefly_death_description";

	internal static readonly int ItemHash = StringExtensionMethods.GetStableHashCode("FireflyOfTheDeath");

	private static Sprite[] s_redIcons;

	private static void CreatePrefab()
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: 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_00af: Expected O, but got Unknown
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Expected O, but got Unknown
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Wisp");
		if (!Object.op_Implicit((Object)(object)itemPrefab))
		{
			return;
		}
		Plugin.ItemPrefab = Plugin.InitPrefabClone(itemPrefab, "FireflyOfTheDeath");
		Transform val = Plugin.ItemPrefab.transform.Find("demister_ball");
		if (Object.op_Implicit((Object)(object)val))
		{
			((Object)val).name = "firefly_death_ball_item";
			val.localScale *= 0.75f;
			MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
			if (Object.op_Implicit((Object)(object)component))
			{
				((Renderer)component).sharedMaterial = new Material(((Renderer)component).sharedMaterial)
				{
					name = "firefly_death_ball_item"
				};
				((Renderer)component).sharedMaterial.SetColor("_EmissionColor", Plugin.LightColor.Value);
			}
		}
		Transform val2 = Plugin.ItemPrefab.transform.Find("flare");
		if (Object.op_Implicit((Object)(object)val2))
		{
			ParticleSystem component2 = ((Component)val2).GetComponent<ParticleSystem>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				MainModule main = component2.main;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.8f, 0.02f, 0.02f, 0.35f));
			}
		}
		Transform val3 = Plugin.ItemPrefab.transform.Find("sparcs_front");
		if (Object.op_Implicit((Object)(object)val3))
		{
			ParticleSystemRenderer component3 = ((Component)val3).GetComponent<ParticleSystemRenderer>();
			if (Object.op_Implicit((Object)(object)component3))
			{
				((Renderer)component3).sharedMaterial = new Material(((Renderer)component3).sharedMaterial)
				{
					name = "firefly_death_sparcs_item"
				};
				((Renderer)component3).sharedMaterial.SetColor("_EmissionColor", Plugin.LightColor.Value);
			}
		}
		Transform val4 = Plugin.ItemPrefab.transform.Find("Point light");
		if (Object.op_Implicit((Object)(object)val4) && Object.op_Implicit((Object)(object)((Component)val4).GetComponent<Light>()))
		{
			((Component)val4).GetComponent<Light>().color = Plugin.LightColor.Value;
		}
	}

	internal static void PatchItemData(ItemData data)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		if (data != null)
		{
			data.m_dropPrefab = Plugin.ItemPrefab;
			data.m_shared.m_name = "Firefly of the Death";
			data.m_shared.m_description = "A blood-red firefly bound to the memory of your last tomb.";
			data.m_shared.m_itemType = (ItemType)2;
			data.m_shared.m_icons = CreateRedIcons(data.m_shared.m_icons);
			StatusEffect consumeStatusEffect = ObjectDB.instance.m_StatusEffects.Find((StatusEffect effect) => Object.op_Implicit((Object)(object)effect) && ((Object)effect).name == "FireflyOfTheDeath");
			data.m_shared.m_consumeStatusEffect = consumeStatusEffect;
			data.m_shared.m_maxStackSize = Plugin.ItemStackSize.Value;
			data.m_shared.m_maxQuality = 1;
			data.m_shared.m_weight = Plugin.ItemWeight.Value;
		}
	}

	private static Sprite[] CreateRedIcons(Sprite[] sourceIcons)
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: 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_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		if (s_redIcons != null)
		{
			return s_redIcons;
		}
		if (sourceIcons == null || sourceIcons.Length == 0)
		{
			return sourceIcons;
		}
		s_redIcons = (Sprite[])(object)new Sprite[sourceIcons.Length];
		Vector2 val4 = default(Vector2);
		for (int i = 0; i < sourceIcons.Length; i++)
		{
			Sprite val = sourceIcons[i];
			if (!Object.op_Implicit((Object)(object)val))
			{
				continue;
			}
			Texture2D texture = val.texture;
			Rect textureRect = val.textureRect;
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			RenderTexture active = RenderTexture.active;
			Graphics.Blit((Texture)(object)texture, temporary);
			RenderTexture.active = temporary;
			Texture2D val2 = new Texture2D(((Texture)texture).width, ((Texture)texture).height, (TextureFormat)4, false);
			val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), 0, 0);
			val2.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			Color[] pixels = val2.GetPixels();
			for (int j = 0; j < pixels.Length; j++)
			{
				Color val3 = pixels[j];
				if (!(val3.a <= 0.001f))
				{
					float num = Mathf.Max(val3.r, Mathf.Max(val3.g, val3.b));
					float num2 = (val3.r + val3.g + val3.b) / 3f;
					float num3 = Mathf.Clamp01(Mathf.Max(num, num2));
					pixels[j] = new Color(num3, num3 * 0.08f, num3 * 0.06f, val3.a);
				}
			}
			val2.SetPixels(pixels);
			val2.Apply();
			((Object)val2).name = ((Object)texture).name + "_firefly_death_red";
			((Vector2)(ref val4))..ctor(val.pivot.x / ((Rect)(ref textureRect)).width, val.pivot.y / ((Rect)(ref textureRect)).height);
			s_redIcons[i] = Sprite.Create(val2, textureRect, val4, val.pixelsPerUnit, 0u, (SpriteMeshType)1, val.border);
			((Object)s_redIcons[i]).name = ((Object)val).name + "_firefly_death_red";
		}
		return s_redIcons;
	}

	private static void RegisterPrefab()
	{
		ClearReferences();
		if (!Object.op_Implicit((Object)(object)Plugin.ItemPrefab))
		{
			CreatePrefab();
		}
		if (!Object.op_Implicit((Object)(object)Plugin.ItemPrefab))
		{
			return;
		}
		SE_FireflyOfDeath.AddCustomStatusEffect(ObjectDB.instance);
		ItemDrop component = Plugin.ItemPrefab.GetComponent<ItemDrop>();
		PatchItemData(Object.op_Implicit((Object)(object)component) ? component.m_itemData : null);
		if (Object.op_Implicit((Object)(object)ObjectDB.instance) && !PrivateValheimDictionary.ContainsKey(ObjectDB.instance, "m_itemByHash", ItemHash))
		{
			ObjectDB.instance.m_items.Add(Plugin.ItemPrefab);
			PrivateValheimDictionary.Add(ObjectDB.instance, "m_itemByHash", ItemHash, Plugin.ItemPrefab);
			if ((Object)(object)component != (Object)null)
			{
				PrivateValheimDictionary.Set(ObjectDB.instance, "m_itemByData", component.m_itemData.m_shared, Plugin.ItemPrefab);
			}
		}
		if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !PrivateValheimDictionary.ContainsKey(ZNetScene.instance, "m_namedPrefabs", ItemHash))
		{
			ZNetScene.instance.m_prefabs.Add(Plugin.ItemPrefab);
			PrivateValheimDictionary.Add(ZNetScene.instance, "m_namedPrefabs", ItemHash, Plugin.ItemPrefab);
		}
		SetRecipe();
	}

	internal static void SetRecipe()
	{
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || !Object.op_Implicit((Object)(object)Plugin.ItemPrefab))
		{
			return;
		}
		ObjectDB.instance.m_recipes.RemoveAll((Recipe x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name == "FireflyOfTheDeath");
		CraftingStation craftingStation = null;
		if (!string.IsNullOrWhiteSpace(Plugin.ItemCraftingStation.Value))
		{
			Recipe val = ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_craftingStation) && r.m_craftingStation.m_name == Plugin.ItemCraftingStation.Value));
			craftingStation = (Object.op_Implicit((Object)(object)val) ? val.m_craftingStation : null);
		}
		Recipe val2 = ScriptableObject.CreateInstance<Recipe>();
		((Object)val2).name = "FireflyOfTheDeath";
		val2.m_amount = 1;
		val2.m_minStationLevel = Plugin.ItemMinStationLevel.Value;
		val2.m_item = Plugin.ItemPrefab.GetComponent<ItemDrop>();
		val2.m_enabled = true;
		val2.m_craftingStation = craftingStation;
		List<Requirement> list = new List<Requirement>();
		string[] array = Plugin.ItemRecipe.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
		foreach (string text in array)
		{
			string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries);
			if (array2.Length == 2 && int.TryParse(array2[1], out var result) && result > 0)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array2[0].Trim());
				if (Object.op_Implicit((Object)(object)itemPrefab))
				{
					list.Add(new Requirement
					{
						m_amount = result,
						m_resItem = itemPrefab.GetComponent<ItemDrop>()
					});
				}
			}
		}
		val2.m_resources = list.ToArray();
		ObjectDB.instance.m_recipes.Add(val2);
	}

	internal static void ClearReferences()
	{
		if (Object.op_Implicit((Object)(object)ObjectDB.instance) && PrivateValheimDictionary.ContainsKey(ObjectDB.instance, "m_itemByHash", ItemHash))
		{
			GameObject val = PrivateValheimDictionary.Get<GameObject>(ObjectDB.instance, "m_itemByHash", ItemHash);
			if (Object.op_Implicit((Object)(object)val))
			{
				ObjectDB.instance.m_items.Remove(val);
			}
			PrivateValheimDictionary.Remove(ObjectDB.instance, "m_itemByHash", ItemHash);
		}
		if (Object.op_Implicit((Object)(object)ZNetScene.instance) && PrivateValheimDictionary.ContainsKey(ZNetScene.instance, "m_namedPrefabs", ItemHash))
		{
			GameObject val2 = PrivateValheimDictionary.Get<GameObject>(ZNetScene.instance, "m_namedPrefabs", ItemHash);
			if (Object.op_Implicit((Object)(object)val2))
			{
				ZNetScene.instance.m_prefabs.Remove(val2);
			}
			PrivateValheimDictionary.Remove(ZNetScene.instance, "m_namedPrefabs", ItemHash);
		}
	}

	internal static void PatchItemOnConfigChange()
	{
		ItemDrop val = (Object.op_Implicit((Object)(object)Plugin.ItemPrefab) ? Plugin.ItemPrefab.GetComponent<ItemDrop>() : null);
		PatchItemData(Object.op_Implicit((Object)(object)val) ? val.m_itemData : null);
	}
}
internal static class PrivateValheimDictionary
{
	private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static object Dictionary(object owner, string fieldName)
	{
		FieldInfo field = owner.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field == null)
		{
			throw new MissingFieldException(owner.GetType().FullName, fieldName);
		}
		return field.GetValue(owner);
	}

	internal static bool ContainsKey(object owner, string fieldName, object key)
	{
		object obj = Dictionary(owner, fieldName);
		return (bool)obj.GetType().GetMethod("ContainsKey").Invoke(obj, new object[1] { key });
	}

	internal static void Add(object owner, string fieldName, object key, object value)
	{
		object obj = Dictionary(owner, fieldName);
		obj.GetType().GetMethod("Add").Invoke(obj, new object[2] { key, value });
	}

	internal static void Set(object owner, string fieldName, object key, object value)
	{
		object obj = Dictionary(owner, fieldName);
		PropertyInfo property = obj.GetType().GetProperty("Item");
		if (property != null)
		{
			property.SetValue(obj, value, new object[1] { key });
		}
		else
		{
			Remove(owner, fieldName, key);
			Add(owner, fieldName, key, value);
		}
	}

	internal static T Get<T>(object owner, string fieldName, object key) where T : class
	{
		object obj = Dictionary(owner, fieldName);
		PropertyInfo property = obj.GetType().GetProperty("Item");
		return (property == null) ? null : (property.GetValue(obj, new object[1] { key }) as T);
	}

	internal static void Remove(object owner, string fieldName, object key)
	{
		object obj = Dictionary(owner, fieldName);
		obj.GetType().GetMethod("Remove").Invoke(obj, new object[1] { key });
	}
}
public class SE_FireflyOfDeath : StatusEffect
{
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	[HarmonyPriority(500)]
	private static class ObjectDBAwakeStatus
	{
		private static void Postfix(ObjectDB __instance)
		{
			AddCustomStatusEffect(__instance);
		}
	}

	public const string StatusEffectName = "FireflyOfTheDeath";

	public const string BallPrefabName = "firefly_death_ball";

	public static readonly int StatusEffectHash = StringExtensionMethods.GetStableHashCode("FireflyOfTheDeath");

	public static readonly int BallPrefabHash = StringExtensionMethods.GetStableHashCode("firefly_death_ball");

	public LightFlicker m_lightFlicker;

	public LightLod m_lightLod;

	public Light m_light;

	public bool m_indoors;

	public GameObject m_ballPrefab;

	public Vector3 m_offset = new Vector3(0.1f, 3.5f, 0.1f);

	public Vector3 m_offsetInterior = new Vector3(0.5f, 2.1f, 0f);

	public float m_maxDistance = 7f;

	public float m_ballAcceleration = 6f;

	public float m_ballMaxSpeed = 60f;

	public float m_ballFriction = 0.02f;

	public float m_noiseDistance = 1.35f;

	public float m_noiseDistanceInterior = 0.2f;

	public float m_noiseDistanceYScale = 0.35f;

	public float m_noiseSpeed = 0.4f;

	public float m_characterVelocityFactor = 3f;

	public float m_rotationSpeed = 8f;

	public int m_coverRayMask;

	public GameObject m_ballInstance;

	public Vector3 m_ballVel;

	private float m_tombRefresh;

	private Vector3? m_lastTomb;

	public override void Setup(Character character)
	{
		((StatusEffect)this).Setup(character);
		if (m_coverRayMask == 0)
		{
			m_coverRayMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });
		}
	}

	internal static void AddCustomStatusEffect(ObjectDB odb)
	{
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		if (odb.m_StatusEffects.Count == 0)
		{
			return;
		}
		StatusEffect? obj = odb.m_StatusEffects.Find((StatusEffect effect) => Object.op_Implicit((Object)(object)effect) && ((Object)effect).name == "Demister");
		SE_Demister val = (SE_Demister)(object)((obj is SE_Demister) ? obj : null);
		if (!Object.op_Implicit((Object)(object)val) || odb.m_StatusEffects.Any((StatusEffect effect) => Object.op_Implicit((Object)(object)effect) && ((Object)effect).name == "FireflyOfTheDeath"))
		{
			return;
		}
		SE_FireflyOfDeath sE_FireflyOfDeath = ScriptableObject.CreateInstance<SE_FireflyOfDeath>();
		((Object)sE_FireflyOfDeath).name = "FireflyOfTheDeath";
		SetPrivateField(sE_FireflyOfDeath, "m_nameHash", StatusEffectHash);
		((StatusEffect)sE_FireflyOfDeath).m_name = "Firefly of the Death";
		((StatusEffect)sE_FireflyOfDeath).m_tooltip = "Release a firefly that guides you toward your last remaining tomb.";
		ItemDrop val2 = (Object.op_Implicit((Object)(object)Plugin.ItemPrefab) ? Plugin.ItemPrefab.GetComponent<ItemDrop>() : null);
		if ((Object)(object)val2 != (Object)null && val2.m_itemData != null && val2.m_itemData.m_shared.m_icons != null && val2.m_itemData.m_shared.m_icons.Length != 0)
		{
			((StatusEffect)sE_FireflyOfDeath).m_icon = val2.m_itemData.m_shared.m_icons[0];
		}
		((StatusEffect)sE_FireflyOfDeath).m_ttl = Plugin.StatusEffectDuration.Value;
		((StatusEffect)sE_FireflyOfDeath).m_startMessageType = (MessageType)1;
		if (!Object.op_Implicit((Object)(object)Plugin.BallPrefab))
		{
			CloneBallPrefab(val.m_ballPrefab);
		}
		if (Object.op_Implicit((Object)(object)Plugin.BallPrefab))
		{
			sE_FireflyOfDeath.m_ballPrefab = Plugin.BallPrefab;
			if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !PrivateValheimDictionary.ContainsKey(ZNetScene.instance, "m_namedPrefabs", BallPrefabHash))
			{
				ZNetScene.instance.m_prefabs.Add(Plugin.BallPrefab);
				PrivateValheimDictionary.Add(ZNetScene.instance, "m_namedPrefabs", BallPrefabHash, Plugin.BallPrefab);
			}
		}
		odb.m_StatusEffects.Add((StatusEffect)(object)sE_FireflyOfDeath);
	}

	private static void CloneBallPrefab(GameObject demisterBall)
	{
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: 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_0102: Expected O, but got Unknown
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Expected O, but got Unknown
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Expected O, but got Unknown
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c7: Expected O, but got Unknown
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0400: Unknown result type (might be due to invalid IL or missing references)
		//IL_0404: Unknown result type (might be due to invalid IL or missing references)
		//IL_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Unknown result type (might be due to invalid IL or missing references)
		//IL_041e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)demisterBall))
		{
			return;
		}
		Plugin.BallPrefab = Plugin.InitPrefabClone(demisterBall, "firefly_death_ball");
		Transform val = Plugin.BallPrefab.transform.Find("effects/Particle System Force Field");
		if (Object.op_Implicit((Object)(object)val))
		{
			Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
		}
		Component component = Plugin.BallPrefab.GetComponent("Jewelcrafting.GemEffects.Wisplight/SetForceField");
		if (Object.op_Implicit((Object)(object)component))
		{
			Object.DestroyImmediate((Object)(object)component);
		}
		Transform val2 = Plugin.BallPrefab.transform.Find("demister_ball");
		if (Object.op_Implicit((Object)(object)val2))
		{
			if (Plugin.ShowLightSource.Value)
			{
				((Object)val2).name = "firefly_death_ball_visual";
				val2.localScale = Vector3.one * 0.03f;
				MeshRenderer component2 = ((Component)val2).GetComponent<MeshRenderer>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					((Renderer)component2).sharedMaterial = new Material(((Renderer)component2).sharedMaterial)
					{
						name = "firefly_death_ball"
					};
					((Renderer)component2).sharedMaterial.SetColor("_EmissionColor", Plugin.LightColor.Value);
				}
			}
			else
			{
				Object.DestroyImmediate((Object)(object)((Component)val2).gameObject);
			}
		}
		Transform val3 = Plugin.BallPrefab.transform.Find("effects/Point light");
		if (Object.op_Implicit((Object)(object)val3))
		{
			Light component3 = ((Component)val3).GetComponent<Light>();
			component3.intensity = Plugin.LightIntensityOutdoors.Value;
			component3.color = Plugin.LightColor.Value;
			component3.range = Plugin.LightRangeOutdoors.Value;
			component3.shadowStrength = Plugin.LightShadowsOutdoors.Value;
			component3.shadows = (LightShadows)((component3.shadowStrength > 0f) ? 2 : 0);
		}
		Light[] componentsInChildren = Plugin.BallPrefab.GetComponentsInChildren<Light>(true);
		foreach (Light val4 in componentsInChildren)
		{
			val4.color = Plugin.LightColor.Value;
		}
		ParticleSystemRenderer[] componentsInChildren2 = Plugin.BallPrefab.GetComponentsInChildren<ParticleSystemRenderer>(true);
		foreach (ParticleSystemRenderer val5 in componentsInChildren2)
		{
			if (Object.op_Implicit((Object)(object)((Renderer)val5).sharedMaterial))
			{
				((Renderer)val5).sharedMaterial = new Material(((Renderer)val5).sharedMaterial);
				if (((Renderer)val5).sharedMaterial.HasProperty("_EmissionColor"))
				{
					((Renderer)val5).sharedMaterial.SetColor("_EmissionColor", Plugin.LightColor.Value);
				}
				if (((Renderer)val5).sharedMaterial.HasProperty("_Color"))
				{
					((Renderer)val5).sharedMaterial.SetColor("_Color", Plugin.LightColor.Value);
				}
			}
		}
		Transform val6 = Plugin.BallPrefab.transform.Find("effects/flame");
		if (!Object.op_Implicit((Object)(object)val6))
		{
			return;
		}
		for (int num = val6.childCount - 1; num >= 0; num--)
		{
			Transform child = val6.GetChild(num);
			if (((Object)child).name == "sparcs_front")
			{
				ParticleSystemRenderer component4 = ((Component)child).GetComponent<ParticleSystemRenderer>();
				((Renderer)component4).sharedMaterial = new Material(((Renderer)component4).sharedMaterial)
				{
					name = "firefly_death_sparcs"
				};
				((Renderer)component4).sharedMaterial.SetColor("_EmissionColor", Plugin.LightColor.Value);
			}
			else if (Plugin.ShowLightFlare.Value && ((Object)child).name == "flare")
			{
				child.localScale = Vector3.one * 0.5f;
				ParticleSystemRenderer component5 = ((Component)child).GetComponent<ParticleSystemRenderer>();
				((Renderer)component5).sharedMaterial = new Material(((Renderer)component5).sharedMaterial)
				{
					name = "firefly_death_flare"
				};
				((Renderer)component5).sharedMaterial.SetColor("_Color", Plugin.LightColor.Value);
				ParticleSystem component6 = ((Component)child).GetComponent<ParticleSystem>();
				MainModule main = component6.main;
				Color value = Plugin.LightColor.Value;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(value.r, value.g, value.b, 0.04f));
			}
			else
			{
				Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
			}
		}
	}

	private bool IsUnderRoof()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		RaycastHit val = default(RaycastHit);
		return Physics.Raycast(base.m_character.GetCenterPoint(), Vector3.up, ref val, 4f, m_coverRayMask);
	}

	public override void UpdateStatusEffect(float dt)
	{
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: 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)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_032c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_0336: Unknown result type (might be due to invalid IL or missing references)
		//IL_0338: Unknown result type (might be due to invalid IL or missing references)
		//IL_033a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Unknown result type (might be due to invalid IL or missing references)
		//IL_0391: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_039d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03be: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_036d: Unknown result type (might be due to invalid IL or missing references)
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0370: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_0377: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0386: Unknown result type (might be due to invalid IL or missing references)
		//IL_038b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0390: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_043c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0447: Unknown result type (might be due to invalid IL or missing references)
		//IL_044c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0451: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_0463: Unknown result type (might be due to invalid IL or missing references)
		//IL_0469: Unknown result type (might be due to invalid IL or missing references)
		//IL_046e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0484: Unknown result type (might be due to invalid IL or missing references)
		//IL_0489: Unknown result type (might be due to invalid IL or missing references)
		//IL_048b: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0409: Unknown result type (might be due to invalid IL or missing references)
		//IL_0414: Unknown result type (might be due to invalid IL or missing references)
		//IL_041f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0425: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Unknown result type (might be due to invalid IL or missing references)
		//IL_042f: Unknown result type (might be due to invalid IL or missing references)
		((StatusEffect)this).UpdateStatusEffect(dt);
		if (!Object.op_Implicit((Object)(object)m_ballInstance))
		{
			Vector3 val = base.m_character.GetCenterPoint() + ((Component)base.m_character).transform.forward * 0.5f;
			m_ballInstance = Object.Instantiate<GameObject>(m_ballPrefab, val, Quaternion.identity);
			Light[] componentsInChildren = m_ballInstance.GetComponentsInChildren<Light>(true);
			foreach (Light val2 in componentsInChildren)
			{
				val2.color = Plugin.LightColor.Value;
				val2.intensity = Plugin.LightIntensityOutdoors.Value;
				val2.range = Plugin.LightRangeOutdoors.Value;
				val2.shadowStrength = Plugin.LightShadowsOutdoors.Value;
				val2.shadows = (LightShadows)((val2.shadowStrength > 0f) ? 2 : 0);
				((Behaviour)val2).enabled = true;
			}
			m_lightFlicker = m_ballInstance.GetComponentInChildren<LightFlicker>(true);
			m_light = m_ballInstance.GetComponentInChildren<Light>(true);
			m_lightLod = m_ballInstance.GetComponentInChildren<LightLod>(true);
			if (Object.op_Implicit((Object)(object)m_light))
			{
				m_light.color = Plugin.LightColor.Value;
				((Behaviour)m_light).enabled = true;
			}
			if (Object.op_Implicit((Object)(object)m_light) && Object.op_Implicit((Object)(object)m_lightFlicker) && Object.op_Implicit((Object)(object)m_lightLod))
			{
				ApplyLight(base.m_character.InInterior());
			}
		}
		bool flag = IsUnderRoof();
		Vector3 position = ((Component)base.m_character).transform.position;
		Vector3 val3 = m_ballInstance.transform.position;
		Vector3 val4 = (flag ? m_offsetInterior : m_offset);
		float num = (flag ? m_noiseDistanceInterior : m_noiseDistance);
		Vector3 val5 = position + ((Component)base.m_character).transform.TransformVector(val4);
		m_tombRefresh -= dt;
		if (m_tombRefresh <= 0f)
		{
			m_tombRefresh = 1f;
			ref Vector3? lastTomb = ref m_lastTomb;
			Character character = base.m_character;
			lastTomb = TombLocator.FindLastRemainingTomb((Player)(object)((character is Player) ? character : null));
		}
		if (m_lastTomb.HasValue)
		{
			Vector3 val6 = m_lastTomb.Value - position;
			val6.y = 0f;
			if (((Vector3)(ref val6)).sqrMagnitude > 0.001f)
			{
				Vector3 normalized = ((Vector3)(ref val6)).normalized;
				val5 = position + normalized * 4f;
				val5.y = position.y + (flag ? m_offsetInterior.y : m_offset.y);
			}
		}
		float num2 = Time.time * m_noiseSpeed;
		val5 += new Vector3(Mathf.Sin(num2 * 4f), Mathf.Sin(num2 * 2f) * m_noiseDistanceYScale, Mathf.Cos(num2 * 5f)) * num;
		float num3 = Vector3.Distance(val5, val3);
		Vector3 val8;
		if (num3 > m_maxDistance * 2f)
		{
			val3 = val5;
		}
		else if (num3 > m_maxDistance)
		{
			Vector3 val7 = val5;
			val8 = val3 - val5;
			val3 = val7 + ((Vector3)(ref val8)).normalized * m_maxDistance;
		}
		val8 = val5 - val3;
		Vector3 normalized2 = ((Vector3)(ref val8)).normalized;
		m_ballVel += normalized2 * m_ballAcceleration * dt;
		if (((Vector3)(ref m_ballVel)).magnitude > m_ballMaxSpeed)
		{
			m_ballVel = ((Vector3)(ref m_ballVel)).normalized * m_ballMaxSpeed;
		}
		if (!flag)
		{
			m_ballVel += base.m_character.GetVelocity() * m_characterVelocityFactor * dt;
		}
		m_ballVel -= m_ballVel * m_ballFriction;
		m_ballInstance.transform.position = val3 + m_ballVel * dt;
		Quaternion rotation = m_ballInstance.transform.rotation;
		rotation *= Quaternion.Euler(m_rotationSpeed, 0f, m_rotationSpeed * 0.5321f);
		m_ballInstance.transform.rotation = rotation;
		if (!Object.op_Implicit((Object)(object)m_light) || !Object.op_Implicit((Object)(object)m_lightFlicker) || !Object.op_Implicit((Object)(object)m_lightLod))
		{
			m_lightFlicker = m_ballInstance.GetComponentInChildren<LightFlicker>(true);
			m_light = m_ballInstance.GetComponentInChildren<Light>(true);
			m_lightLod = m_ballInstance.GetComponentInChildren<LightLod>(true);
		}
		if (Object.op_Implicit((Object)(object)m_light) && Object.op_Implicit((Object)(object)m_lightFlicker) && Object.op_Implicit((Object)(object)m_lightLod))
		{
			if (base.m_ttl != 0f && base.m_ttl - ((StatusEffect)this).GetDuration() <= base.m_ttl * 0.1f)
			{
				SetLightIntensity(0.4f + 0.6f * (base.m_ttl - ((StatusEffect)this).GetDuration()) / (base.m_ttl * 0.1f));
			}
			else if (base.m_character.InInterior() && !m_indoors)
			{
				m_indoors = true;
				ApplyLight(indoors: true);
			}
			else if (!base.m_character.InInterior() && m_indoors)
			{
				m_indoors = false;
				ApplyLight(indoors: false);
			}
		}
	}

	private void ApplyLight(bool indoors)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		m_light.color = Plugin.LightColor.Value;
		((Behaviour)m_light).enabled = true;
		SetLightIntensity(indoors ? Plugin.LightIntensityIndoors.Value : Plugin.LightIntensityOutdoors.Value);
		m_light.range = (indoors ? Plugin.LightRangeIndoors.Value : Plugin.LightRangeOutdoors.Value);
		m_light.shadowStrength = (indoors ? Plugin.LightShadowsIndoors.Value : Plugin.LightShadowsOutdoors.Value);
		SetPrivateField(m_lightLod, "m_lightDistance", 40f);
		SetPrivateField(m_lightLod, "m_baseRange", m_light.range);
		SetPrivateField(m_lightLod, "m_baseShadowStrength", m_light.shadowStrength);
		m_light.shadows = (LightShadows)((m_light.shadowStrength > 0f) ? 2 : 0);
	}

	private void SetLightIntensity(float value)
	{
		m_light.intensity = value;
		SetPrivateField(m_lightFlicker, "m_baseIntensity", value);
	}

	private void RemoveEffects()
	{
		if (Object.op_Implicit((Object)(object)m_ballInstance))
		{
			ZNetView component = m_ballInstance.GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				component.ClaimOwnership();
				component.Destroy();
			}
			else
			{
				Object.Destroy((Object)(object)m_ballInstance);
			}
			m_ballInstance = null;
		}
	}

	public override void Stop()
	{
		((StatusEffect)this).Stop();
		RemoveEffects();
	}

	public override void OnDestroy()
	{
		((StatusEffect)this).OnDestroy();
		RemoveEffects();
	}

	protected override void OnApplicationQuit()
	{
		((StatusEffect)this).OnApplicationQuit();
		m_ballInstance = null;
	}

	private static void SetPrivateField(object target, string fieldName, object value)
	{
		if (target != null)
		{
			Type type = target.GetType();
			FieldInfo fieldInfo = null;
			while (type != null && fieldInfo == null)
			{
				fieldInfo = type.GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				type = type.BaseType;
			}
			if (fieldInfo == null)
			{
				throw new MissingFieldException(target.GetType().FullName, fieldName);
			}
			fieldInfo.SetValue(target, value);
		}
	}
}
internal static class TombLocator
{
	internal static Vector3? FindLastRemainingTomb(Player player)
	{
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)player))
		{
			return null;
		}
		long playerID = player.GetPlayerID();
		TombStone[] array = Object.FindObjectsByType<TombStone>((FindObjectsInactive)0, (FindObjectsSortMode)0);
		TombStone val = null;
		uint num = 0u;
		TombStone[] array2 = array;
		foreach (TombStone val2 in array2)
		{
			if (!Object.op_Implicit((Object)(object)val2))
			{
				continue;
			}
			ZNetView component = ((Component)val2).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
			{
				continue;
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null && zDO.GetLong(ZDOVars.s_owner, 0L) == playerID)
			{
				ZDOID uid = zDO.m_uid;
				uint iD = ((ZDOID)(ref uid)).ID;
				if (!Object.op_Implicit((Object)(object)val) || iD > num)
				{
					val = val2;
					num = iD;
				}
			}
		}
		return Object.op_Implicit((Object)(object)val) ? new Vector3?(((Component)val).transform.position) : ((Vector3?)null);
	}
}