Decompiled source of Leash v1.1.4

plugins/Leash.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.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyMetadata("PlanetRadialRewrite", "off")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Leash
{
	internal static class Art
	{
		private static readonly Dictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>();

		private static readonly Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();

		internal static Texture2D Texture(string name, bool repeat = true)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (textures.TryGetValue(name, out var value))
			{
				return value;
			}
			value = null;
			using (Stream stream = typeof(Art).Assembly.GetManifestResourceStream("Leash.art." + name + ".png"))
			{
				if (stream != null)
				{
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					value = new Texture2D(2, 2, (TextureFormat)4, true)
					{
						name = "ChistixLeash_" + name
					};
					if (!ImageConversion.LoadImage(value, memoryStream.ToArray()))
					{
						value = null;
					}
					else
					{
						((Texture)value).wrapMode = (TextureWrapMode)(!repeat);
						((Texture)value).anisoLevel = 4;
					}
				}
			}
			if ((Object)(object)value == (Object)null)
			{
				Plugin.Debug("no picture " + name);
			}
			return textures[name] = value;
		}

		internal static Sprite Sprite(string name)
		{
			//IL_003e: 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)
			if (sprites.TryGetValue(name, out var value))
			{
				return value;
			}
			Texture2D val = Texture(name, repeat: false);
			value = (((Object)(object)val != (Object)null) ? Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f) : null);
			if ((Object)(object)value != (Object)null)
			{
				((Object)value).name = "ChistixLeash_" + name;
			}
			return sprites[name] = value;
		}

		internal static Texture2D Of(Kind kind)
		{
			return Texture(kind switch
			{
				Kind.Chain => "tex_chain", 
				Kind.Strap => "tex_strap", 
				_ => "tex_rope", 
			});
		}

		internal static float Aspect(Kind kind)
		{
			Texture2D val = Of(kind);
			if (!((Object)(object)val != (Object)null) || ((Texture)val).width <= 0)
			{
				return 4f;
			}
			return (float)((Texture)val).height / (float)((Texture)val).width;
		}

		internal static float TileLength(Kind kind, float radius)
		{
			return Aspect(kind) * 2f * (float)Math.PI * Mathf.Max(radius, 0.005f);
		}

		internal static string IconOf(Kind kind)
		{
			return kind switch
			{
				Kind.Strap => "icon_strap", 
				Kind.Chain => "icon_chain", 
				Kind.Lasso => "icon_lasso", 
				_ => "icon_rope", 
			};
		}
	}
	internal static class Bait
	{
		internal sealed class Spec
		{
			internal string prefab;

			internal string token;

			internal string baseItem;

			internal string ru;

			internal string en;

			internal string descRu;

			internal string descEn;

			internal string recipe;

			internal string station;

			internal ConfigEntryRef config;

			internal GameObject made;

			internal HashSet<string> foods = new HashSet<string>();
		}

		internal sealed class ConfigEntryRef
		{
			internal ConfigEntry<string> recipe;

			internal ConfigEntry<string> station;
		}

		internal static readonly Spec[] Specs = new Spec[3]
		{
			new Spec
			{
				prefab = "ChistixBaitSweet",
				token = "$item_chistix_bait_sweet",
				baseItem = "Honey",
				ru = "Сладкая приманка",
				en = "Sweet bait",
				recipe = "Raspberry:3,Blueberries:3,Honey:1",
				station = "piece_workbench",
				descRu = "Ягоды с мёдом для кабана. Возьми в руку и держи колёсико мыши, чтобы прицелиться, отпусти — бросок; ЛКМ кладёт перед собой. Кабан подойдёт, съест и успокоится — можно надеть поводок.",
				descEn = "Berries and honey, for boars. Hold it in your hand, hold the mouse wheel to aim, let go to throw; left click sets it down. The boar comes, eats and calms down - time for a leash."
			},
			new Spec
			{
				prefab = "ChistixBaitMeat",
				token = "$item_chistix_bait_meat",
				baseItem = "RawMeat",
				ru = "Мясная приманка",
				en = "Meat bait",
				recipe = "RawMeat:2,Dandelion:2",
				station = "piece_workbench",
				descRu = "Мясо с одуванчиком для волка. Возьми в руку и держи колёсико мыши, чтобы прицелиться, отпусти — бросок; ЛКМ кладёт перед собой. Волк подойдёт, съест и успокоится.",
				descEn = "Meat with dandelion, for wolves. Hold it in your hand, hold the mouse wheel to aim, let go to throw; left click sets it down. The wolf comes, eats and calms down."
			},
			new Spec
			{
				prefab = "ChistixBaitGrain",
				token = "$item_chistix_bait_grain",
				baseItem = "Barley",
				ru = "Зерновая приманка",
				en = "Grain bait",
				recipe = "Cloudberry:3,Barley:3",
				station = "piece_cauldron",
				descRu = "Морошка с ячменём для локса. Возьми в руку и держи колёсико мыши, чтобы прицелиться, отпусти — бросок; ЛКМ кладёт перед собой. Локс подойдёт, съест и успокоится.",
				descEn = "Cloudberries with barley, for lox. Hold it in your hand, hold the mouse wheel to aim, let go to throw; left click sets it down. The lox comes, eats and calms down."
			}
		};

		internal static readonly int KBait = StringExtensionMethods.GetStableHashCode("chistix_leash_bait");

		internal static readonly int KCalm = StringExtensionMethods.GetStableHashCode("chistix_leash_calm");

		private static GameObject holder;

		private static bool held;

		private static int choice;

		private static LineRenderer arc;

		private static readonly List<Vector3> path = new List<Vector3>();

		private static Material lineMaterial;

		private static bool aiming;

		private static readonly Dictionary<TMP_Text, string> hintWords = new Dictionary<TMP_Text, string>();

		internal static bool Held => held;

		internal static bool Aiming => aiming;

		private static bool Secondary
		{
			get
			{
				if (!ZInput.GetButton("SecondaryAttack"))
				{
					return ZInput.GetButton("JoySecondaryAttack");
				}
				return true;
			}
		}

		private static bool PrimaryDown
		{
			get
			{
				if (!ZInput.GetButtonDown("Attack"))
				{
					return ZInput.GetButtonDown("JoyAttack");
				}
				return true;
			}
		}

		internal static Spec Of(ItemData item)
		{
			if (item?.m_shared != null)
			{
				return Specs.FirstOrDefault((Spec s) => s.token == item.m_shared.m_name);
			}
			return null;
		}

		internal static void Bind(ConfigFile config)
		{
			string[] array = new string[3] { "BaitSweet", "BaitMeat", "BaitGrain" };
			for (int i = 0; i < Specs.Length; i++)
			{
				Spec spec = Specs[i];
				spec.config = new ConfigEntryRef
				{
					recipe = config.Bind<string>(array[i], "Ingredients", spec.recipe, "Из чего делается: «Предмет:количество» через запятую. Приманка считается каждым из этих предметов: на неё идёт и успокаивается тот, кто ест хоть один из них."),
					station = config.Bind<string>(array[i], "Station", spec.station, "Где делается (имя префаба станции; пусто — руками).")
				};
				spec.config.recipe.SettingChanged += delegate
				{
					Item.Register(ObjectDB.instance);
				};
				spec.config.station.SettingChanged += delegate
				{
					Item.Register(ObjectDB.instance);
				};
			}
		}

		private static void Ensure(Spec spec, Func<string, GameObject> find)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_0101: 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_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			if ((Object)(object)spec.made != (Object)null)
			{
				return;
			}
			GameObject val = find(spec.baseItem) ?? find("Honey");
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.GetComponent<ItemDrop>() == (Object)null))
			{
				if ((Object)(object)holder == (Object)null)
				{
					holder = new GameObject("ChistixLeashBaits");
					holder.SetActive(false);
					Object.DontDestroyOnLoad((Object)(object)holder);
				}
				GameObject val2 = Object.Instantiate<GameObject>(val, holder.transform);
				((Object)val2).name = spec.prefab;
				ItemDrop component = val2.GetComponent<ItemDrop>();
				SharedData val3 = (SharedData)AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(component.m_itemData.m_shared, null);
				component.m_itemData.m_shared = val3;
				component.m_itemData.m_dropPrefab = val2;
				val3.m_name = spec.token;
				val3.m_description = spec.token + "_desc";
				val3.m_itemType = (ItemType)3;
				val3.m_animationState = (AnimationState)1;
				val3.m_food = (val3.m_foodStamina = (val3.m_foodEitr = 0f));
				val3.m_consumeStatusEffect = null;
				val3.m_equipStatusEffect = null;
				val3.m_useDurability = false;
				val3.m_maxStackSize = 20;
				val3.m_weight = 0.3f;
				val3.m_teleportable = true;
				val3.m_damages = default(DamageTypes);
				BaitLook.Apply(val2, spec.prefab);
				Sprite val4 = Art.Sprite((spec.prefab == "ChistixBaitSweet") ? "icon_bait_sweet" : ((spec.prefab == "ChistixBaitMeat") ? "icon_bait_meat" : "icon_bait_grain")) ?? BaitLook.Icon(spec.prefab);
				if ((Object)(object)val4 != (Object)null)
				{
					val3.m_icons = (Sprite[])(object)new Sprite[1] { val4 };
				}
				spec.made = val2;
			}
		}

		internal static void Register(ObjectDB db)
		{
			bool flag = false;
			Spec[] specs = Specs;
			foreach (Spec spec in specs)
			{
				Ensure(spec, (string n) => db.GetItemPrefab(n));
				if (!((Object)(object)spec.made == (Object)null) && !db.m_items.Contains(spec.made))
				{
					db.m_items.Add(spec.made);
					flag = true;
				}
			}
			if (flag)
			{
				db.UpdateRegisters();
			}
			foreach (Spec item in Specs.Where((Spec x) => (Object)(object)x.made != (Object)null))
			{
				string name = "Recipe_" + item.prefab;
				db.m_recipes.RemoveAll((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name == name);
				Recipe val = ScriptableObject.CreateInstance<Recipe>();
				((Object)val).name = name;
				val.m_item = item.made.GetComponent<ItemDrop>();
				val.m_amount = 2;
				val.m_enabled = !Plugin.LeashOnly.Value;
				val.m_resources = Item.Requirements(db, item.config.recipe.Value, item.prefab);
				val.m_craftingStation = Item.Station(db, item.config.station.Value);
				val.m_minStationLevel = 1;
				db.m_recipes.Add(val);
				item.foods = new HashSet<string>(from r in val.m_resources
					where (Object)(object)r.m_resItem != (Object)null
					select r.m_resItem.m_itemData.m_shared.m_name);
			}
		}

		internal static void Register(ZNetScene scene)
		{
			Spec[] specs = Specs;
			foreach (Spec spec in specs)
			{
				Ensure(spec, (string n) => scene.GetPrefab(n));
				if (!((Object)(object)spec.made == (Object)null))
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)spec.made).name);
					if (!scene.m_namedPrefabs.ContainsKey(stableHashCode))
					{
						scene.m_prefabs.Add(spec.made);
						scene.m_namedPrefabs.Add(stableHashCode, spec.made);
					}
				}
			}
		}

		internal static void Words(Localization localization, MethodInfo add, bool ru)
		{
			Spec[] specs = Specs;
			foreach (Spec spec in specs)
			{
				add.Invoke(localization, new object[2]
				{
					spec.token.Substring(1),
					ru ? spec.ru : spec.en
				});
				add.Invoke(localization, new object[2]
				{
					spec.token.Substring(1) + "_desc",
					ru ? spec.descRu : spec.descEn
				});
			}
		}

		internal static bool Eats(MonsterAI ai, ItemData item)
		{
			Spec spec = Of(item);
			if (spec == null || ai.m_consumeItems == null)
			{
				return false;
			}
			return ai.m_consumeItems.Any((ItemDrop c) => (Object)(object)c != (Object)null && spec.foods.Contains(c.m_itemData.m_shared.m_name));
		}

		private static bool Lures(MonsterAI ai, ItemDrop drop)
		{
			if ((Object)(object)drop == (Object)null || drop.m_itemData == null)
			{
				return false;
			}
			if (Eats(ai, drop.m_itemData))
			{
				return true;
			}
			if (!Plugin.OrdinaryFoodLures.Value && Of(drop.m_itemData) == null)
			{
				return false;
			}
			if (ai.m_consumeItems != null)
			{
				return ai.m_consumeItems.Any((ItemDrop c) => (Object)(object)c != (Object)null && c.m_itemData.m_shared.m_name == drop.m_itemData.m_shared.m_name);
			}
			return false;
		}

		private static bool IsBait(ItemDrop drop)
		{
			ZNetView val = (((Object)(object)drop != (Object)null) ? ((Component)drop).GetComponent<ZNetView>() : null);
			if ((Object)(object)val != (Object)null && val.IsValid())
			{
				return val.GetZDO().GetLong(KBait, 0L) != 0;
			}
			return false;
		}

		internal static ItemDrop Farther(MonsterAI ai)
		{
			//IL_002b: 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_0031: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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 (ai.m_consumeItems == null || ai.m_consumeItems.Count == 0)
			{
				return null;
			}
			float num = Plugin.BaitRadius.Value;
			ItemDrop val = null;
			Vector3 position = ((Component)ai).transform.position;
			Pens.Pen pen = Pens.At(position);
			foreach (ItemDrop s_instance in ItemDrop.s_instances)
			{
				if (!((Object)(object)s_instance == (Object)null))
				{
					float num2 = Vector3.Distance(((Component)s_instance).transform.position, position);
					if (!(num2 >= num) && IsBait(s_instance) && Lures(ai, s_instance) && Pens.At(((Component)s_instance).transform.position) == pen)
					{
						num = num2;
						val = s_instance;
					}
				}
			}
			if (!((Object)(object)val != (Object)null) || !((BaseAI)ai).HavePath(((Component)val).transform.position))
			{
				return null;
			}
			return val;
		}

		internal static bool Calm(Character c)
		{
			ZNetView val = (((Object)(object)c != (Object)null) ? ((Component)c).GetComponent<ZNetView>() : null);
			if ((Object)(object)val == (Object)null || !val.IsValid() || (Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			return (double)val.GetZDO().GetFloat(KCalm, 0f) > ZNet.instance.GetTimeSeconds();
		}

		internal static float CalmLeft(Character c)
		{
			ZNetView val = (((Object)(object)c != (Object)null) ? ((Component)c).GetComponent<ZNetView>() : null);
			if ((Object)(object)val == (Object)null || !val.IsValid() || (Object)(object)ZNet.instance == (Object)null)
			{
				return 0f;
			}
			return Mathf.Max(0f, (float)((double)val.GetZDO().GetFloat(KCalm, 0f) - ZNet.instance.GetTimeSeconds()));
		}

		internal static void Ate(Tameable tame, ItemDrop item)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)item == (Object)null || Of(item.m_itemData) == null)
			{
				return;
			}
			Character component = ((Component)tame).GetComponent<Character>();
			ZNetView component2 = ((Component)tame).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || !component2.IsOwner() || component.IsTamed() || (component.IsBoss() && !Plugin.CalmBosses.Value) || component.GetMaxHealth() > (float)Plugin.CalmMaxHealth.Value)
			{
				return;
			}
			if (Plugin.On(Plugin.Fear) && Taming.Trapped(component))
			{
				Link component3 = ((Component)component).GetComponent<Link>();
				if (component3 == null || !component3.Leashed)
				{
					return;
				}
			}
			component2.GetZDO().Set(KCalm, (float)(ZNet.instance.GetTimeSeconds() + (double)Plugin.CalmSeconds.Value));
			Husbandry.Gain(((Component)component).transform.position, 2f);
			BaseAI component4 = ((Component)component).GetComponent<BaseAI>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.SetAlerted(false);
			}
			Plugin.Debug($"calm: {component.m_name} for {Plugin.CalmSeconds.Value} s");
		}

		internal static void Disturbed(Character c)
		{
			ZNetView val = (((Object)(object)c != (Object)null) ? ((Component)c).GetComponent<ZNetView>() : null);
			if ((Object)(object)val != (Object)null && val.IsValid() && val.IsOwner() && Calm(c))
			{
				val.GetZDO().Set(KCalm, 0f);
			}
		}

		private static List<ItemData> Foods(Player player)
		{
			List<ItemData> allItems = ((Humanoid)player).GetInventory().GetAllItems();
			List<ItemData> list = allItems.Where((ItemData i) => Of(i) != null).ToList();
			list.AddRange(allItems.Where((ItemData i) => Of(i) == null && ((int)i.m_shared.m_itemType == 2 || i.m_shared.m_food > 0f)));
			return (from i in list
				group i by i.m_shared.m_name into g
				select g.First()).ToList();
		}

		internal static void Reset()
		{
			held = false;
			aiming = false;
			Hide();
		}

		internal static ItemData InHand(Player player)
		{
			ItemData val = (((Object)(object)player != (Object)null) ? ((Humanoid)player).GetRightItem() : null);
			if (val == null || Of(val) == null)
			{
				return null;
			}
			return val;
		}

		internal static string Hand(Player player)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = InHand(player);
			if (val == null || ((Character)player).InPlaceMode() || Hud.InRadial())
			{
				if (aiming)
				{
					aiming = false;
					Hide();
				}
				return null;
			}
			Aim(player, out var from, out var velocity);
			if (Secondary)
			{
				aiming = true;
				Preview(from, velocity);
				return null;
			}
			if (aiming)
			{
				aiming = false;
				Hide();
				Throw(player, val, from, velocity);
				return null;
			}
			if (PrimaryDown)
			{
				Place(player, val);
				return null;
			}
			return null;
		}

		internal static void KeyHintsLook(KeyHints hints)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && (Object)(object)hints.m_combatHints != (Object)null && hints.m_combatHints.activeSelf && InHand(localPlayer) != null)
			{
				hints.m_bowDrawGP.SetActive(false);
				hints.m_bowDrawKB.SetActive(false);
				GameObject[] array = (GameObject[])(object)new GameObject[2] { hints.m_primaryAttackGP, hints.m_primaryAttackKB };
				foreach (GameObject obj in array)
				{
					obj.SetActive(!aiming);
					Label(obj, Plugin.T("Положить перед собой", "Set down in front"));
				}
				array = (GameObject[])(object)new GameObject[2] { hints.m_secondaryAttackGP, hints.m_secondaryAttackKB };
				foreach (GameObject obj2 in array)
				{
					obj2.SetActive(true);
					Label(obj2, aiming ? Plugin.T("Отпустить: бросить", "Release to throw") : Plugin.T("Держать: бросить по дуге", "Hold to throw along the arc"));
				}
			}
			else
			{
				if (hintWords.Count == 0)
				{
					return;
				}
				foreach (KeyValuePair<TMP_Text, string> hintWord in hintWords)
				{
					if ((Object)(object)hintWord.Key != (Object)null)
					{
						hintWord.Key.text = hintWord.Value;
					}
				}
				hintWords.Clear();
			}
		}

		private static void Label(GameObject row, string words)
		{
			TMP_Text val = (((Object)(object)row != (Object)null) ? ((IEnumerable<TMP_Text>)row.GetComponentsInChildren<TMP_Text>(true)).FirstOrDefault((Func<TMP_Text, bool>)((TMP_Text t) => (Object)(object)t.transform.parent == (Object)(object)row.transform)) : null);
			if (!((Object)(object)val == (Object)null))
			{
				if (!hintWords.ContainsKey(val))
				{
					hintWords[val] = val.text;
				}
				if (val.text != words)
				{
					val.text = words;
				}
			}
		}

		private static void Place(Player player, ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_006d: 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)
			Vector3 val = Planet.Up(((Component)player).transform.position);
			Vector3 val2 = ((Component)player).transform.forward - val * Vector3.Dot(((Component)player).transform.forward, val);
			Vector3 val3 = ((Component)player).transform.position + ((Vector3)(ref val2)).normalized * 1.2f + val * 0.6f;
			Throw(player, item, val3, Vector3.zero);
		}

		internal static bool BlocksAttack(Humanoid who)
		{
			Player val = (Player)(object)((who is Player) ? who : null);
			if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer)
			{
				return InHand(val) != null;
			}
			return false;
		}

		internal static string Keys(Player player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = Plugin.BaitKey.Value;
			if ((int)value == 0)
			{
				return null;
			}
			if (ZInput.GetKeyDown(value, false))
			{
				held = true;
			}
			if (!held)
			{
				return null;
			}
			List<ItemData> list = Foods(player);
			if (list.Count == 0)
			{
				held = false;
				Hide();
				((Character)player).Message((MessageType)2, Plugin.T("Нечего бросить: нужна еда или приманка", "Nothing to throw: you need food or bait"), 0, (Sprite)null, false);
				return null;
			}
			Commands.Reading = true;
			float mouseScrollWheel = ZInput.GetMouseScrollWheel();
			Commands.Reading = false;
			if (Mathf.Abs(mouseScrollWheel) > 0.01f)
			{
				choice += ((!(mouseScrollWheel > 0f)) ? 1 : (-1));
			}
			choice = (choice % list.Count + list.Count) % list.Count;
			ItemData val = list[choice];
			Aim(player, out var from, out var velocity);
			Preview(from, velocity);
			if (ZInput.GetKeyUp(value, false) || !ZInput.GetKey(value, false))
			{
				held = false;
				Hide();
				Throw(player, val, from, velocity);
				return null;
			}
			string text = Localization.instance.Localize(val.m_shared.m_name);
			string text2 = ((Of(val) != null) ? Plugin.T(" — успокаивает", " — calms") : Plugin.T(" — только приманивает", " — lures only"));
			return Plugin.T("Приманка: ", "Bait: ") + "<color=yellow>‹ " + text + " ›</color>" + text2 + Plugin.T(" (колесо — выбор, отпустить — бросить)", " (wheel to pick, release to throw)");
		}

		private static void Aim(Player player, out Vector3 from, out Vector3 velocity)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : ((Component)player).transform);
			Vector3 val = Planet.Up(((Component)player).transform.position);
			VisEquipment component = ((Component)player).GetComponent<VisEquipment>();
			from = (((Object)(object)component != (Object)null && (Object)(object)component.m_rightHand != (Object)null) ? component.m_rightHand.position : (((Component)player).transform.position + val * 1.4f));
			Vector3 val2 = obj.forward + val * 0.3f;
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			velocity = normalized * (float)Plugin.BaitSpeed.Value;
		}

		private static void Preview(Vector3 from, Vector3 velocity)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: 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_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_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: 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_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: 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_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)arc == (Object)null)
			{
				GameObject val = new GameObject("ChistixLeashBaitArc");
				Object.DontDestroyOnLoad((Object)val);
				arc = val.AddComponent<LineRenderer>();
				if (lineMaterial == null)
				{
					lineMaterial = new Material(Shader.Find("Sprites/Default"));
				}
				((Renderer)arc).sharedMaterial = lineMaterial;
				arc.startWidth = 0.04f;
				arc.endWidth = 0.02f;
				arc.startColor = new Color(1f, 0.85f, 0.3f, 0.9f);
				arc.endColor = new Color(1f, 0.6f, 0.2f, 0.6f);
				arc.numCapVertices = 2;
				((Renderer)arc).shadowCastingMode = (ShadowCastingMode)0;
			}
			path.Clear();
			Vector3 val2 = Planet.Up(from);
			V3 v = Planet.ToV(from);
			V3 velocity2 = Planet.ToV(velocity);
			V3 up = Planet.ToV(val2);
			Vector3 gravity = Physics.gravity;
			V3[] array = LeashMath.Ballistic(v, velocity2, up, ((Vector3)(ref gravity)).magnitude, 0.04, 80);
			int mask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle", "Water" });
			Vector3 val3 = from;
			path.Add(from);
			Vector3? val4 = null;
			RaycastHit val7 = default(RaycastHit);
			for (int i = 1; i < array.Length; i++)
			{
				Vector3 val5 = Planet.ToU(array[i]);
				Vector3 val6 = val5 - val3;
				if (((Vector3)(ref val6)).sqrMagnitude > 1E-06f && Physics.Raycast(val3, ((Vector3)(ref val6)).normalized, ref val7, ((Vector3)(ref val6)).magnitude, mask, (QueryTriggerInteraction)1))
				{
					path.Add(((RaycastHit)(ref val7)).point);
					val4 = ((RaycastHit)(ref val7)).point;
					break;
				}
				path.Add(val5);
				val3 = val5;
			}
			if (val4.HasValue)
			{
				Vector3 val8 = val4.Value + val2 * 0.05f;
				Vector3 val9 = Vector3.Cross(val2, Vector3.forward);
				if (((Vector3)(ref val9)).sqrMagnitude < 0.01f)
				{
					val9 = Vector3.Cross(val2, Vector3.right);
				}
				((Vector3)(ref val9)).Normalize();
				Vector3 val10 = Vector3.Cross(val2, val9);
				for (int j = 0; j <= 12; j++)
				{
					float num = (float)j * (float)Math.PI * 2f / 12f;
					path.Add(val8 + (val9 * Mathf.Cos(num) + val10 * Mathf.Sin(num)) * 0.35f);
				}
			}
			arc.positionCount = path.Count;
			for (int k = 0; k < path.Count; k++)
			{
				arc.SetPosition(k, path[k]);
			}
			((Renderer)arc).enabled = true;
		}

		private static void Hide()
		{
			if ((Object)(object)arc != (Object)null)
			{
				((Renderer)arc).enabled = false;
			}
		}

		private static void Throw(Player player, ItemData food, Vector3 from, Vector3 velocity)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (!inventory.ContainsItem(food))
			{
				return;
			}
			ItemDrop val = ItemDrop.DropItem(food, 1, from, Quaternion.identity);
			inventory.RemoveItem(food, 1);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			val.m_autoPickup = false;
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				component.GetZDO().Set(KBait, player.GetPlayerID());
			}
			Rigidbody component2 = ((Component)val).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.linearVelocity = velocity;
				component2.angularVelocity = Random.insideUnitSphere * 2f;
				((Component)val).gameObject.AddComponent<Landing>();
			}
			foreach (Link item in Link.All)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item.monster != (Object)null && item.Owner && Vector3.Distance(((Component)item).transform.position, from) < (float)(Plugin.BaitRadius.Value + 20))
				{
					item.monster.m_consumeSearchTimer = Mathf.Max(item.monster.m_consumeSearchTimer, item.monster.m_consumeSearchInterval - 1.5f);
				}
			}
			Plugin.Debug("bait thrown: " + food.m_shared.m_name);
		}

		internal static void Marked(ItemDrop drop)
		{
			if (IsBait(drop))
			{
				drop.m_autoPickup = false;
			}
		}
	}
	internal sealed class Landing : MonoBehaviour
	{
		private Rigidbody body;

		private int touches;

		private float until;

		private void Awake()
		{
			body = ((Component)this).GetComponent<Rigidbody>();
			until = Time.time + 6f;
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_001c: 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_0046: 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)
			if ((Object)(object)body == (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Rigidbody obj = body;
			obj.linearVelocity *= ((touches == 0) ? 0.08f : 0.3f);
			Rigidbody obj2 = body;
			obj2.angularVelocity *= 0.2f;
			if (++touches >= 3)
			{
				Object.Destroy((Object)(object)this);
			}
		}

		private void Update()
		{
			if (Time.time > until)
			{
				Object.Destroy((Object)(object)this);
			}
		}
	}
	internal static class BaitLook
	{
		internal sealed class Palette
		{
			internal Color dark;

			internal Color light;

			internal Color speck;
		}

		internal static readonly Dictionary<string, Palette> Palettes = new Dictionary<string, Palette>
		{
			["ChistixBaitSweet"] = new Palette
			{
				dark = new Color(0.38f, 0.05f, 0.16f),
				light = new Color(0.78f, 0.2f, 0.34f),
				speck = new Color(0.95f, 0.85f, 0.55f)
			},
			["ChistixBaitMeat"] = new Palette
			{
				dark = new Color(0.26f, 0.08f, 0.06f),
				light = new Color(0.55f, 0.2f, 0.16f),
				speck = new Color(0.92f, 0.82f, 0.72f)
			},
			["ChistixBaitGrain"] = new Palette
			{
				dark = new Color(0.55f, 0.4f, 0.12f),
				light = new Color(0.93f, 0.78f, 0.38f),
				speck = new Color(0.98f, 0.94f, 0.75f)
			}
		};

		private static readonly Color leafDark = new Color(0.12f, 0.28f, 0.08f);

		private static readonly Color leafLight = new Color(0.35f, 0.58f, 0.18f);

		private static readonly Color twineDark = new Color(0.45f, 0.36f, 0.22f);

		private static readonly Color twineLight = new Color(0.78f, 0.68f, 0.48f);

		private static readonly Dictionary<string, Mesh> meshes = new Dictionary<string, Mesh>();

		private static readonly Dictionary<string, Material> materials = new Dictionary<string, Material>();

		private static Material baseMaterial;

		internal static void Apply(GameObject prefab, string name)
		{
			if (!Palettes.TryGetValue(name, out var value))
			{
				return;
			}
			if (baseMaterial == null)
			{
				baseMaterial = Rope.Lit(prefab);
			}
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is ParticleSystemRenderer))
				{
					val.enabled = false;
				}
			}
			if ((Object)(object)prefab.GetComponentInChildren<Collider>(true) == (Object)null)
			{
				prefab.AddComponent<SphereCollider>().radius = 0.1f;
			}
			Model(prefab.transform, "model", value, name, 1f).SetActive(true);
			Transform val2 = prefab.transform.Find("attach");
			if ((Object)(object)val2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val2).gameObject);
			}
			Model(prefab.transform, "attach", value, name, 0.8f).SetActive(false);
		}

		private static GameObject Model(Transform parent, string label, Palette p, string name, float scale)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00c3: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_016b: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			GameObject val = new GameObject(label);
			val.transform.SetParent(parent, false);
			val.transform.localScale = Vector3.one * scale;
			Material material = Pictured(tex: Art.Texture((name == "ChistixBaitSweet") ? "fill_sweet" : ((name == "ChistixBaitMeat") ? "fill_meat" : "fill_grain")), key: name + "_lump", scale: new Vector2(2f, 1f)) ?? Lit(name + "_lump", p.dark, p.light, p.speck, specks: true);
			Material val2 = ((name == "ChistixBaitGrain") ? Straw() : Pictured("leaf", Art.Texture("leaf"), Vector2.one));
			if (val2 == null)
			{
				val2 = Lit("leaf", leafDark, leafLight, leafLight, specks: false);
			}
			Material material2 = Pictured("twine", Art.Texture("tex_rope"), new Vector2(1f, 3f)) ?? Lit("twine", twineDark, twineLight, twineLight, specks: false);
			Part(val, "lump", Mesh("lump", () => Lump(0.09f)), material);
			Part(val, "leaf", Mesh("leaf", () => Leaf(0.097f)), val2);
			Part(val, "twine", Mesh("twine", () => Ring(0.092f, 0.007f)), material2);
			Part(val, "knot", Mesh("knot", () => Lump(0.018f)), material2).transform.localPosition = new Vector3(0f, 0.075f, 0f);
			return val;
		}

		private static GameObject Part(GameObject root, string name, Mesh mesh, Material material)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(root.transform, false);
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material;
			return val;
		}

		private static Mesh Mesh(string key, Func<Mesh> make)
		{
			if (!meshes.TryGetValue(key, out var value) || (Object)(object)value == (Object)null)
			{
				value = (meshes[key] = make());
			}
			return value;
		}

		private static Mesh Lump(float radius)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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)
			//IL_00cb: 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)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			Vector3 val = default(Vector3);
			for (int i = 0; i <= 8; i++)
			{
				float num = (float)Math.PI * (float)i / 8f;
				for (int j = 0; j <= 12; j++)
				{
					float num2 = (float)Math.PI * 2f * (float)j / 12f;
					((Vector3)(ref val))..ctor(Mathf.Sin(num) * Mathf.Cos(num2), Mathf.Cos(num), Mathf.Sin(num) * Mathf.Sin(num2));
					float num3 = 1f + 0.08f * Mathf.Sin((float)i * 2.3f + (float)(j % 12) * 1.7f) * Mathf.Sin(num);
					list.Add(Vector3.Scale(val * radius * num3, new Vector3(1f, 0.82f, 1f)));
					list2.Add(val);
					list3.Add(new Vector2((float)j / 12f, (float)i / 8f));
				}
			}
			for (int k = 0; k < 8; k++)
			{
				for (int l = 0; l < 12; l++)
				{
					int num4 = k * 13 + l;
					int num5 = num4 + 12 + 1;
					list4.Add(num4);
					list4.Add(num4 + 1);
					list4.Add(num5);
					list4.Add(num4 + 1);
					list4.Add(num5 + 1);
					list4.Add(num5);
				}
			}
			return Build("ChistixBaitLump", list, list2, list3, list4);
		}

		private static Mesh Leaf(float radius)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			Vector3 val = default(Vector3);
			for (int i = 0; i <= 6; i++)
			{
				for (int j = 0; j <= 16; j++)
				{
					float num = (float)Math.PI * 2f * (float)j / 16f;
					float num2 = 0.48f + 0.22f * Mathf.Pow(Mathf.Abs(Mathf.Cos(num * 2f)), 3f);
					float num3 = (float)Math.PI * (1f - num2 * (float)i / 6f);
					((Vector3)(ref val))..ctor(Mathf.Sin(num3) * Mathf.Cos(num), Mathf.Cos(num3), Mathf.Sin(num3) * Mathf.Sin(num));
					list.Add(Vector3.Scale(val * radius, new Vector3(1f, 0.82f, 1f)));
					list2.Add(val);
					list3.Add(new Vector2((float)j / 16f, (float)i / 6f));
				}
			}
			for (int k = 0; k < 6; k++)
			{
				for (int l = 0; l < 16; l++)
				{
					int num4 = k * 17 + l;
					int num5 = num4 + 16 + 1;
					list4.Add(num4);
					list4.Add(num5);
					list4.Add(num4 + 1);
					list4.Add(num4 + 1);
					list4.Add(num5);
					list4.Add(num5 + 1);
					list4.Add(num4);
					list4.Add(num4 + 1);
					list4.Add(num5);
					list4.Add(num4 + 1);
					list4.Add(num5 + 1);
					list4.Add(num5);
				}
			}
			return Build("ChistixBaitLeaf", list, list2, list3, list4);
		}

		private static Mesh Ring(float r, float tube)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			Vector3 val = default(Vector3);
			for (int i = 0; i <= 20; i++)
			{
				float num = (float)i * (float)Math.PI * 2f / 20f;
				((Vector3)(ref val))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num));
				for (int j = 0; j <= 5; j++)
				{
					float num2 = (float)j * (float)Math.PI * 2f / 5f;
					Vector3 val2 = val * Mathf.Cos(num2) + Vector3.up * Mathf.Sin(num2);
					list.Add(val * r + val2 * tube);
					list2.Add(val2);
					list3.Add(new Vector2((float)i * 0.5f, (float)j / 5f));
				}
			}
			for (int k = 0; k < 20; k++)
			{
				for (int l = 0; l < 5; l++)
				{
					int num3 = k * 6 + l;
					int num4 = num3 + 5 + 1;
					list4.Add(num3);
					list4.Add(num3 + 1);
					list4.Add(num4);
					list4.Add(num3 + 1);
					list4.Add(num4 + 1);
					list4.Add(num4);
				}
			}
			return Build("ChistixBaitTwine", list, list2, list3, list4);
		}

		private static Mesh Build(string name, List<Vector3> v, List<Vector3> n, List<Vector2> uv, List<int> t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = name
			};
			val.SetVertices(v);
			val.SetNormals(n);
			val.SetUVs(0, uv);
			val.SetTriangles(t, 0);
			val.RecalculateBounds();
			return val;
		}

		private static Material Pictured(string key, Texture2D tex, Vector2 scale)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_007f: 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_0054: 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)
			if ((Object)(object)tex == (Object)null)
			{
				return null;
			}
			if (materials.TryGetValue("pic_" + key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = (((Object)(object)baseMaterial != (Object)null) ? new Material(baseMaterial) : new Material(Shader.Find("Standard") ?? Shader.Find("Sprites/Default")));
			((Object)value).name = "ChistixBait_" + key;
			value.mainTexture = (Texture)(object)tex;
			value.mainTextureScale = scale;
			value.mainTextureOffset = Vector2.zero;
			if (value.HasProperty("_Color"))
			{
				value.color = Color.white;
			}
			string[] array = new string[3] { "_BumpMap", "_MetallicGlossMap", "_EmissionMap" };
			foreach (string text in array)
			{
				if (value.HasProperty(text))
				{
					value.SetTexture(text, (Texture)null);
				}
			}
			value.DisableKeyword("_EMISSION");
			return materials["pic_" + key] = value;
		}

		private static Material Straw()
		{
			//IL_001a: 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)
			Material val = Pictured("straw", Art.Texture("tex_rope"), new Vector2(3f, 2f));
			if ((Object)(object)val != (Object)null && val.HasProperty("_Color"))
			{
				val.color = new Color(1.55f, 1.35f, 0.85f);
			}
			return val;
		}

		private static Material Lit(string key, Color dark, Color light, Color speck, bool specks)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, true)
			{
				wrapMode = (TextureWrapMode)0,
				name = "ChistixBait_" + key
			};
			Color[] array = (Color[])(object)new Color[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num = Mathf.PerlinNoise((float)j * 0.18f, (float)i * 0.18f) * 0.7f + Mathf.PerlinNoise((float)j * 0.6f + 17f, (float)i * 0.6f + 5f) * 0.3f;
					Color val2 = Color.Lerp(dark, light, num);
					if (specks && Mathf.PerlinNoise((float)j * 1.3f + 40f, (float)i * 1.3f + 9f) > 0.78f)
					{
						val2 = Color.Lerp(val2, speck, 0.8f);
					}
					array[i * 64 + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply(true);
			value = (((Object)(object)baseMaterial != (Object)null) ? new Material(baseMaterial) : new Material(Shader.Find("Standard") ?? Shader.Find("Sprites/Default")));
			((Object)value).name = "ChistixBait_" + key;
			value.mainTexture = (Texture)(object)val;
			value.mainTextureScale = Vector2.one;
			value.mainTextureOffset = Vector2.zero;
			if (value.HasProperty("_Color"))
			{
				value.color = Color.white;
			}
			string[] array2 = new string[3] { "_BumpMap", "_MetallicGlossMap", "_EmissionMap" };
			foreach (string text in array2)
			{
				if (value.HasProperty(text))
				{
					value.SetTexture(text, (Texture)null);
				}
			}
			value.DisableKeyword("_EMISSION");
			return materials[key] = value;
		}

		internal static Sprite Icon(string name)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_02af: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			if (!Palettes.TryGetValue(name, out var value))
			{
				return null;
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[16384];
			float num = 64f;
			float num2 = 60f;
			float num3 = 42f;
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num4 = ((float)j - num) / num3;
					float num5 = ((float)i - num2) / (num3 * 0.86f);
					float num6 = num4 * num4 + num5 * num5;
					Color val2 = Color.clear;
					if (num6 <= 1f)
					{
						float num7 = Mathf.Clamp01(0.55f + 0.45f * ((0f - num4) * 0.5f + num5 * 0.6f + Mathf.Sqrt(Mathf.Max(0f, 1f - num6)) * 0.6f));
						val2 = Color.Lerp(value.dark, value.light, num7);
						if (Mathf.PerlinNoise((float)j * 0.35f, (float)i * 0.35f) > 0.74f)
						{
							val2 = Color.Lerp(val2, value.speck, 0.75f);
						}
						float num8 = -0.05f + 0.28f * Mathf.Pow(Mathf.Abs(Mathf.Sin(num4 * 3.1f)), 2f);
						if (num5 < num8)
						{
							val2 = Color.Lerp(leafDark, leafLight, num7);
							if (Mathf.Abs(Mathf.Repeat(num4 * 3f + num5 * 2.2f, 1f) - 0.5f) < 0.05f)
							{
								val2 = Color.Lerp(val2, leafDark, 0.6f);
							}
						}
						if (Mathf.Abs(num5 - 0.08f - 0.06f * num4) < 0.07f)
						{
							val2 = Color.Lerp(twineDark, twineLight, num7);
						}
						float a = Mathf.Clamp01((1f - num6) * num3 * 0.5f);
						val2.a = a;
					}
					float num9 = ((float)j - num) / 9f;
					float num10 = ((float)i - (num2 + num3 * 0.86f - 4f)) / 7f;
					if (num9 * num9 + num10 * num10 <= 1f)
					{
						val2 = Color.Lerp(twineDark, twineLight, 0.5f + 0.5f * ((0f - num9) * 0.4f + num10 * 0.5f));
					}
					array[i * 128 + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
		}
	}
	internal static class Cart
	{
		internal static readonly KeyValuePair<int, int> Horse = ZDO.GetHashZDOID("chistix_leash_horse");

		private static float timer;

		private static Func<Vagon, float> roadFactor;

		private static bool roadLooked;

		internal static ZDOID HorseOf(Vagon vagon)
		{
			//IL_0024: 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)
			ZNetView val = (((Object)(object)vagon != (Object)null) ? ((Component)vagon).GetComponent<ZNetView>() : null);
			if (!((Object)(object)val != (Object)null) || !val.IsValid())
			{
				return ZDOID.None;
			}
			return val.GetZDO().GetZDOID(Horse);
		}

		private static Vector3 BackLocal(Link link, Vagon vagon)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			Character character = link.character;
			Vector3 lossyScale = ((Component)link).transform.lossyScale;
			return new Vector3(0f, vagon.m_attachOffset.y / Mathf.Max(lossyScale.y, 0.01f), (0f - character.GetRadius()) * 0.9f / Mathf.Max(lossyScale.z, 0.01f));
		}

		internal static bool Hitch(Player player, Vagon vagon)
		{
			//IL_0032: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: 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_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: 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_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)vagon).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			ZDOID val = HorseOf(vagon);
			if (!((ZDOID)(ref val)).IsNone())
			{
				((Character)player).Message((MessageType)2, Plugin.T("Телега уже запряжена", "The cart is already hitched"), 0, (Sprite)null, false);
				return false;
			}
			if (vagon.IsAttached())
			{
				((Character)player).Message((MessageType)2, Plugin.T("Телегу кто-то тянет", "Someone is pulling the cart"), 0, (Sprite)null, false);
				return false;
			}
			Link link = (from l in Leash.Mine
				where l.Led && !l.Hitched && !l.Wild
				orderby Vector3.Distance(((Component)l).transform.position, ((Component)vagon).transform.position)
				select l).FirstOrDefault();
			if ((Object)(object)link == (Object)null)
			{
				((Character)player).Message((MessageType)2, Plugin.T("Сначала возьми зверя на поводок", "Leash a creature first"), 0, (Sprite)null, false);
				return false;
			}
			if (Vector3.Distance(((Component)link).transform.position, ((Component)vagon).transform.position) > link.length + 12f)
			{
				((Character)player).Message((MessageType)2, Plugin.T("Зверь слишком далеко от телеги", "The creature is too far from the cart"), 0, (Sprite)null, false);
				return false;
			}
			if (!component.IsOwner())
			{
				component.ClaimOwnership();
			}
			ZDO val2 = Leash.Claim(link);
			val2.Set(Link.KCart, component.GetZDO().m_uid);
			component.GetZDO().Set(Horse, val2.m_uid);
			link.Refresh();
			Vector3 val3 = vagon.m_attachPoint.position - ((Component)vagon).transform.position;
			Vector3 val4 = Planet.Up(vagon.m_attachPoint.position);
			val3 -= val4 * Vector3.Dot(val3, val4);
			if (((Vector3)(ref val3)).sqrMagnitude < 0.01f)
			{
				val3 = ((Component)vagon).transform.forward;
			}
			((Vector3)(ref val3)).Normalize();
			Vector3 pos = vagon.m_attachPoint.position + val3 * (link.character.GetRadius() * 0.9f) - val4 * (vagon.m_attachOffset.y - 0.05f);
			Leash.Warp(link, pos);
			((Component)link).transform.rotation = Quaternion.LookRotation(val3, val4);
			if ((Object)(object)link.character.m_body != (Object)null)
			{
				link.character.m_body.rotation = ((Component)link).transform.rotation;
			}
			Join(vagon, link);
			double num = LeashMath.Capacity(link.Pull, Plugin.CartLoadPerHealth.Value);
			((Character)player).Message((MessageType)2, Plugin.T($"{Leash.Name(link)} запряжён: тянет до {num:0} кг", $"{Leash.Name(link)} is hitched: pulls up to {num:0} kg"), 0, (Sprite)null, false);
			return true;
		}

		private static void Join(Vagon vagon, Link link)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)vagon.m_attachJoin != (Object)null)
			{
				Object.Destroy((Object)(object)vagon.m_attachJoin);
			}
			ConfigurableJoint val = ((Component)vagon).gameObject.AddComponent<ConfigurableJoint>();
			((Joint)val).autoConfigureConnectedAnchor = false;
			((Joint)val).anchor = vagon.m_attachPoint.localPosition;
			((Joint)val).connectedAnchor = BackLocal(link, vagon);
			((Joint)val).breakForce = vagon.m_breakForce * Mathf.Max(1f, link.Pull / 100f);
			val.xMotion = (ConfigurableJointMotion)1;
			val.yMotion = (ConfigurableJointMotion)1;
			val.zMotion = (ConfigurableJointMotion)0;
			SoftJointLimit linearLimit = default(SoftJointLimit);
			((SoftJointLimit)(ref linearLimit)).limit = 0.001f;
			val.linearLimit = linearLimit;
			SoftJointLimitSpring linearLimitSpring = default(SoftJointLimitSpring);
			((SoftJointLimitSpring)(ref linearLimitSpring)).spring = vagon.m_spring;
			((SoftJointLimitSpring)(ref linearLimitSpring)).damper = vagon.m_springDamping;
			val.linearLimitSpring = linearLimitSpring;
			((Joint)val).connectedBody = link.character.m_body;
			vagon.m_attachJoin = val;
			vagon.m_attachedObject = ((Component)link).gameObject;
			((Component)vagon).GetComponent<ZNetView>().GetZDO().Set(ZDOVars.s_attachJointHash, true);
		}

		internal static void Unhitch(Link link)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(link.cart) : null);
			Vagon val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Vagon>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				ZNetView component = ((Component)val2).GetComponent<ZNetView>();
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
				}
				if ((Object)(object)val2.m_attachedObject == (Object)(object)((Component)link).gameObject)
				{
					val2.Detach();
				}
				component.GetZDO().Set(Horse, ZDOID.None);
			}
			ZDO obj = Leash.Claim(link);
			if (obj != null)
			{
				obj.Set(Link.KCart, ZDOID.None);
			}
			Restore(link);
			link.Refresh();
		}

		internal static void Tick(float dt)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: 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)
			timer -= dt;
			if (timer > 0f)
			{
				return;
			}
			timer = 0.5f;
			foreach (Link item in Link.All.Where((Link l) => (Object)(object)l != (Object)null && l.Hitched && l.Owner).ToList())
			{
				GameObject val = ZNetScene.instance.FindInstance(item.cart);
				Vagon val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Vagon>() : null);
				if ((Object)(object)val2 == (Object)null)
				{
					if (Time.time - item.bornAt > 10f && ZDOMan.instance.GetZDO(item.cart) == null)
					{
						ZDO obj = Leash.Claim(item);
						if (obj != null)
						{
							obj.Set(Link.KCart, ZDOID.None);
						}
						Restore(item);
						item.Refresh();
					}
					continue;
				}
				ZNetView component = ((Component)val2).GetComponent<ZNetView>();
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
				}
				if ((Object)(object)val2.m_attachJoin == (Object)null || (Object)(object)val2.m_attachedObject != (Object)(object)((Component)item).gameObject)
				{
					if (!(Vector3.Distance(val2.m_attachPoint.position, ((Component)item).transform.TransformPoint(BackLocal(item, val2))) < 4f))
					{
						continue;
					}
					Join(val2, item);
				}
				float num = val2.m_baseMass + (((Object)(object)val2.m_container != (Object)null) ? (val2.m_container.GetInventory().GetTotalWeight() * val2.m_itemWeightMassFactor) : 0f);
				num *= RoadFactor(val2);
				Speed(item, (float)LeashMath.CartSpeed(num, LeashMath.Capacity(item.Pull, Plugin.CartLoadPerHealth.Value)));
			}
		}

		private static float RoadFactor(Vagon vagon)
		{
			if (!roadLooked)
			{
				roadLooked = true;
				try
				{
					MethodInfo methodInfo = (from a in AppDomain.CurrentDomain.GetAssemblies()
						select a.GetType("Trails.Api", throwOnError: false)).FirstOrDefault((Type t) => t != null)?.GetMethod("CartFactor", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Vagon) }, null);
					if (methodInfo != null && methodInfo.ReturnType == typeof(float))
					{
						roadFactor = (Func<Vagon, float>)Delegate.CreateDelegate(typeof(Func<Vagon, float>), methodInfo);
						Plugin.Log("Trails found: carts are lighter on roads");
					}
				}
				catch (Exception ex)
				{
					Plugin.Debug("Trails: " + ex.Message);
				}
			}
			if (roadFactor == null)
			{
				return 1f;
			}
			try
			{
				return Mathf.Clamp(roadFactor(vagon), 0.1f, 1f);
			}
			catch
			{
				return 1f;
			}
		}

		private static void Speed(Link link, float factor)
		{
			Character character = link.character;
			if (link.baseWalk < 0f)
			{
				link.baseWalk = character.m_walkSpeed;
				link.baseRun = character.m_runSpeed;
				link.baseSpeed = character.m_speed;
			}
			character.m_walkSpeed = link.baseWalk * factor;
			character.m_runSpeed = link.baseRun * factor;
			character.m_speed = link.baseSpeed * factor;
		}

		internal static void Restore(Link link)
		{
			if (!(link.baseWalk < 0f) && !((Object)(object)link.character == (Object)null))
			{
				link.character.m_walkSpeed = link.baseWalk;
				link.character.m_runSpeed = link.baseRun;
				link.character.m_speed = link.baseSpeed;
				link.baseWalk = -1f;
			}
		}

		internal static bool Fits(Vagon vagon, GameObject go, ref bool result)
		{
			//IL_003f: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Link link = (((Object)(object)go != (Object)null) ? go.GetComponent<Link>() : null);
			if ((Object)(object)link == (Object)null || !link.Hitched)
			{
				return false;
			}
			ZNetView component = ((Component)vagon).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || link.cart != component.GetZDO().m_uid)
			{
				return false;
			}
			result = ((Component)vagon).transform.up.y >= 0.1f || Planet.On;
			if (result)
			{
				result = Vector3.Distance(vagon.m_attachPoint.position, ((Component)link).transform.TransformPoint(BackLocal(link, vagon))) < 3f + link.character.GetRadius() * 0.5f;
			}
			return true;
		}

		internal static bool PulledByCreature(Vagon vagon)
		{
			if ((Object)(object)vagon.m_attachedObject != (Object)null)
			{
				return (Object)(object)vagon.m_attachedObject.GetComponent<Link>() != (Object)null;
			}
			return false;
		}
	}
	internal sealed class Collar
	{
		private sealed class Fit
		{
			internal float radius;

			internal Vector3 centre;
		}

		private const int Around = 16;

		private const int Tube = 6;

		private readonly GameObject go;

		private readonly MeshRenderer renderer;

		private readonly float ringRadius;

		private readonly float tube;

		private readonly MeshFilter filter;

		private readonly Transform neck;

		private readonly Transform head;

		private readonly Character character;

		private Kind kind = (Kind)(-1);

		private static readonly Dictionary<string, Fit> fits = new Dictionary<string, Fit>();

		private readonly Fit fit;

		private readonly float scale;

		internal float Radius => ringRadius;

		internal Collar(Transform neck, Transform head, Character character)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			this.neck = neck;
			this.head = (((Object)(object)head != (Object)(object)neck) ? head : null);
			this.character = character;
			scale = Mathf.Max(Mathf.Abs(((Component)character).transform.lossyScale.y), 0.01f);
			string prefabName = Utils.GetPrefabName(((Component)character).gameObject);
			if (!fits.TryGetValue(prefabName, out fit))
			{
				fit = Measure();
				fits[prefabName] = fit;
			}
			ringRadius = ((fit != null) ? (fit.radius * scale) : Mathf.Clamp(Mathf.Min(character.GetRadius() * 0.3f, character.GetHeight() * 0.12f), 0.06f, 0.35f));
			tube = Mathf.Max(ringRadius * 0.14f, 0.012f);
			go = new GameObject("ChistixLeashCollar");
			filter = go.AddComponent<MeshFilter>();
			filter.sharedMesh = Torus(ringRadius, tube, Kind.Rope);
			renderer = go.AddComponent<MeshRenderer>();
			((Renderer)renderer).shadowCastingMode = (ShadowCastingMode)1;
			go.SetActive(false);
		}

		internal void Show(bool on, Kind leash)
		{
			if (on && leash != kind)
			{
				kind = leash;
				((Renderer)renderer).sharedMaterial = Rope.Material(leash);
				filter.sharedMesh = Torus(ringRadius, tube, leash);
			}
			if (go.activeSelf != on)
			{
				go.SetActive(on);
			}
			if (on)
			{
				Place();
			}
		}

		private void Place()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)neck == (Object)null))
			{
				Vector3 val = (((Object)(object)head != (Object)null) ? (head.position - neck.position) : Vector3.zero);
				Vector3 val2 = neck.position;
				if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
				{
					val2 += val * 0.25f;
				}
				else
				{
					val = (((Object)(object)character != (Object)null) ? ((Component)character).transform.forward : Vector3.forward);
				}
				if (fit != null)
				{
					val2 = neck.TransformPoint(fit.centre);
				}
				go.transform.SetPositionAndRotation(val2, Quaternion.FromToRotation(Vector3.up, ((Vector3)(ref val)).normalized));
				go.transform.localScale = Vector3.one;
			}
		}

		private Fit Measure()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_01e3: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: 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_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: 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)
			try
			{
				Vector3 val = (((Object)(object)head != (Object)null) ? (head.position - neck.position) : (((Component)character).transform.forward * Mathf.Max(character.GetHeight() * 0.15f, 0.1f)));
				float magnitude = ((Vector3)(ref val)).magnitude;
				if (magnitude < 0.001f)
				{
					return null;
				}
				Vector3 val2 = val / magnitude;
				Vector3 val3 = neck.position + (((Object)(object)head != (Object)null) ? (val * 0.25f) : Vector3.zero);
				float num = Mathf.Max(0.03f, magnitude * 0.15f);
				List<Vector3> list = new List<Vector3>();
				Mesh val4 = new Mesh();
				SkinnedMeshRenderer[] componentsInChildren = ((Component)character).GetComponentsInChildren<SkinnedMeshRenderer>(false);
				foreach (SkinnedMeshRenderer val5 in componentsInChildren)
				{
					if (!((Renderer)val5).enabled || (Object)(object)val5.sharedMesh == (Object)null)
					{
						continue;
					}
					val5.BakeMesh(val4);
					Matrix4x4 val6 = Matrix4x4.TRS(((Component)val5).transform.position, ((Component)val5).transform.rotation, Vector3.one);
					Vector3[] vertices = val4.vertices;
					foreach (Vector3 val7 in vertices)
					{
						Vector3 val8 = ((Matrix4x4)(ref val6)).MultiplyPoint3x4(val7) - val3;
						float num2 = Vector3.Dot(val8, val2);
						if (Mathf.Abs(num2) < num)
						{
							list.Add(val3 + val8 - val2 * num2);
						}
					}
				}
				Object.Destroy((Object)(object)val4);
				if (list.Count < 12)
				{
					return null;
				}
				Vector3 val9 = Vector3.zero;
				foreach (Vector3 item in list)
				{
					val9 += item;
				}
				val9 /= (float)list.Count;
				List<float> list2 = new List<float>(list.Count);
				foreach (Vector3 item2 in list)
				{
					Vector3 val10 = item2 - val9;
					list2.Add(((Vector3)(ref val10)).magnitude);
				}
				list2.Sort();
				float num3 = list2[(int)((float)list2.Count * 0.7f)] + 0.015f;
				num3 = Mathf.Clamp(num3, 0.04f, 1f);
				Plugin.Debug($"collar for {((Object)character).name}: radius {num3:0.00} m from {list.Count} points");
				return new Fit
				{
					radius = num3 / scale,
					centre = neck.InverseTransformPoint(val9)
				};
			}
			catch (Exception ex)
			{
				Plugin.Debug("collar measure: " + ex.Message);
				return null;
			}
		}

		internal Vector3 Knot(Vector3 up)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			return go.transform.position - up * ringRadius * 0.8f;
		}

		internal void Destroy()
		{
			if ((Object)(object)go != (Object)null)
			{
				Object.Destroy((Object)(object)go);
			}
		}

		private static Mesh Torus(float r, float t, Kind kind)
		{
			//IL_0090: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: 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_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			Vector3[] array = (Vector3[])(object)new Vector3[119];
			Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length];
			Vector2[] array3 = (Vector2[])(object)new Vector2[array.Length];
			Vector3 val = default(Vector3);
			Vector3 val2 = default(Vector3);
			for (int i = 0; i <= 16; i++)
			{
				float num = (float)i * (float)Math.PI * 2f / 16f;
				((Vector3)(ref val))..ctor(Mathf.Cos(num) * r, 0f, Mathf.Sin(num) * r);
				((Vector3)(ref val2))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num));
				for (int j = 0; j <= 6; j++)
				{
					float num2 = (float)j * (float)Math.PI * 2f / 6f;
					Vector3 val3 = val2 * Mathf.Cos(num2) + Vector3.up * Mathf.Sin(num2);
					int num3 = i * 7 + j;
					array[num3] = val + val3 * t;
					array2[num3] = val3;
					array3[num3] = new Vector2((float)j / 6f, (float)i * 2f * (float)Math.PI * r / 16f / Art.TileLength(kind, t));
				}
			}
			int[] array4 = new int[576];
			int num4 = 0;
			for (int k = 0; k < 16; k++)
			{
				for (int l = 0; l < 6; l++)
				{
					int num5 = k * 7 + l;
					int num6 = num5 + 6 + 1;
					array4[num4++] = num5;
					array4[num4++] = num5 + 1;
					array4[num4++] = num6;
					array4[num4++] = num5 + 1;
					array4[num4++] = num6 + 1;
					array4[num4++] = num6;
				}
			}
			Mesh val4 = new Mesh
			{
				name = "ChistixLeashCollar",
				vertices = array,
				normals = array2,
				uv = array3,
				triangles = array4
			};
			val4.RecalculateBounds();
			return val4;
		}
	}
	internal static class Commands
	{
		internal static Command Selected;

		private static bool held;

		private static bool scrolled;

		internal static bool Reading;

		internal const string RpcName = "ChistixLeash_Whistle";

		private static AudioClip clip;

		internal static bool Held => held;

		internal static string Name(Command c)
		{
			return c switch
			{
				Command.Stay => Plugin.T("стоять", "stay"), 
				Command.Guard => Plugin.T("охраняй место", "guard here"), 
				Command.Attack => Plugin.T("атакуй цель", "attack target"), 
				Command.Whistle => Plugin.T("ко мне (свисток)", "come (whistle)"), 
				_ => Plugin.T("рядом", "heel"), 
			};
		}

		internal static void Reset()
		{
			held = false;
		}

		internal static string Keys(Player player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = Plugin.CommandKey.Value;
			if ((int)value == 0)
			{
				return null;
			}
			if (ZInput.GetKeyDown(value, false))
			{
				held = true;
				scrolled = false;
			}
			if (!held)
			{
				return null;
			}
			Reading = true;
			float mouseScrollWheel = ZInput.GetMouseScrollWheel();
			Reading = false;
			if (Mathf.Abs(mouseScrollWheel) > 0.01f)
			{
				Selected = (Command)LeashMath.Cycle((int)Selected, (!(mouseScrollWheel > 0f)) ? 1 : (-1));
				scrolled = true;
			}
			if (ZInput.GetKeyUp(value, false) || !ZInput.GetKey(value, false))
			{
				held = false;
				if (!scrolled)
				{
					Give(player, Selected);
				}
				return null;
			}
			return Plugin.T("Команда: ", "Command: ") + "<color=yellow>‹ " + Name(Selected) + " ›</color>" + Plugin.T(" (колесо — выбор, отпустить — отдать)", " (wheel to pick, release to give)");
		}

		internal static void Give(Player player, Command command)
		{
			List<Link> list = Leash.Mine.Where((Link l) => !l.Wild).ToList();
			if (command == Command.Whistle)
			{
				Whistle(player, list);
				return;
			}
			if (list.Count == 0)
			{
				((Character)player).Message((MessageType)2, Plugin.T("Никого на поводке", "No one on the leash"), 0, (Sprite)null, false);
				return;
			}
			if (command == Command.Attack)
			{
				Character target = Lasso.Aimed(60f);
				if ((Object)(object)target == (Object)null || target.IsPlayer() || target.IsDead() || list.Any((Link l) => (Object)(object)l.character == (Object)(object)target))
				{
					((Character)player).Message((MessageType)2, Plugin.T("Наведи прицел на цель", "Aim at a target"), 0, (Sprite)null, false);
					return;
				}
				int num = Leash.Assist(target, force: true);
				((Character)player).Message((MessageType)2, (num > 0) ? Plugin.T($"Взять! ({num})", $"Get it! ({num})") : Plugin.T("Цель дальше поводка", "The target is beyond the leash"), 0, (Sprite)null, false);
				return;
			}
			foreach (Link item in list)
			{
				Leash.SetCommand(item, command, player);
			}
			((Character)player).Message((MessageType)2, Plugin.T("Команда: ", "Command: ") + Name(command), 0, (Sprite)null, false);
		}

		private static void Whistle(Player player, List<Link> mine)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Sound(((Component)player).transform.position);
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "ChistixLeash_Whistle", new object[1] { ((Component)player).transform.position });
			}
			foreach (Link item in mine)
			{
				if (!item.Hitched && (item.Tied || item.command != Command.Heel))
				{
					Leash.SetCommand(item, Command.Heel, player);
				}
			}
			((Character)player).Message((MessageType)2, Plugin.T("Ко мне!", "Come!"), 0, (Sprite)null, false);
		}

		internal static void Register()
		{
			if (ZRoutedRpc.instance == null)
			{
				return;
			}
			ZRoutedRpc.instance.Register<Vector3>("ChistixLeash_Whistle", (Action<long, Vector3>)delegate(long sender, Vector3 pos)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)ZNet.instance != (Object)null) || sender != ZNet.GetUID())
				{
					Sound(pos);
				}
			});
		}

		private static void Sound(Vector3 pos)
		{
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_01da: Expected O, but got Unknown
			if (!Plugin.WhistleSound.Value)
			{
				return;
			}
			if ((Object)(object)clip == (Object)null)
			{
				float num = 0.75f;
				float[] array = new float[(int)(44100f * num)];
				double num2 = 0.0;
				for (int i = 0; i < array.Length; i++)
				{
					float num3 = (float)i / 44100f;
					bool num4 = num3 > 0.38f;
					float num5 = (num4 ? (num3 - 0.4f) : num3);
					float num6 = (num4 ? (2300f + 1100f * Mathf.Clamp01(num5 / 0.3f)) : (1700f + 900f * Mathf.Clamp01(num5 / 0.3f)));
					num2 += Math.PI * 2.0 * (double)num6 / 44100.0;
					float num7 = Mathf.Clamp01(num5 / 0.03f) * Mathf.Clamp01((0.34f - num5) / 0.08f);
					if (num3 > 0.34f && num3 < 0.4f)
					{
						num7 = 0f;
					}
					array[i] = (float)Math.Sin(num2) * num7 * 0.35f;
				}
				clip = AudioClip.Create("ChistixLeashWhistle", array.Length, 1, 44100, false);
				clip.SetData(array, 0);
			}
			GameObject val = new GameObject("ChistixLeashWhistle");
			val.transform.position = pos;
			AudioSource val2 = val.AddComponent<AudioSource>();
			val2.clip = clip;
			val2.spatialBlend = 1f;
			val2.minDistance = 6f;
			val2.maxDistance = 90f;
			val2.rolloffMode = (AudioRolloffMode)1;
			if ((Object)(object)AudioMan.instance != (Object)null && (Object)(object)AudioMan.instance.m_ambientMixer != (Object)null)
			{
				val2.outputAudioMixerGroup = AudioMan.instance.m_ambientMixer;
			}
			val2.Play();
			Object.Destroy((Object)val, clip.length + 0.2f);
		}
	}
	internal sealed class Feeder : MonoBehaviour
	{
		internal const string PrefabName = "chistix_hitch_feeder";

		internal const string NameToken = "$piece_chistix_feeder";

		private static GameObject prefab;

		internal static readonly List<Feeder> All = new List<Feeder>();

		public float penScale = 1f;

		private ZNetView nview;

		private Container container;

		private float timer;

		private GameObject[] piles;

		private void Awake()
		{
			nview = ((Component)this).GetComponent<ZNetView>();
			container = ((Component)this).GetComponent<Container>();
			All.Add(this);
			timer = Random.Range(1f, 3f);
			piles = new string[3] { "Fill_1", "Fill_2", "Fill_3" }.Select(delegate(string n)
			{
				Transform obj = ((Component)this).transform.Find(n);
				return (obj == null) ? null : ((Component)obj).gameObject;
			}).ToArray();
			Pens.Added(this);
		}

		private void OnDestroy()
		{
			All.Remove(this);
			Pens.Removed(this);
		}

		private void Update()
		{
			timer -= Time.deltaTime;
			if (timer > 0f)
			{
				return;
			}
			timer = 3f;
			if ((Object)(object)nview == (Object)null || !nview.IsValid() || (Object)(object)container == (Object)null)
			{
				return;
			}
			Piles();
			if (container.IsInUse())
			{
				return;
			}
			try
			{
				Feed();
			}
			catch (Exception ex)
			{
				Plugin.Warn("feeder: " + ex.Message);
			}
		}

		private void Piles()
		{
			if (piles == null || piles.All((GameObject p) => (Object)(object)p == (Object)null))
			{
				return;
			}
			Inventory inventory = container.GetInventory();
			int num