Decompiled source of LogicalReplicator v1.1.3

LogicalReplicator.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LogicalReplicator")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LogicalReplicator")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("24d3e958-fc8c-4f4b-a53c-41d760263c32")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LogicalReplicator;

public static class ReplicatorCore
{
	public static bool IsBurning = false;

	public static bool IsSynthesizing = false;

	public static float BurnTimeRemaining = 0f;

	public static float SynthTimeRemaining = 0f;

	public static ItemData ItemInSlot;

	private static string selectedBlueprint;

	private static float selectedBlueprintCost = 0f;

	private static int synthesizeAmount = 1;

	private static Coroutine burnRoutine;

	private static Coroutine synthRoutine;

	private static GameObject activeBurnSfx;

	private static GameObject activeSynthSfx;

	public static void ResetBurnSlot()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		ItemInSlot = null;
		if ((Object)(object)ReplicatorUI.ItemIconImage != (Object)null)
		{
			ReplicatorUI.ItemIconImage.sprite = null;
			((Graphic)ReplicatorUI.ItemIconImage).color = new Color(1f, 1f, 1f, 0f);
		}
		if ((Object)(object)ReplicatorUI.StatusText != (Object)null)
		{
			ReplicatorUI.StatusText.text = "Поместите предмет...";
		}
		ReplicatorUI.SetButtonState(ReplicatorUI.ActionButton, interactable: false, "Абсорбировать");
		if ((Object)(object)ReplicatorUI.ProgressBar != (Object)null)
		{
			ReplicatorUI.ProgressBar.value = 0f;
		}
		if ((Object)(object)ReplicatorUI.BurnSlotImage != (Object)null)
		{
			ReplicatorUI.RemoveTooltip(((Component)ReplicatorUI.BurnSlotImage).gameObject);
		}
	}

	public static void HandleClose()
	{
		if (!IsBurning && ItemInSlot != null)
		{
			((Humanoid)Player.m_localPlayer).GetInventory().AddItem(ItemInSlot);
			ResetBurnSlot();
		}
	}

	public static string GetPrefabName(ItemData itemData)
	{
		if (itemData == null)
		{
			return "";
		}
		if ((Object)(object)itemData.m_dropPrefab != (Object)null)
		{
			return ((Object)itemData.m_dropPrefab).name;
		}
		if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null)
		{
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				ItemDrop component = item.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null && component.m_itemData.m_shared.m_name == itemData.m_shared.m_name)
				{
					return ((Object)item).name;
				}
			}
		}
		return itemData.m_shared.m_name;
	}

	public static float GetBiomassValue(ItemData itemData)
	{
		if (itemData == null)
		{
			return 0f;
		}
		string prefabName = GetPrefabName(itemData);
		if (prefabName == "BiomassCube")
		{
			return 100f;
		}
		if (prefabName == "BiomassCrate")
		{
			return 1000f;
		}
		Recipe val = null;
		foreach (Recipe recipe in ObjectDB.instance.m_recipes)
		{
			if ((Object)(object)recipe.m_item != (Object)null && recipe.m_item.m_itemData.m_shared.m_name == itemData.m_shared.m_name)
			{
				val = recipe;
				break;
			}
		}
		if ((Object)(object)val != (Object)null && val.m_resources != null && val.m_resources.Length != 0)
		{
			float num = 0f;
			Requirement[] resources = val.m_resources;
			foreach (Requirement val2 in resources)
			{
				if ((Object)(object)val2.m_resItem != (Object)null)
				{
					num += val2.m_resItem.m_itemData.m_shared.m_weight * (float)(val2.m_amount + val2.m_amountPerLevel * Mathf.Max(0, itemData.m_quality - 1));
				}
			}
			if (num > 0f)
			{
				return num / (float)Mathf.Max(1, val.m_amount);
			}
		}
		return itemData.m_shared.m_weight;
	}

	public static void OnBurnClicked()
	{
		if (IsBurning)
		{
			if (burnRoutine != null)
			{
				((MonoBehaviour)ReplicatorPlugin.Instance).StopCoroutine(burnRoutine);
			}
			CleanupBurnVFX();
			IsBurning = false;
			if (ItemInSlot != null)
			{
				((Humanoid)Player.m_localPlayer).GetInventory().AddItem(ItemInSlot);
			}
			ResetBurnSlot();
		}
		else if (ItemInSlot != null)
		{
			ReplicatorUI.SetButtonState(ReplicatorUI.ActionButton, interactable: true, "[ ОТМЕНА ]");
			ReplicatorVFX.PlaySafeSound("sfx_smelter_add_ore", "sfx_build_hammer_metal");
			float num = GetBiomassValue(ItemInSlot) * (float)ItemInSlot.m_stack;
			float burnTime = Mathf.Max(1f, num);
			float gainedMass = num * ReplicatorPlugin.MassMultiplier.Value;
			string prefabName = GetPrefabName(ItemInSlot);
			if (prefabName == "BiomassCube" || prefabName == "BiomassCrate")
			{
				gainedMass = num;
				burnTime = 3f;
			}
			if (ReplicatorPlugin.InstantBurnEnabled.Value)
			{
				FinishBurn(prefabName, gainedMass);
			}
			else
			{
				burnRoutine = ((MonoBehaviour)ReplicatorPlugin.Instance).StartCoroutine(BurnRoutine(burnTime, prefabName, gainedMass));
			}
		}
	}

	private static void CleanupBurnVFX()
	{
		if ((Object)(object)activeBurnSfx != (Object)null)
		{
			Object.Destroy((Object)(object)activeBurnSfx);
		}
		if ((Object)(object)ReplicatorVFX.BurnLight != (Object)null)
		{
			((MonoBehaviour)ReplicatorPlugin.Instance).StartCoroutine(ReplicatorVFX.FadeLightOut(ReplicatorVFX.BurnLight, 1.5f));
		}
		activeBurnSfx = null;
		ReplicatorVFX.ResetBurnVisuals();
	}

	private static IEnumerator BurnRoutine(float burnTime, string prefabName, float gainedMass)
	{
		IsBurning = true;
		BurnTimeRemaining = burnTime;
		if ((Object)(object)ReplicatorUI.ProgressBar != (Object)null)
		{
			ReplicatorUI.ProgressBar.maxValue = burnTime;
		}
		activeBurnSfx = ReplicatorVFX.CreateLoopingSound(((Component)Player.m_localPlayer).transform, ReplicatorPlugin.BurnSoundVolume.Value, "smelter", "charcoal_kiln", "fire_pit");
		double lastWorldTime = ZNet.instance.GetTimeSeconds();
		while (BurnTimeRemaining > 0f)
		{
			double currentWorldTime = ZNet.instance.GetTimeSeconds();
			float delta = (float)(currentWorldTime - lastWorldTime);
			lastWorldTime = currentWorldTime;
			if (delta > 0f)
			{
				BurnTimeRemaining -= delta;
			}
			float progress = Mathf.Clamp01(1f - BurnTimeRemaining / burnTime);
			if ((Object)(object)activeBurnSfx != (Object)null)
			{
				AudioSource src = activeBurnSfx.GetComponent<AudioSource>();
				if ((Object)(object)src != (Object)null)
				{
					src.volume = ReplicatorPlugin.BurnSoundVolume.Value;
				}
			}
			if ((Object)(object)ReplicatorUI.StatusText != (Object)null)
			{
				ReplicatorUI.StatusText.text = $"Разборка: {Mathf.CeilToInt(Mathf.Max(0f, BurnTimeRemaining))} сек. ({Mathf.RoundToInt(progress * 100f)}%)";
			}
			if ((Object)(object)ReplicatorUI.ProgressBar != (Object)null)
			{
				ReplicatorUI.ProgressBar.value = burnTime - Mathf.Max(0f, BurnTimeRemaining);
			}
			if (ReplicatorPlugin.EnableBurnGlow.Value && (Object)(object)ReplicatorVFX.BurnLight != (Object)null)
			{
				ReplicatorVFX.BurnLight.intensity = Mathf.Clamp(progress * 5f, 0f, 1f) * ReplicatorVFX.BurnLightMax;
			}
			ReplicatorVFX.AnimateBurnModel(progress);
			yield return (object)new WaitForSeconds(0.1f);
		}
		FinishBurn(prefabName, gainedMass);
	}

	private static void FinishBurn(string prefabName, float gainedMass)
	{
		ReplicatorDB.LearnItem(prefabName);
		ReplicatorDB.StoredMass += gainedMass;
		ReplicatorVFX.PlaySafeSound("sfx_blob_alert", "sfx_mud_tick");
		ReplicatorVFX.PlaySafeEffect(((Component)Player.m_localPlayer).transform, false, "vfx_blood_hit", "vfx_blob_hit");
		((Character)Player.m_localPlayer).Message((MessageType)1, $"[Репликатор] Абсорбция завершена. +{gainedMass:F1} БМ", 0, (Sprite)null);
		ReplicatorUI.UpdateGrid();
		ReplicatorUI.UpdateEpm();
		CleanupBurnVFX();
		ResetBurnSlot();
		IsBurning = false;
	}

	public static void SelectBlueprint(string itemName, float costPerItem)
	{
		if (!IsSynthesizing)
		{
			selectedBlueprint = itemName;
			selectedBlueprintCost = costPerItem;
			synthesizeAmount = 1;
			ReplicatorVFX.PlaySafeSound("sfx_gui_button");
			UpdateSynthesisUI();
		}
	}

	public static void ChangeAmount(int delta)
	{
		if (!IsSynthesizing && !string.IsNullOrEmpty(selectedBlueprint))
		{
			int num = ((!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303)) ? 1 : 10);
			SetAmount(synthesizeAmount + delta * num);
		}
	}

	public static void SetAmount(int amount)
	{
		if (!IsSynthesizing && !string.IsNullOrEmpty(selectedBlueprint))
		{
			synthesizeAmount = Mathf.Clamp(amount, 1, 9999);
			ReplicatorVFX.PlaySafeSound("sfx_gui_button");
			UpdateSynthesisUI();
		}
	}

	private static void UpdateSynthesisUI()
	{
		if (string.IsNullOrEmpty(selectedBlueprint))
		{
			return;
		}
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(selectedBlueprint);
		if (!((Object)(object)itemPrefab == (Object)null))
		{
			float num = selectedBlueprintCost * (float)synthesizeAmount;
			if ((Object)(object)ReplicatorUI.SelectedNameText != (Object)null)
			{
				ReplicatorUI.SelectedNameText.text = $"{Localization.instance.Localize(itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name)} ({num:F1} БМ)";
			}
			float num2 = ((selectedBlueprint == "BiomassCube" || selectedBlueprint == "BiomassCrate") ? 3f : num);
			if ((Object)(object)ReplicatorUI.SynthesisTimerText != (Object)null)
			{
				ReplicatorUI.SynthesisTimerText.text = $"Время: {Mathf.CeilToInt(Mathf.Max(1f, num2))} сек";
			}
			if ((Object)(object)ReplicatorUI.amountInputField != (Object)null && !ReplicatorUI.amountInputField.isFocused)
			{
				ReplicatorUI.amountInputField.text = synthesizeAmount.ToString();
			}
			else if ((Object)(object)ReplicatorUI.AmountText != (Object)null && (Object)(object)ReplicatorUI.amountInputField == (Object)null)
			{
				ReplicatorUI.AmountText.text = synthesizeAmount.ToString();
			}
			if (!IsSynthesizing)
			{
				ReplicatorUI.SetButtonState(ReplicatorUI.SynthesizeButton, ReplicatorDB.StoredMass >= num, "Синтезировать");
			}
		}
	}

	public static void OnSynthesizeClicked()
	{
		if (IsSynthesizing)
		{
			if (synthRoutine != null)
			{
				((MonoBehaviour)ReplicatorPlugin.Instance).StopCoroutine(synthRoutine);
			}
			CleanupSynthVFX();
			IsSynthesizing = false;
			UpdateSynthesisUI();
		}
		else
		{
			if (string.IsNullOrEmpty(selectedBlueprint))
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(selectedBlueprint);
			float num = selectedBlueprintCost * (float)synthesizeAmount;
			if (!((Object)(object)itemPrefab == (Object)null) && !(ReplicatorDB.StoredMass < num))
			{
				ReplicatorUI.SetButtonState(ReplicatorUI.SynthesizeButton, interactable: true, "[ ОТМЕНА ]");
				ReplicatorVFX.PlaySafeSound("sfx_forge_use", "sfx_chest_open");
				float time = Mathf.Max(1f, num);
				if (selectedBlueprint == "BiomassCube" || selectedBlueprint == "BiomassCrate")
				{
					time = 3f;
				}
				if (ReplicatorPlugin.InstantBurnEnabled.Value)
				{
					FinishSynthesis(itemPrefab, num, synthesizeAmount);
				}
				else
				{
					synthRoutine = ((MonoBehaviour)ReplicatorPlugin.Instance).StartCoroutine(SynthRoutine(time, num, itemPrefab, synthesizeAmount));
				}
			}
		}
	}

	private static void CleanupSynthVFX()
	{
		if ((Object)(object)activeSynthSfx != (Object)null)
		{
			Object.Destroy((Object)(object)activeSynthSfx);
		}
		if ((Object)(object)ReplicatorVFX.SynthLight != (Object)null)
		{
			((MonoBehaviour)ReplicatorPlugin.Instance).StartCoroutine(ReplicatorVFX.FadeLightOut(ReplicatorVFX.SynthLight, 1.5f));
		}
		ReplicatorVFX.ResetSynthVisuals();
	}

	public static void TriggerOverloadBurst()
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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_00a0: Expected O, but got Unknown
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		Animator componentInChildren = ((Component)Player.m_localPlayer).GetComponentInChildren<Animator>();
		Transform val = ((componentInChildren != null) ? componentInChildren.GetBoneTransform((HumanBodyBones)8) : null) ?? ((Component)Player.m_localPlayer).transform;
		Vector3 val2 = val.position + val.forward * 0.5f;
		ReplicatorVFX.PlaySafeEffectAt(val2, "vfx_sledge_lightning_hit", "vfx_HitSparks", "vfx_lightning");
		ReplicatorVFX.PlaySafeSound("sfx_lightning_hit", "sfx_sledge_hit");
		HitData val3 = new HitData();
		val3.m_damage.m_lightning = 0.1f;
		val3.m_point = val2;
		((Character)Player.m_localPlayer).ApplyDamage(val3, true, false, (DamageModifier)0);
		Collider[] array = Physics.OverlapSphere(val2, 4f);
		Collider[] array2 = array;
		foreach (Collider val4 in array2)
		{
			Character componentInParent = ((Component)val4).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)Player.m_localPlayer)
			{
				componentInParent.ApplyDamage(val3, true, false, (DamageModifier)0);
			}
		}
	}

	private static IEnumerator SynthRoutine(float time, float totalCost, GameObject prefab, int amount)
	{
		IsSynthesizing = true;
		SynthTimeRemaining = time;
		bool isOverloaded = totalCost >= 500f;
		activeSynthSfx = ReplicatorVFX.CreateLoopingSound(((Component)Player.m_localPlayer).transform, ReplicatorPlugin.SynthSoundVolume.Value, "piece_spinningwheel", "portal_wood", "forge");
		double lastWorldTime = ZNet.instance.GetTimeSeconds();
		while (SynthTimeRemaining > 0f)
		{
			double currentWorldTime = ZNet.instance.GetTimeSeconds();
			float delta = (float)(currentWorldTime - lastWorldTime);
			lastWorldTime = currentWorldTime;
			if (delta > 0f)
			{
				SynthTimeRemaining -= delta;
			}
			float progress = Mathf.Clamp01(1f - SynthTimeRemaining / time);
			float glowProgress = Mathf.Clamp01(progress * 2f);
			if ((Object)(object)activeSynthSfx != (Object)null)
			{
				AudioSource src = activeSynthSfx.GetComponent<AudioSource>();
				if ((Object)(object)src != (Object)null)
				{
					src.volume = ReplicatorPlugin.SynthSoundVolume.Value;
				}
			}
			if ((Object)(object)ReplicatorUI.SynthesisTimerText != (Object)null)
			{
				ReplicatorUI.SynthesisTimerText.text = $"Синтез... {Mathf.CeilToInt(Mathf.Max(0f, SynthTimeRemaining))} сек ({Mathf.RoundToInt(progress * 100f)}%)";
			}
			if (ReplicatorPlugin.EnableSynthGlow.Value && (Object)(object)ReplicatorVFX.SynthLight != (Object)null)
			{
				float maxIntensity = (isOverloaded ? (ReplicatorVFX.SynthLightMax * 2f) : ReplicatorVFX.SynthLightMax);
				ReplicatorVFX.SynthLight.intensity = Mathf.Lerp(0f, maxIntensity, glowProgress);
			}
			ReplicatorVFX.AnimateSynthModel(glowProgress);
			if (isOverloaded && progress > 0.8f && Random.value < 0.1f)
			{
				TriggerOverloadBurst();
			}
			yield return (object)new WaitForSeconds(0.1f);
		}
		FinishSynthesis(prefab, totalCost, amount);
	}

	private static void FinishSynthesis(GameObject prefab, float totalCost, int amount)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		ReplicatorDB.StoredMass -= totalCost;
		ReplicatorUI.UpdateEpm();
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			Transform transform = ((Component)Player.m_localPlayer).transform;
			Vector3 val = transform.position + Vector3.up * 1.5f + transform.forward * 0.5f;
			int num = amount;
			int maxStackSize = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize;
			while (num > 0)
			{
				int num2 = Mathf.Min(num, maxStackSize);
				GameObject val2 = Object.Instantiate<GameObject>(prefab, val, Quaternion.identity);
				val2.GetComponent<ItemDrop>().m_itemData.m_stack = num2;
				Rigidbody component = val2.GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.AddForce(transform.forward * 4f + Vector3.up * 2f, (ForceMode)2);
				}
				num -= num2;
			}
			ReplicatorVFX.PlaySafeSound("sfx_lootspawn", "sfx_chest_close");
			ReplicatorVFX.PlaySafeEffect(transform, false, "vfx_lootspawn", "vfx_sledge_iron_hit");
			((Character)Player.m_localPlayer).Message((MessageType)2, $"[Репликатор] Синтезировано: x{amount}!", 0, (Sprite)null);
		}
		CleanupSynthVFX();
		IsSynthesizing = false;
		UpdateSynthesisUI();
	}

	public static void OnSleepTimeSkipped(float realSecondsSkipped)
	{
		if (!(realSecondsSkipped <= 0f))
		{
			if (IsBurning && BurnTimeRemaining > 0f)
			{
				BurnTimeRemaining -= realSecondsSkipped;
				ReplicatorPlugin.ModLogger.LogInfo((object)$"[Репликатор] Пропущено {realSecondsSkipped:F1} сек. абсорбции из-за сна.");
			}
			if (IsSynthesizing && SynthTimeRemaining > 0f)
			{
				SynthTimeRemaining -= realSecondsSkipped;
				ReplicatorPlugin.ModLogger.LogInfo((object)$"[Репликатор] Пропущено {realSecondsSkipped:F1} сек. синтеза из-за сна.");
			}
		}
	}
}
public static class ReplicatorDB
{
	private const string KeyItems = "LearnedReplications";

	private const string KeyMass = "ReplicatorMass";

	public static float StoredMass
	{
		get
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.m_customData.TryGetValue("ReplicatorMass", out var value) && float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return 0f;
		}
		set
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				Player.m_localPlayer.m_customData["ReplicatorMass"] = value.ToString(CultureInfo.InvariantCulture);
			}
		}
	}

	public static void LearnItem(string prefabName)
	{
		if (!((Object)(object)Player.m_localPlayer == (Object)null) && !string.IsNullOrEmpty(prefabName))
		{
			List<string> learnedItems = GetLearnedItems();
			if (!learnedItems.Contains(prefabName))
			{
				learnedItems.Add(prefabName);
				Player.m_localPlayer.m_customData["LearnedReplications"] = string.Join(",", learnedItems);
			}
		}
	}

	public static List<string> GetLearnedItems()
	{
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return new List<string>();
		}
		if (Player.m_localPlayer.m_customData.TryGetValue("LearnedReplications", out var value) && !string.IsNullOrEmpty(value))
		{
			return new List<string>(value.Split(new char[1] { ',' }));
		}
		return new List<string>();
	}
}
[HarmonyPatch(typeof(Player), "TakeInput")]
public static class PlayerTakeInputPatch
{
	public static void Postfix(ref bool __result)
	{
		if (ReplicatorUI.IsOpen && ReplicatorUI.IsTyping())
		{
			__result = false;
		}
	}
}
[HarmonyPatch(typeof(InventoryGui), "Update")]
public static class InventoryGuiUpdatePatch
{
	public static bool Prefix()
	{
		if (ReplicatorUI.IsOpen && ReplicatorUI.IsTyping())
		{
			if (Input.GetKeyDown((KeyCode)27))
			{
				EventSystem.current.SetSelectedGameObject((GameObject)null);
				return false;
			}
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(InventoryGui), "ShowSplitDialog")]
public static class InventorySplitPanelZOrderPatch
{
	public static void Postfix(InventoryGui __instance)
	{
		if ((Object)(object)__instance.m_splitPanel != (Object)null)
		{
			Canvas val = ((Component)__instance.m_splitPanel).GetComponent<Canvas>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)__instance.m_splitPanel).gameObject.AddComponent<Canvas>();
				((Component)__instance.m_splitPanel).gameObject.AddComponent<GraphicRaycaster>();
			}
			val.overrideSorting = true;
			val.sortingOrder = 1005;
		}
	}
}
[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
public static class InventoryQuickTransferPatch
{
	public static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		if (ReplicatorUI.IsOpen && item != null && Input.GetKey((KeyCode)306) && ReplicatorCore.ItemInSlot == null)
		{
			ReplicatorCore.ItemInSlot = item.Clone();
			((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(item);
			ReplicatorUI.ItemIconImage.sprite = ReplicatorCore.ItemInSlot.m_shared.m_icons[0];
			((Graphic)ReplicatorUI.ItemIconImage).color = Color.white;
			ReplicatorUI.SetButtonState(ReplicatorUI.ActionButton, interactable: true, "Абсорбировать");
			string prefabName = ReplicatorCore.GetPrefabName(ReplicatorCore.ItemInSlot);
			float num = ReplicatorCore.GetBiomassValue(ReplicatorCore.ItemInSlot) * (float)ReplicatorCore.ItemInSlot.m_stack;
			float num2 = num * ReplicatorPlugin.MassMultiplier.Value;
			if (prefabName == "BiomassCube" || prefabName == "BiomassCrate")
			{
				num2 = num;
			}
			ReplicatorUI.StatusText.text = $"Выход: {num2:F1} БМ (x{ReplicatorCore.ItemInSlot.m_stack})";
			if ((Object)(object)ReplicatorUI.BurnSlotImage != (Object)null)
			{
				ReplicatorUI.ApplyTooltip(((Component)ReplicatorUI.BurnSlotImage).gameObject, Localization.instance.Localize(ReplicatorCore.ItemInSlot.m_shared.m_name), ReplicatorCore.ItemInSlot.GetTooltip(-1));
			}
			ReplicatorVFX.PlaySafeSound("sfx_gui_button");
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Player), "OnSpawned")]
public static class PlayerVisualAttachmentPatch
{
	public static void Postfix(Player __instance)
	{
		if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
		{
			ReplicatorVFX.AttachModelToPlayer(__instance);
		}
	}
}
[HarmonyPatch(typeof(ZNetScene), "Awake")]
public static class ZNetSceneRegistrationPatch
{
	public static void Postfix(ZNetScene __instance)
	{
		ReplicatorShared.RegisterToZNetScene(__instance);
	}
}
[HarmonyPatch(typeof(ObjectDB), "Awake")]
public static class ObjectDBRegistrationPatchAwake
{
	public static void Postfix(ObjectDB __instance)
	{
		ReplicatorShared.RegisterToObjectDB(__instance);
	}
}
[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
public static class ObjectDBRegistrationPatchCopy
{
	public static void Postfix(ObjectDB __instance)
	{
		ReplicatorShared.RegisterToObjectDB(__instance);
	}
}
[HarmonyPatch(typeof(Inventory), "GetTotalWeight")]
public static class InventoryWeightPatch
{
	public static void Postfix(Inventory __instance, ref float __result)
	{
		if ((Object)(object)Player.m_localPlayer != (Object)null && __instance == ((Humanoid)Player.m_localPlayer).GetInventory())
		{
			__result += ReplicatorDB.StoredMass / 10f;
		}
	}
}
[HarmonyPatch(typeof(EnvMan), "FixedUpdate")]
public static class EnvManTimeJumpPatch
{
	private static double lastGameTime = -1.0;

	public static void Postfix(EnvMan __instance)
	{
		if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		double timeSeconds = ZNet.instance.GetTimeSeconds();
		if (lastGameTime > 0.0)
		{
			double num = timeSeconds - lastGameTime;
			if (num > 300.0)
			{
				float num2 = ((__instance.m_dayLengthSec > 0) ? ((float)__instance.m_dayLengthSec) : 1800f);
				float realSecondsSkipped = (float)num * (num2 / 86400f);
				ReplicatorCore.OnSleepTimeSkipped(realSecondsSkipped);
			}
		}
		lastGameTime = timeSeconds;
	}
}
[BepInPlugin("com.sellivira.logicalreplicator", "Logical Replicator", "1.1.3")]
public class ReplicatorPlugin : BaseUnityPlugin
{
	public const string ModGUID = "com.sellivira.logicalreplicator";

	public const string ModName = "Logical Replicator";

	public const string ModVersion = "1.1.3";

	private readonly Harmony harmony = new Harmony("com.sellivira.logicalreplicator");

	public static ManualLogSource ModLogger;

	public static ReplicatorPlugin Instance;

	public static ConfigEntry<bool> InstantBurnEnabled;

	public static ConfigEntry<KeyboardShortcut> ToggleUiKey;

	public static ConfigEntry<float> MassMultiplier;

	public static ConfigEntry<bool> EnableBurnGlow;

	public static ConfigEntry<bool> EnableSynthGlow;

	public static ConfigEntry<float> SynthSoundVolume;

	public static ConfigEntry<float> BurnSoundVolume;

	public static ConfigEntry<Vector2> UiPosition;

	public static ConfigEntry<bool> IsUiLocked;

	private void Awake()
	{
		//IL_004c: 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_0098: Expected O, but got Unknown
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Expected O, but got Unknown
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Expected O, but got Unknown
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		ModLogger = ((BaseUnityPlugin)this).Logger;
		InstantBurnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. Разработка", "Мгновенное сжигание", false, "Отключает таймеры.");
		ToggleUiKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("2. Управление", "Хоткей интерфейса", new KeyboardShortcut((KeyCode)278, Array.Empty<KeyCode>()), "Кнопка открытия окна репликатора.");
		MassMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("3. Баланс", "Множитель массы", 2f, new ConfigDescription("Дюп-фактор: 1.0 = честно.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
		EnableBurnGlow = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Эффекты", "Свечение при абсорбции", true, "Включает бордовый источник света.");
		EnableSynthGlow = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Эффекты", "Свечение при синтезе", true, "Включает циановый источник света.");
		SynthSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("4. Эффекты", "Громкость звука синтеза", 0.35f, new ConfigDescription("Громкость звука работы (0.0 - 1.0)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		BurnSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("4. Эффекты", "Громкость звука сжигания", 0.8f, new ConfigDescription("Громкость звука костра (0.0 - 1.0)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		UiPosition = ((BaseUnityPlugin)this).Config.Bind<Vector2>("5. Интерфейс", "Позиция окна", Vector2.zero, "Сохраненные координаты окна на экране.");
		IsUiLocked = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Интерфейс", "Закрепить окно", false, "Блокирует перетаскивание окна.");
		ReplicatorShared.LoadAssetBundle();
		harmony.PatchAll();
		ModLogger.LogInfo((object)"Плагин Logical Replicator v1.1.3 инициализирован.");
	}

	private void Update()
	{
		//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)
		if (!((Object)(object)Player.m_localPlayer == (Object)null))
		{
			if ((Object)(object)ReplicatorVFX.Instance == (Object)null && (Object)(object)ReplicatorShared.Prefab != (Object)null)
			{
				ReplicatorVFX.AttachModelToPlayer(Player.m_localPlayer);
			}
			bool flag = false;
			KeyboardShortcut value = ToggleUiKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && !Console.IsVisible() && !Chat.instance.HasFocus())
			{
				ReplicatorUI.Toggle();
				flag = true;
			}
			if (!flag && ReplicatorUI.IsOpen && (Object)(object)InventoryGui.instance != (Object)null && !InventoryGui.IsVisible())
			{
				ReplicatorUI.ForceClose();
			}
			ReplicatorUI.HandleInventoryClicks();
		}
	}
}
public static class ReplicatorShared
{
	public static GameObject Prefab;

	public static GameObject UiPrefab;

	public static GameObject BiomassCube;

	public static GameObject BiomassCrate;

	public static void LoadAssetBundle()
	{
		string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "replicator_assets");
		if (!File.Exists(text))
		{
			return;
		}
		AssetBundle val = AssetBundle.LoadFromFile(text);
		if (!((Object)(object)val != (Object)null))
		{
			return;
		}
		GameObject[] array = val.LoadAllAssets<GameObject>();
		foreach (GameObject val2 in array)
		{
			if ((Object)(object)val2.GetComponent<Canvas>() != (Object)null || ((Object)val2).name.Contains("UI"))
			{
				UiPrefab = val2;
			}
			else if (((Object)val2).name == "BiomassCube")
			{
				BiomassCube = val2;
			}
			else if (((Object)val2).name == "BiomassCrate")
			{
				BiomassCrate = val2;
			}
			else if ((Object)(object)val2.GetComponentInChildren<MeshRenderer>() != (Object)null || (Object)(object)val2.GetComponentInChildren<SkinnedMeshRenderer>() != (Object)null)
			{
				Prefab = val2;
			}
		}
		if ((Object)(object)Prefab == (Object)null)
		{
			Prefab = val.LoadAllAssets<GameObject>()[0];
		}
		InitializePrefab(BiomassCube);
		InitializePrefab(BiomassCrate);
		val.Unload(false);
	}

	private static void InitializePrefab(GameObject prefab)
	{
		if ((Object)(object)prefab == (Object)null)
		{
			return;
		}
		ItemDrop component = prefab.GetComponent<ItemDrop>();
		if ((Object)(object)component != (Object)null && component.m_itemData != null)
		{
			component.m_itemData.m_dropPrefab = prefab;
			if (((Object)prefab).name == "BiomassCube")
			{
				component.m_itemData.m_shared.m_name = "Логический-Биомассивный куб";
				component.m_itemData.m_shared.m_description = "Предмет, созданный Логическим Репликатором, отход весом 10 кг, но имеющий материальную ценность БМ 100.";
			}
			else if (((Object)prefab).name == "BiomassCrate")
			{
				component.m_itemData.m_shared.m_name = "Логический-Биомассивный ящик";
				component.m_itemData.m_shared.m_description = "Огромный спрессованный контейнер биомассы. Вес 100 кг, материальная ценность БМ 1000.";
			}
		}
		int num = LayerMask.NameToLayer("item");
		prefab.layer = ((num != -1) ? num : 12);
		if ((Object)(object)prefab.GetComponent<ZSyncTransform>() == (Object)null)
		{
			prefab.AddComponent<ZSyncTransform>();
		}
		if ((Object)(object)prefab.GetComponent<ZNetView>() == (Object)null)
		{
			prefab.AddComponent<ZNetView>();
		}
		if ((Object)(object)prefab.GetComponent<Rigidbody>() == (Object)null)
		{
			prefab.AddComponent<Rigidbody>();
		}
	}

	public static void RegisterToZNetScene(ZNetScene zns)
	{
		if (!((Object)(object)zns == (Object)null))
		{
			RegisterPrefabToZNetScene(zns, BiomassCube);
			RegisterPrefabToZNetScene(zns, BiomassCrate);
		}
	}

	public static void RegisterToObjectDB(ObjectDB odb)
	{
		if (!((Object)(object)odb == (Object)null))
		{
			RegisterItemToObjectDB(odb, BiomassCube);
			RegisterItemToObjectDB(odb, BiomassCrate);
		}
	}

	private static void RegisterPrefabToZNetScene(ZNetScene zns, GameObject prefab)
	{
		if (!((Object)(object)prefab == (Object)null))
		{
			if (!zns.m_prefabs.Contains(prefab))
			{
				zns.m_prefabs.Add(prefab);
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
			if (AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(zns) is Dictionary<int, GameObject> dictionary && !dictionary.ContainsKey(stableHashCode))
			{
				dictionary[stableHashCode] = prefab;
			}
		}
	}

	private static void RegisterItemToObjectDB(ObjectDB odb, GameObject prefab)
	{
		if (!((Object)(object)prefab == (Object)null))
		{
			if (!odb.m_items.Contains(prefab))
			{
				odb.m_items.Add(prefab);
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
			if (AccessTools.Field(typeof(ObjectDB), "m_itemByHash").GetValue(odb) is Dictionary<int, GameObject> dictionary && !dictionary.ContainsKey(stableHashCode))
			{
				dictionary[stableHashCode] = prefab;
			}
		}
	}
}
public class DraggableUI : MonoBehaviour, IDragHandler, IEventSystemHandler, IEndDragHandler
{
	public RectTransform target;

	public void OnDrag(PointerEventData eventData)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if (!ReplicatorPlugin.IsUiLocked.Value)
		{
			Canvas val = (((Object)(object)InventoryGui.instance != (Object)null) ? ((Component)InventoryGui.instance).GetComponentInParent<Canvas>() : null);
			float num = (((Object)(object)val != (Object)null) ? val.scaleFactor : 1f);
			RectTransform obj = target;
			obj.anchoredPosition += eventData.delta / num;
		}
	}

	public void OnEndDrag(PointerEventData eventData)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		if (!ReplicatorPlugin.IsUiLocked.Value)
		{
			ReplicatorPlugin.UiPosition.Value = target.anchoredPosition;
			((BaseUnityPlugin)ReplicatorPlugin.Instance).Config.Save();
		}
	}
}
public static class ReplicatorUI
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction<string> <>9__28_0;

		public static UnityAction <>9__28_1;

		public static UnityAction <>9__28_2;

		public static UnityAction <>9__28_3;

		public static UnityAction<string> <>9__28_4;

		internal void <SetupReferences>b__28_0(string val)
		{
			if (int.TryParse(val, out var result))
			{
				ReplicatorCore.SetAmount(result);
			}
			else
			{
				ReplicatorCore.SetAmount(1);
			}
		}

		internal void <SetupReferences>b__28_1()
		{
			ReplicatorPlugin.IsUiLocked.Value = !ReplicatorPlugin.IsUiLocked.Value;
			((BaseUnityPlugin)ReplicatorPlugin.Instance).Config.Save();
			UpdateLockButtonVisuals();
			ReplicatorVFX.PlaySafeSound("sfx_gui_button");
		}

		internal void <SetupReferences>b__28_2()
		{
			ReplicatorCore.ChangeAmount(1);
		}

		internal void <SetupReferences>b__28_3()
		{
			ReplicatorCore.ChangeAmount(-1);
		}

		internal void <SetupReferences>b__28_4(string q)
		{
			CurrentSearchQuery = q.ToLower();
			UpdateGrid();
		}
	}

	private static GameObject uiInstance;

	private static CanvasGroup uiCanvasGroup;

	public static Image BurnSlotImage;

	public static Image ItemIconImage;

	public static Button ActionButton;

	public static Text StatusText;

	public static Text EpmCounter;

	public static Slider ProgressBar;

	private static Transform gridContainer;

	private static GameObject itemTemplate;

	public static Button SynthesizeButton;

	public static Text SynthesisTimerText;

	public static Text SelectedNameText;

	public static Text AmountText;

	public static InputField searchBar;

	public static InputField amountInputField;

	public static string CurrentSearchQuery = "";

	private static GameObject vanillaTooltipPrefab;

	public static bool IsOpen { get; private set; } = false;

	private static GameObject GetVanillaTooltipPrefab()
	{
		if ((Object)(object)vanillaTooltipPrefab != (Object)null)
		{
			return vanillaTooltipPrefab;
		}
		if ((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_playerGrid != (Object)null)
		{
			GameObject elementPrefab = InventoryGui.instance.m_playerGrid.m_elementPrefab;
			if ((Object)(object)elementPrefab != (Object)null)
			{
				UITooltip component = elementPrefab.GetComponent<UITooltip>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.m_tooltipPrefab != (Object)null)
				{
					vanillaTooltipPrefab = component.m_tooltipPrefab;
					return vanillaTooltipPrefab;
				}
			}
		}
		return null;
	}

	public static void ApplyTooltip(GameObject target, string topic, string text)
	{
		if ((Object)(object)target == (Object)null)
		{
			return;
		}
		GameObject val = GetVanillaTooltipPrefab();
		if ((Object)(object)val == (Object)null)
		{
			UITooltip component = target.GetComponent<UITooltip>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			return;
		}
		UITooltip val2 = target.GetComponent<UITooltip>();
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = target.AddComponent<UITooltip>();
		}
		val2.m_tooltipPrefab = val;
		val2.m_topic = topic;
		val2.m_text = text;
	}

	public static void RemoveTooltip(GameObject target)
	{
		if (!((Object)(object)target == (Object)null))
		{
			UITooltip component = target.GetComponent<UITooltip>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
		}
	}

	public static bool IsTyping()
	{
		bool flag = (Object)(object)searchBar != (Object)null && searchBar.isFocused;
		bool flag2 = (Object)(object)amountInputField != (Object)null && amountInputField.isFocused;
		return flag || flag2;
	}

	public static void Toggle()
	{
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: 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)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ReplicatorShared.UiPrefab == (Object)null)
		{
			return;
		}
		if ((Object)(object)uiInstance == (Object)null)
		{
			if ((Object)(object)InventoryGui.instance == (Object)null)
			{
				return;
			}
			uiInstance = Object.Instantiate<GameObject>(ReplicatorShared.UiPrefab);
			uiInstance.SetActive(true);
			uiInstance.transform.SetParent(((Component)InventoryGui.instance).transform, false);
			GraphicRaycaster component = uiInstance.GetComponent<GraphicRaycaster>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			CanvasScaler component2 = uiInstance.GetComponent<CanvasScaler>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component2);
			}
			Canvas component3 = uiInstance.GetComponent<Canvas>();
			if ((Object)(object)component3 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component3);
			}
			RectTransform component4 = uiInstance.GetComponent<RectTransform>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.anchorMin = Vector2.zero;
				component4.anchorMax = Vector2.one;
				component4.offsetMin = Vector2.zero;
				component4.offsetMax = Vector2.zero;
				((Transform)component4).localScale = Vector3.one;
			}
			SetupReferences();
		}
		IsOpen = !IsOpen;
		if ((Object)(object)uiCanvasGroup != (Object)null)
		{
			uiCanvasGroup.alpha = (IsOpen ? 1f : 0f);
			uiCanvasGroup.blocksRaycasts = IsOpen;
			uiCanvasGroup.interactable = IsOpen;
		}
		if (IsOpen)
		{
			UpdateGrid();
			UpdateEpm();
			UpdateLockButtonVisuals();
			if ((Object)(object)InventoryGui.instance != (Object)null && !InventoryGui.IsVisible())
			{
				InventoryGui.instance.Show((Container)null, 1);
			}
			if ((Object)(object)uiInstance != (Object)null && (Object)(object)InventoryGui.instance != (Object)null)
			{
				if ((Object)(object)InventoryGui.instance.m_splitPanel != (Object)null)
				{
					uiInstance.transform.SetSiblingIndex(((Component)InventoryGui.instance.m_splitPanel).transform.GetSiblingIndex());
				}
				else
				{
					uiInstance.transform.SetAsLastSibling();
				}
			}
		}
		else
		{
			ReplicatorCore.HandleClose();
		}
	}

	public static void ForceClose()
	{
		if (IsOpen && !((Object)(object)uiCanvasGroup == (Object)null))
		{
			IsOpen = false;
			uiCanvasGroup.alpha = 0f;
			uiCanvasGroup.blocksRaycasts = false;
			uiCanvasGroup.interactable = false;
			ReplicatorCore.HandleClose();
		}
	}

	private static void SetupReferences()
	{
		//IL_00b3: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_045d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0467: Expected O, but got Unknown
		//IL_0429: Unknown result type (might be due to invalid IL or missing references)
		//IL_042e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0434: Expected O, but got Unknown
		//IL_048a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0494: Expected O, but got Unknown
		//IL_04af: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b9: Expected O, but got Unknown
		//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ec: Expected O, but got Unknown
		//IL_0519: Unknown result type (might be due to invalid IL or missing references)
		//IL_051e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0524: Expected O, but got Unknown
		uiCanvasGroup = uiInstance.GetComponent<CanvasGroup>();
		if ((Object)(object)uiCanvasGroup == (Object)null)
		{
			uiCanvasGroup = uiInstance.AddComponent<CanvasGroup>();
		}
		Transform val = uiInstance.transform.Find("MainPanel");
		if ((Object)(object)val == (Object)null)
		{
			val = ((uiInstance.transform.childCount > 0) ? uiInstance.transform.GetChild(0) : uiInstance.transform);
		}
		if ((Object)(object)((Component)val).GetComponent<DraggableUI>() == (Object)null)
		{
			DraggableUI draggableUI = ((Component)val).gameObject.AddComponent<DraggableUI>();
			draggableUI.target = (RectTransform)(object)((val is RectTransform) ? val : null);
			if (ReplicatorPlugin.UiPosition.Value != Vector2.zero)
			{
				draggableUI.target.anchoredPosition = ReplicatorPlugin.UiPosition.Value;
			}
		}
		Transform obj = FindChild(uiInstance.transform, "SlotBackground");
		BurnSlotImage = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
		Transform obj2 = FindChild(uiInstance.transform, "ItemIcon");
		ItemIconImage = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
		Transform obj3 = FindChild(uiInstance.transform, "ActionButton");
		ActionButton = ((obj3 != null) ? ((Component)obj3).GetComponent<Button>() : null);
		Transform obj4 = FindChild(uiInstance.transform, "StatusText");
		StatusText = ((obj4 != null) ? ((Component)obj4).GetComponent<Text>() : null);
		Transform obj5 = FindChild(uiInstance.transform, "EpmCounter");
		EpmCounter = ((obj5 != null) ? ((Component)obj5).GetComponent<Text>() : null);
		Transform obj6 = FindChild(uiInstance.transform, "ProgressBar");
		ProgressBar = ((obj6 != null) ? ((Component)obj6).GetComponent<Slider>() : null);
		gridContainer = FindChild(uiInstance.transform, "Content");
		Transform obj7 = FindChild(gridContainer, "ItemTemplate");
		itemTemplate = ((obj7 != null) ? ((Component)obj7).gameObject : null);
		if ((Object)(object)itemTemplate != (Object)null)
		{
			itemTemplate.SetActive(false);
		}
		Transform obj8 = FindChild(uiInstance.transform, "SynthesizeButton");
		SynthesizeButton = ((obj8 != null) ? ((Component)obj8).GetComponent<Button>() : null);
		Transform obj9 = FindChild(uiInstance.transform, "SynthesisTimerText");
		SynthesisTimerText = ((obj9 != null) ? ((Component)obj9).GetComponent<Text>() : null);
		Transform obj10 = FindChild(uiInstance.transform, "SelectedNameText");
		SelectedNameText = ((obj10 != null) ? ((Component)obj10).GetComponent<Text>() : null);
		Transform obj11 = FindChild(uiInstance.transform, "SearchBar");
		searchBar = ((obj11 != null) ? ((Component)obj11).GetComponent<InputField>() : null);
		Transform obj12 = FindChild(uiInstance.transform, "CloseButton");
		Button val2 = ((obj12 != null) ? ((Component)obj12).GetComponent<Button>() : null);
		Transform obj13 = FindChild(uiInstance.transform, "PlusButton");
		Button val3 = ((obj13 != null) ? ((Component)obj13).GetComponent<Button>() : null);
		Transform obj14 = FindChild(uiInstance.transform, "MinusButton");
		Button val4 = ((obj14 != null) ? ((Component)obj14).GetComponent<Button>() : null);
		Transform obj15 = FindChild(uiInstance.transform, "AmountText");
		AmountText = ((obj15 != null) ? ((Component)obj15).GetComponent<Text>() : null);
		if ((Object)(object)AmountText != (Object)null && (Object)(object)amountInputField == (Object)null)
		{
			((Graphic)AmountText).raycastTarget = true;
			amountInputField = ((Component)AmountText).gameObject.AddComponent<InputField>();
			amountInputField.textComponent = AmountText;
			amountInputField.contentType = (ContentType)2;
			amountInputField.characterLimit = 4;
			amountInputField.text = "1";
			((UnityEvent<string>)(object)amountInputField.onEndEdit).AddListener((UnityAction<string>)delegate(string s)
			{
				if (int.TryParse(s, out var result))
				{
					ReplicatorCore.SetAmount(result);
				}
				else
				{
					ReplicatorCore.SetAmount(1);
				}
			});
		}
		Transform obj16 = FindChild(uiInstance.transform, "LockButton");
		Button val5 = ((obj16 != null) ? ((Component)obj16).GetComponent<Button>() : null);
		if ((Object)(object)val5 != (Object)null)
		{
			ButtonClickedEvent onClick = val5.onClick;
			object obj17 = <>c.<>9__28_1;
			if (obj17 == null)
			{
				UnityAction val6 = delegate
				{
					ReplicatorPlugin.IsUiLocked.Value = !ReplicatorPlugin.IsUiLocked.Value;
					((BaseUnityPlugin)ReplicatorPlugin.Instance).Config.Save();
					UpdateLockButtonVisuals();
					ReplicatorVFX.PlaySafeSound("sfx_gui_button");
				};
				<>c.<>9__28_1 = val6;
				obj17 = (object)val6;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj17);
		}
		if ((Object)(object)ActionButton != (Object)null)
		{
			((UnityEvent)ActionButton.onClick).AddListener(new UnityAction(ReplicatorCore.OnBurnClicked));
		}
		if ((Object)(object)SynthesizeButton != (Object)null)
		{
			((UnityEvent)SynthesizeButton.onClick).AddListener(new UnityAction(ReplicatorCore.OnSynthesizeClicked));
		}
		if ((Object)(object)val2 != (Object)null)
		{
			((UnityEvent)val2.onClick).AddListener(new UnityAction(ForceClose));
		}
		if ((Object)(object)val3 != (Object)null)
		{
			ButtonClickedEvent onClick2 = val3.onClick;
			object obj18 = <>c.<>9__28_2;
			if (obj18 == null)
			{
				UnityAction val7 = delegate
				{
					ReplicatorCore.ChangeAmount(1);
				};
				<>c.<>9__28_2 = val7;
				obj18 = (object)val7;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj18);
		}
		if ((Object)(object)val4 != (Object)null)
		{
			ButtonClickedEvent onClick3 = val4.onClick;
			object obj19 = <>c.<>9__28_3;
			if (obj19 == null)
			{
				UnityAction val8 = delegate
				{
					ReplicatorCore.ChangeAmount(-1);
				};
				<>c.<>9__28_3 = val8;
				obj19 = (object)val8;
			}
			((UnityEvent)onClick3).AddListener((UnityAction)obj19);
		}
		if ((Object)(object)searchBar != (Object)null)
		{
			((UnityEvent<string>)(object)searchBar.onValueChanged).AddListener((UnityAction<string>)delegate(string q)
			{
				CurrentSearchQuery = q.ToLower();
				UpdateGrid();
			});
		}
	}

	public static void UpdateLockButtonVisuals()
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		Transform obj = FindChild(uiInstance.transform, "LockButton");
		Button val = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null);
		if ((Object)(object)val != (Object)null)
		{
			Text componentInChildren = ((Component)val).GetComponentInChildren<Text>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = (ReplicatorPlugin.IsUiLocked.Value ? "\ud83d\udd12 ЗАМОК" : "\ud83d\udd13 СВОБОДНО");
				((Graphic)componentInChildren).color = (ReplicatorPlugin.IsUiLocked.Value ? new Color(1f, 0.4f, 0.4f) : new Color(0.6f, 1f, 0.6f));
			}
		}
	}

	public static void SetButtonState(Button btn, bool interactable, string text)
	{
		if (!((Object)(object)btn == (Object)null))
		{
			((Selectable)btn).interactable = interactable;
			Text componentInChildren = ((Component)btn).GetComponentInChildren<Text>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = text;
			}
		}
	}

	public static void UpdateEpm()
	{
		if ((Object)(object)EpmCounter != (Object)null)
		{
			EpmCounter.text = $"Доступно материала: {ReplicatorDB.StoredMass:F1} БМ";
		}
	}

	public static void UpdateGrid()
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		if ((Object)(object)gridContainer == (Object)null || (Object)(object)itemTemplate == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		foreach (Transform item in gridContainer)
		{
			Transform val = item;
			if ((Object)(object)((Component)val).gameObject != (Object)(object)itemTemplate)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}
		List<string> learnedItems = ReplicatorDB.GetLearnedItems();
		if ((Object)(object)ReplicatorShared.BiomassCube != (Object)null)
		{
			GenerateGridIcon(((Object)ReplicatorShared.BiomassCube).name);
		}
		if ((Object)(object)ReplicatorShared.BiomassCrate != (Object)null)
		{
			GenerateGridIcon(((Object)ReplicatorShared.BiomassCrate).name);
		}
		foreach (string item2 in learnedItems)
		{
			if (!(item2 == "BiomassCube") && !(item2 == "BiomassCrate"))
			{
				GenerateGridIcon(item2);
			}
		}
	}

	private static void GenerateGridIcon(string itemName)
	{
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Expected O, but got Unknown
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemName);
		if ((Object)(object)itemPrefab == (Object)null)
		{
			return;
		}
		ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null)
		{
			return;
		}
		string text = Localization.instance.Localize(component.m_itemData.m_shared.m_name);
		if (string.IsNullOrEmpty(CurrentSearchQuery) || text.ToLower().Contains(CurrentSearchQuery))
		{
			GameObject val = Object.Instantiate<GameObject>(itemTemplate, gridContainer);
			val.SetActive(true);
			Transform obj = FindChild(val.transform, "Icon");
			Image val2 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			Transform obj2 = FindChild(val.transform, "WeightText");
			Text val3 = ((obj2 != null) ? ((Component)obj2).GetComponent<Text>() : null) ?? val.GetComponentInChildren<Text>();
			if ((Object)(object)val2 != (Object)null && component.m_itemData.m_shared.m_icons != null && component.m_itemData.m_shared.m_icons.Length != 0)
			{
				val2.sprite = component.m_itemData.m_shared.m_icons[0];
			}
			float cost = ReplicatorCore.GetBiomassValue(component.m_itemData);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.text = $"{cost:F1} БМ";
			}
			ApplyTooltip(val, text, component.m_itemData.GetTooltip(-1));
			((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ReplicatorCore.SelectBlueprint(itemName, cost);
			});
		}
	}

	public static void HandleInventoryClicks()
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		if (!IsOpen || ReplicatorCore.IsBurning || (Object)(object)BurnSlotImage == (Object)null || (Object)(object)InventoryGui.instance == (Object)null || !Input.GetMouseButtonDown(0) || !RectTransformUtility.RectangleContainsScreenPoint(((Graphic)BurnSlotImage).rectTransform, Vector2.op_Implicit(Input.mousePosition), (Camera)null))
		{
			return;
		}
		FieldInfo fieldInfo = AccessTools.Field(typeof(InventoryGui), "m_dragItem");
		object? obj = fieldInfo?.GetValue(InventoryGui.instance);
		ItemData val = (ItemData)((obj is ItemData) ? obj : null);
		if (val != null && ReplicatorCore.ItemInSlot == null)
		{
			ReplicatorCore.ItemInSlot = val.Clone();
			((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(val);
			ItemIconImage.sprite = ReplicatorCore.ItemInSlot.m_shared.m_icons[0];
			((Graphic)ItemIconImage).color = Color.white;
			SetButtonState(ActionButton, interactable: true, "Абсорбировать");
			string prefabName = ReplicatorCore.GetPrefabName(ReplicatorCore.ItemInSlot);
			float num = ReplicatorCore.GetBiomassValue(ReplicatorCore.ItemInSlot) * (float)ReplicatorCore.ItemInSlot.m_stack;
			float num2 = num * ReplicatorPlugin.MassMultiplier.Value;
			if (prefabName == "BiomassCube" || prefabName == "BiomassCrate")
			{
				num2 = num;
			}
			StatusText.text = $"Выход: {num2:F1} БМ (x{ReplicatorCore.ItemInSlot.m_stack})";
			ApplyTooltip(((Component)BurnSlotImage).gameObject, Localization.instance.Localize(ReplicatorCore.ItemInSlot.m_shared.m_name), ReplicatorCore.ItemInSlot.GetTooltip(-1));
			fieldInfo.SetValue(InventoryGui.instance, null);
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(InventoryGui), "m_dragGo");
			object? obj2 = fieldInfo2?.GetValue(InventoryGui.instance);
			GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Object.Destroy((Object)(object)val2);
			}
			fieldInfo2?.SetValue(InventoryGui.instance, null);
			ReplicatorVFX.PlaySafeSound("sfx_gui_button");
		}
		else if (val == null && ReplicatorCore.ItemInSlot != null)
		{
			((Humanoid)Player.m_localPlayer).GetInventory().AddItem(ReplicatorCore.ItemInSlot);
			ReplicatorCore.ResetBurnSlot();
			ReplicatorVFX.PlaySafeSound("sfx_gui_button");
		}
	}

	private static Transform FindChild(Transform parent, string name)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected O, but got Unknown
		foreach (Transform item in parent)
		{
			Transform val = item;
			if (((Object)val).name.Equals(name, StringComparison.OrdinalIgnoreCase))
			{
				return val;
			}
			Transform val2 = FindChild(val, name);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return null;
	}
}
public static class ReplicatorVFX
{
	public static GameObject Instance;

	public static Light SynthLight;

	public static Light BurnLight;

	public static float SynthLightMax = 2.5f;

	public static float BurnLightMax = 3f;

	private static List<Material> coreMaterials = new List<Material>();

	private static List<Material> shellMaterials = new List<Material>();

	private static List<Material> crystalMaterials = new List<Material>();

	private static List<Color> originalCoreColors = new List<Color>();

	private static List<Color> originalShellColors = new List<Color>();

	private static List<Color> originalCrystalColors = new List<Color>();

	public static void AttachModelToPlayer(Player player)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0316: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02de: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ReplicatorShared.Prefab == (Object)null)
		{
			return;
		}
		Animator componentInChildren = ((Component)player).GetComponentInChildren<Animator>();
		Transform val = ((componentInChildren != null) ? componentInChildren.GetBoneTransform((HumanBodyBones)8) : null) ?? ((Component)player).transform;
		Instance = Object.Instantiate<GameObject>(ReplicatorShared.Prefab, val, false);
		Instance.transform.localPosition = new Vector3(0f, 0.0014f, 0.002f);
		Instance.transform.localRotation = Quaternion.Euler(190f, 0f, 0f);
		Instance.transform.localScale = new Vector3(83f, 83f, 83f);
		Light[] componentsInChildren = Instance.GetComponentsInChildren<Light>(true);
		Light[] array = componentsInChildren;
		foreach (Light val2 in array)
		{
			if (((Object)val2).name.IndexOf("SynthLight", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				SynthLight = val2;
				SynthLightMax = ((val2.intensity > 0f) ? val2.intensity : 2.5f);
				val2.intensity = 0f;
			}
			if (((Object)val2).name.IndexOf("BurnLight", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				BurnLight = val2;
				BurnLightMax = ((val2.intensity > 0f) ? val2.intensity : 3f);
				val2.intensity = 0f;
			}
		}
		coreMaterials.Clear();
		originalCoreColors.Clear();
		shellMaterials.Clear();
		originalShellColors.Clear();
		crystalMaterials.Clear();
		originalCrystalColors.Clear();
		Renderer[] componentsInChildren2 = Instance.GetComponentsInChildren<Renderer>();
		foreach (Renderer val3 in componentsInChildren2)
		{
			Material[] materials = val3.materials;
			foreach (Material val4 in materials)
			{
				if (((Object)val4).name.IndexOf("Core", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val4).name.IndexOf("MAGO", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val4.EnableKeyword("_EMISSION");
					val4.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
					coreMaterials.Add(val4);
					originalCoreColors.Add(val4.HasProperty("_Color") ? val4.color : Color.white);
				}
				else if (((Object)val4).name.IndexOf("Crystal", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val4.EnableKeyword("_EMISSION");
					val4.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
					crystalMaterials.Add(val4);
					originalCrystalColors.Add(val4.HasProperty("_Color") ? val4.color : Color.white);
				}
				else
				{
					shellMaterials.Add(val4);
					originalShellColors.Add(val4.HasProperty("_Color") ? val4.color : Color.white);
				}
			}
		}
	}

	public static void AnimateBurnModel(float progress)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: 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)
		for (int i = 0; i < shellMaterials.Count; i++)
		{
			if (shellMaterials[i].HasProperty("_Color"))
			{
				shellMaterials[i].color = Color.Lerp(originalShellColors[i], Color.black, progress * 0.8f);
			}
		}
		Color val = new Color(1f, 0.1f, 0.1f) * (progress * 30f);
		for (int j = 0; j < crystalMaterials.Count; j++)
		{
			Material val2 = crystalMaterials[j];
			val2.SetColor("_EmissionColor", val);
			val2.SetColor("_Emission", val);
			val2.color = Color.Lerp(originalCrystalColors[j], new Color(1f, 0.1f, 0.1f), progress);
		}
	}

	public static void AnimateSynthModel(float progress)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: 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_0039: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		Color val = new Color(0.1f, 0.8f, 1f) * (progress * 30f);
		for (int i = 0; i < coreMaterials.Count; i++)
		{
			Material val2 = coreMaterials[i];
			val2.SetColor("_EmissionColor", val);
			val2.SetColor("_Emission", val);
			val2.color = Color.Lerp(originalCoreColors[i], new Color(0.1f, 0.8f, 1f), progress);
		}
	}

	public static void ResetBurnVisuals()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < shellMaterials.Count; i++)
		{
			if (shellMaterials[i].HasProperty("_Color"))
			{
				shellMaterials[i].color = originalShellColors[i];
			}
		}
		for (int j = 0; j < crystalMaterials.Count; j++)
		{
			Material val = crystalMaterials[j];
			val.SetColor("_EmissionColor", Color.black);
			val.SetColor("_Emission", Color.black);
			val.color = originalCrystalColors[j];
		}
	}

	public static void ResetSynthVisuals()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < coreMaterials.Count; i++)
		{
			Material val = coreMaterials[i];
			val.SetColor("_EmissionColor", Color.black);
			val.SetColor("_Emission", Color.black);
			val.color = originalCoreColors[i];
		}
	}

	public static void PlaySafeSound(params string[] sfxNames)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		foreach (string text in sfxNames)
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(text);
			if ((Object)(object)prefab != (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(prefab, ((Component)Player.m_localPlayer).transform.position, Quaternion.identity);
				ZSFX component = val.GetComponent<ZSFX>();
				if ((Object)(object)component != (Object)null)
				{
					component.Play();
				}
				break;
			}
		}
	}

	public static void PlaySafeEffect(Transform root, bool onBack, params string[] vfxNames)
	{
		//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_006a: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: 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)
		if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)root == (Object)null)
		{
			return;
		}
		foreach (string text in vfxNames)
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(text);
			if ((Object)(object)prefab != (Object)null)
			{
				float num = (onBack ? (-0.4f) : 0.3f);
				Vector3 val = root.position + Vector3.up * 1.5f + root.forward * num;
				Object.Instantiate<GameObject>(prefab, val, Quaternion.identity);
				break;
			}
		}
	}

	public static void PlaySafeEffectAt(Vector3 position, params string[] vfxNames)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNetScene.instance == (Object)null)
		{
			return;
		}
		foreach (string text in vfxNames)
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(text);
			if ((Object)(object)prefab != (Object)null)
			{
				Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
				break;
			}
		}
	}

	public static GameObject CreateLoopingSound(Transform root, float targetVolume, params string[] prefabNames)
	{
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Expected O, but got Unknown
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)root == (Object)null)
		{
			return null;
		}
		AudioMixerGroup val = null;
		AudioSource[] componentsInChildren = ((Component)root).GetComponentsInChildren<AudioSource>(true);
		AudioSource[] array = componentsInChildren;
		foreach (AudioSource val2 in array)
		{
			if ((Object)(object)val2.outputAudioMixerGroup != (Object)null)
			{
				val = val2.outputAudioMixerGroup;
				break;
			}
		}
		foreach (string text in prefabNames)
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(text);
			if (!((Object)(object)prefab != (Object)null))
			{
				continue;
			}
			AudioClip val3 = null;
			AudioSource[] componentsInChildren2 = prefab.GetComponentsInChildren<AudioSource>(true);
			AudioSource[] array2 = componentsInChildren2;
			foreach (AudioSource val4 in array2)
			{
				if ((Object)(object)val4.clip != (Object)null && val4.loop)
				{
					val3 = val4.clip;
					if ((Object)(object)val == (Object)null)
					{
						val = val4.outputAudioMixerGroup;
					}
					break;
				}
			}
			if ((Object)(object)val3 == (Object)null)
			{
				ZSFX[] componentsInChildren3 = prefab.GetComponentsInChildren<ZSFX>(true);
				ZSFX[] array3 = componentsInChildren3;
				foreach (ZSFX val5 in array3)
				{
					if (val5.m_audioClips != null && val5.m_audioClips.Length != 0)
					{
						val3 = val5.m_audioClips[0];
						break;
					}
				}
			}
			if ((Object)(object)val3 != (Object)null)
			{
				GameObject val6 = new GameObject("ReplicatorLoop_" + text);
				val6.transform.SetParent(root, false);
				val6.transform.localPosition = new Vector3(0f, 1.5f, 0f);
				AudioSource val7 = val6.AddComponent<AudioSource>();
				val7.clip = val3;
				val7.loop = true;
				val7.volume = targetVolume;
				val7.spatialBlend = 1f;
				val7.maxDistance = 15f;
				val7.minDistance = 1f;
				val7.rolloffMode = (AudioRolloffMode)1;
				val7.outputAudioMixerGroup = val;
				val7.Play();
				return val6;
			}
		}
		return null;
	}

	public static IEnumerator FadeLightOut(Light lightObj, float duration)
	{
		if (!((Object)(object)lightObj == (Object)null))
		{
			float startIntensity = lightObj.intensity;
			float t = 0f;
			while (t < duration && (Object)(object)lightObj != (Object)null)
			{
				lightObj.intensity = Mathf.Lerp(startIntensity, 0f, t / duration);
				t += Time.deltaTime;
				yield return null;
			}
			if ((Object)(object)lightObj != (Object)null)
			{
				lightObj.intensity = 0f;
			}
		}
	}
}