Decompiled source of Vines and Wine v0.4.1

Winemaking.dll

Decompiled 8 hours 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.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;
using Winemaking.Core;
using Winemaking.Features.Blindness;
using Winemaking.Features.Fermentation;
using Winemaking.Features.Grapes;
using Winemaking.Features.JokeWines;
using Winemaking.Features.Press;
using Winemaking.Features.SpecialWines;
using Winemaking.Features.Spoilage;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("WinemakingTestHarness")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Winemaking")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+aa4a87d52268f7899e56b96118bc4b315cfd9280")]
[assembly: AssemblyProduct("Winemaking")]
[assembly: AssemblyTitle("Winemaking")]
[assembly: AssemblyVersion("0.1.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 Winemaking
{
	[BepInPlugin("printeromg.winemaking", "Vines and Wine", "0.4.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class WinemakingPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "printeromg.winemaking";

		public const string PluginName = "Vines and Wine";

		public const string PluginVersion = "0.4.1";

		internal static ManualLogSource Log;

		private List<Feature> _features;

		private void Awake()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_features = (from t in typeof(WinemakingPlugin).Assembly.GetTypes()
				where typeof(Feature).IsAssignableFrom(t) && !t.IsAbstract
				select (Feature)Activator.CreateInstance(t) into f
				orderby f.Order
				select f).ToList();
			SyncedConfig.Hook(((BaseUnityPlugin)this).Config);
			Harmony harmony = new Harmony("printeromg.winemaking");
			foreach (Feature feature in _features)
			{
				feature.BindConfig(((BaseUnityPlugin)this).Config);
				feature.Patch(harmony);
			}
			Texts.Register(_features);
			PrefabManager.OnVanillaPrefabsAvailable += RegisterPrefabs;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Vines and Wine 0.4.1 loaded: " + string.Join(", ", _features.Select((Feature f) => f.GetType().Name))));
		}

		private void RegisterPrefabs()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterPrefabs;
			Fruit.Freeze();
			WineRecipe.Freeze();
			foreach (Feature feature in _features)
			{
				feature.RegisterPrefabs();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"registered {GrapeVariety.All.Count} grape varieties: items, cuttings, wild vines");
		}
	}
}
namespace Winemaking.Features.WildVines
{
	internal static class SitePlacement
	{
		private static bool _collecting;

		private static readonly List<ZNetView> Collected = new List<ZNetView>();

		internal static readonly SiteStats Stats = new SiteStats();

		private const float VineClearRadius = 2f;

		private static readonly Type ClearAreaType = AccessTools.Inner(typeof(ZoneSystem), "ClearArea");

		private static readonly MethodInfo FindObjects = AccessTools.Method(typeof(ZDOMan), "FindObjects", (Type[])null, (Type[])null);

		private static HashSet<int> _vineHashes;

		internal static void OnNetViewAwake(ZNetView view)
		{
			if (_collecting && (Object)(object)view != (Object)null)
			{
				Collected.Add(view);
			}
		}

		internal static bool Begin(ZoneSystem zs, Vector2s zone)
		{
			//IL_0006: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!zs.m_locationInstances.TryGetValue(zone, out var value) || value.m_placed || VineSites.ForLocation(value.m_location?.m_prefabName) == null)
			{
				return false;
			}
			Collected.Clear();
			_collecting = true;
			return true;
		}

		internal static void End(ZoneSystem zs, Vector2s zone, SpawnMode mode, List<GameObject> spawnedObjects, IList clearAreas)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_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)
			//IL_0098: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			_collecting = false;
			List<GameObject> objects = (from v in Collected
				where (Object)(object)v != (Object)null
				select ((Component)v).gameObject).ToList();
			Collected.Clear();
			if (!zs.m_locationInstances.TryGetValue(zone, out var value) || !value.m_placed)
			{
				return;
			}
			SiteRule siteRule = VineSites.ForLocation(value.m_location.m_prefabName);
			if (siteRule == null)
			{
				return;
			}
			State state = Random.state;
			try
			{
				Process(siteRule, value, zone, mode, spawnedObjects, objects, clearAreas);
			}
			catch (Exception arg)
			{
				WinemakingPlugin.Log.LogError((object)$"wild vines at {value.m_location.m_prefabName} zone {zone}: {arg}");
			}
			finally
			{
				Random.state = state;
			}
		}

		internal static void Abort()
		{
			_collecting = false;
			Collected.Clear();
		}

		internal static int Seed(Vector2s zone)
		{
			//IL_000a: 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)
			return WorldGenerator.instance.GetSeed() + zone.x * 7919 + zone.y * 6271 + 1464421957;
		}

		private static void Process(SiteRule rule, LocationInstance li, Vector2s zone, SpawnMode mode, List<GameObject> spawnedObjects, List<GameObject> objects, IList clearAreas)
		{
			//IL_0000: 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_001a: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: 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_027f: 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)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			string prefabName = li.m_location.m_prefabName;
			SiteRecord siteRecord = new SiteRecord
			{
				Location = prefabName,
				Zone = zone,
				Rule = rule.Key,
				Mode = mode
			};
			Stats.Add(siteRecord);
			Random random = new Random(Seed(zone));
			double num = random.NextDouble();
			siteRecord.Roll = (float)num;
			if (num >= (double)rule.Chance.Value)
			{
				return;
			}
			siteRecord.Requested = random.Next(rule.Min, rule.Max + 1);
			GameObject val = ((IEnumerable<GameObject>)objects).FirstOrDefault((Func<GameObject, bool>)((GameObject o) => (Object)(object)o.GetComponent<LocationProxy>() != (Object)null));
			Vector3 center = (siteRecord.Position = (((Object)(object)val != (Object)null) ? val.transform.position : li.m_position));
			if (HasVinesNear(zone, center, li.m_location.m_exteriorRadius + 2f))
			{
				siteRecord.Skipped = "vines already present";
				WinemakingPlugin.Log.LogWarning((object)$"wild vines: {prefabName} in zone {zone} already has vines nearby, skipped");
				return;
			}
			Heightmap.ForceGenerateAll();
			Physics.SyncTransforms();
			SiteContext ctx = new SiteContext
			{
				LocationName = prefabName,
				Zone = zone,
				Center = center,
				Radius = li.m_location.m_exteriorRadius,
				ClearArea = li.m_location.m_clearArea,
				Objects = objects
			};
			PlanResult planResult = SitePlanner.Plan(rule, ctx, siteRecord.Requested, random);
			siteRecord.Candidates = planResult.Candidates;
			siteRecord.Valid = planResult.Valid;
			siteRecord.Rejects = planResult.Rejects;
			GameObject prefab = ZNetScene.instance.GetPrefab(rule.Variety.WildVinePrefab);
			foreach (VinePlacement placement in planResult.Placements)
			{
				Spawn(prefab, placement, mode, spawnedObjects);
				AddClearArea(clearAreas, placement.Position);
				siteRecord.Placed.Add(placement);
			}
			string text = string.Join(", ", from p in planResult.Placements
				group p by p.Style into g
				select $"{g.Key.ToString().ToLowerInvariant()} {g.Count()}");
			WinemakingPlugin.Log.LogInfo((object)($"wild vines: {prefabName} zone {zone} ({mode}): {planResult.Placements.Count}/{siteRecord.Requested} {rule.Variety.Id} vines ({text}); " + $"{planResult.Valid} of {planResult.Candidates} spots fit"));
			if (planResult.Placements.Count < siteRecord.Requested)
			{
				WinemakingPlugin.Log.LogDebug((object)string.Format("wild vines: {0} zone {1} rejected spots: {2}", prefabName, zone, string.Join(", ", from kv in planResult.Rejects
					orderby kv.Value descending
					select $"{kv.Key} {kv.Value}")));
			}
		}

		private static void Spawn(GameObject prefab, VinePlacement p, SpawnMode mode, List<GameObject> spawnedObjects)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (int)mode == 2;
			if (flag)
			{
				ZNetView.StartGhostInit();
			}
			try
			{
				GameObject val = Object.Instantiate<GameObject>(prefab, p.Position, p.Rotation);
				val.GetComponent<ZNetView>().GetZDO().Set(WildVine.StyleKey, (int)p.Style, false);
				val.GetComponent<WildVine>().ApplyStyle(p.Style);
				if (flag)
				{
					spawnedObjects?.Add(val);
				}
			}
			finally
			{
				if (flag)
				{
					ZNetView.FinishGhostInit();
				}
			}
		}

		private static void AddClearArea(IList clearAreas, Vector3 position)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (clearAreas != null && ClearAreaType != null)
			{
				clearAreas.Add(Activator.CreateInstance(ClearAreaType, position, 2f));
			}
		}

		private static bool HasVinesNear(Vector2s zone, Vector3 center, float radius)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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)
			if (_vineHashes == null)
			{
				_vineHashes = new HashSet<int>(GrapeVariety.All.Select((GrapeVariety v) => StringExtensionMethods.GetStableHashCode(v.WildVinePrefab)));
			}
			List<ZDO> list = new List<ZDO>();
			FindObjects.Invoke(ZDOMan.instance, new object[3]
			{
				zone,
				list,
				new HashSet<SectorIndex>()
			});
			return list.Any((ZDO z) => _vineHashes.Contains(z.GetPrefab()) && Utils.DistanceXZ(z.GetPosition(), center) < radius);
		}
	}
	[HarmonyPatch]
	internal static class SitePlacementPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ZoneSystem), "PlaceLocations")]
		private static void PlaceLocationsPrefix(ZoneSystem __instance, Vector2s zoneID, out bool __state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			__state = SitePlacement.Begin(__instance, zoneID);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZoneSystem), "PlaceLocations")]
		private static void PlaceLocationsPostfix(ZoneSystem __instance, Vector2s zoneID, SpawnMode mode, List<GameObject> spawnedObjects, object clearAreas, bool __state)
		{
			//IL_0005: 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)
			if (__state)
			{
				SitePlacement.End(__instance, zoneID, mode, spawnedObjects, clearAreas as IList);
			}
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(ZoneSystem), "PlaceLocations")]
		private static void PlaceLocationsFinalizer(Exception __exception)
		{
			if (__exception != null)
			{
				SitePlacement.Abort();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZNetView), "Awake")]
		private static void NetViewAwake(ZNetView __instance)
		{
			SitePlacement.OnNetViewAwake(__instance);
		}
	}
	internal sealed class SiteRecord
	{
		public string Location;

		public string Rule;

		public Vector2s Zone;

		public Vector3 Position;

		public SpawnMode Mode;

		public float Roll;

		public int Requested;

		public int Candidates;

		public int Valid;

		public string Skipped;

		public Dictionary<string, int> Rejects = new Dictionary<string, int>();

		public readonly List<VinePlacement> Placed = new List<VinePlacement>();
	}
	internal sealed class SiteStats
	{
		public readonly List<SiteRecord> Records = new List<SiteRecord>();

		public void Add(SiteRecord r)
		{
			if (Records.Count > 20000)
			{
				Records.RemoveAt(0);
			}
			Records.Add(r);
		}
	}
	internal sealed class SiteContext
	{
		public string LocationName;

		public Vector2s Zone;

		public Vector3 Center;

		public float Radius;

		public bool ClearArea;

		public List<GameObject> Objects = new List<GameObject>();

		private HashSet<GameObject> _set;

		public HashSet<GameObject> ObjectSet => _set ?? (_set = new HashSet<GameObject>(Objects));
	}
	internal sealed class VinePlacement
	{
		public Vector3 Position;

		public Quaternion Rotation;

		public VineStyle Style;

		public string Anchor;

		public float Score;
	}
	internal sealed class PlanResult
	{
		public readonly List<VinePlacement> Placements = new List<VinePlacement>();

		public int Candidates;

		public int Valid;

		public readonly Dictionary<string, int> Rejects = new Dictionary<string, int>();

		public void Reject(string reason)
		{
			Rejects[reason] = ((!Rejects.TryGetValue(reason, out var value)) ? 1 : (value + 1));
		}
	}
	internal static class SitePlanner
	{
		private sealed class Special
		{
			public Vector3 Position;

			public float MinDistance;

			public string Kind;
		}

		private sealed class Candidate
		{
			public Vector3 Position;

			public Vector3 Forward;

			public VineStyle Style;

			public GameObject Anchor;

			public float Score;
		}

		private const float WaterMargin = 1f;

		private const float ZoneMargin = 3f;

		private const float VineWidth = 2f;

		private static int _solid;

		private static int _terrain;

		private static int Solid
		{
			get
			{
				if (_solid == 0)
				{
					return _solid = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "vehicle" });
				}
				return _solid;
			}
		}

		private static int Terrain
		{
			get
			{
				if (_terrain == 0)
				{
					return _terrain = LayerMask.GetMask(new string[1] { "terrain" });
				}
				return _terrain;
			}
		}

		public static PlanResult Plan(SiteRule rule, SiteContext ctx, int count, Random rng)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			PlanResult planResult = new PlanResult();
			List<Special> specials = CollectSpecials(ctx);
			List<Vector3> source = (from o in ctx.Objects
				where (Object)(object)o != (Object)null && rule.NearPrefabs.Contains(Utils.GetPrefabName(o))
				select o.transform.position).ToList();
			List<Candidate> list = new List<Candidate>();
			AddAnchorCandidates(rule, ctx, list);
			if (rule.AllowTrellis)
			{
				AddTrellisCandidates(ctx, list);
			}
			planResult.Candidates = list.Count;
			List<Candidate> list2 = new List<Candidate>();
			foreach (Candidate c in list)
			{
				float num = (float)rng.NextDouble() * 0.8f;
				string text = Validate(ctx, c, specials);
				if (text != null)
				{
					planResult.Reject(text);
					continue;
				}
				float num2 = Utils.DistanceXZ(c.Position, ctx.Center);
				c.Score += num + rule.EdgeBonus * Mathf.Clamp01(num2 / Mathf.Max(1f, ctx.Radius));
				if (source.Any((Vector3 n) => Utils.DistanceXZ(n, c.Position) < rule.NearRadius))
				{
					c.Score += rule.NearBonus;
				}
				list2.Add(c);
			}
			planResult.Valid = list2.Count;
			foreach (Candidate c2 in list2.OrderByDescending((Candidate candidate) => candidate.Score))
			{
				if (planResult.Placements.Count >= count)
				{
					break;
				}
				if (!planResult.Placements.Any((VinePlacement p) => Utils.DistanceXZ(p.Position, c2.Position) < rule.Separation))
				{
					planResult.Placements.Add(new VinePlacement
					{
						Position = c2.Position,
						Rotation = Quaternion.LookRotation(c2.Forward),
						Style = c2.Style,
						Anchor = (((Object)(object)c2.Anchor != (Object)null) ? Utils.GetPrefabName(c2.Anchor) : null),
						Score = c2.Score
					});
				}
			}
			return planResult;
		}

		private static void AddAnchorCandidates(SiteRule rule, SiteContext ctx, List<Candidate> list)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00ec: 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_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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: 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_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: 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_01ba: 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_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: 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_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			float num = ((rule.AnchorStyle == VineStyle.Wall) ? 0.3f : 0.34f);
			foreach (GameObject @object in ctx.Objects)
			{
				if ((Object)(object)@object == (Object)null || !rule.AnchorPieces.Contains(Utils.GetPrefabName(@object)) || !LocalBounds(@object, out var bounds))
				{
					continue;
				}
				Transform transform = @object.transform;
				bool flag = ((Bounds)(ref bounds)).size.x >= ((Bounds)(ref bounds)).size.z;
				float num2 = (flag ? ((Bounds)(ref bounds)).size.x : ((Bounds)(ref bounds)).size.z);
				float num3 = (flag ? ((Bounds)(ref bounds)).size.z : ((Bounds)(ref bounds)).size.x);
				if (num2 < 0.9f || num3 > 1.2f)
				{
					continue;
				}
				Vector3 val = Flat(flag ? transform.right : transform.forward);
				Vector3 val2 = Flat(flag ? transform.forward : transform.right);
				Vector3 val3 = transform.TransformPoint(((Bounds)(ref bounds)).center);
				float[] array = ((!(num2 >= 2.6f)) ? new float[1] : new float[2]
				{
					(0f - num2) / 4f,
					num2 / 4f
				});
				foreach (float num4 in array)
				{
					float[] array2 = new float[2] { 1f, -1f };
					foreach (float num5 in array2)
					{
						Vector3 val4 = val2 * num5;
						Vector3 val5 = val3 + val * num4 + val4 * (num3 / 2f + num);
						bool flag2 = Vector3.Dot(val4, Flat(val5 - ctx.Center)) > 0f;
						list.Add(new Candidate
						{
							Position = val5,
							Forward = val4,
							Style = rule.AnchorStyle,
							Anchor = @object,
							Score = rule.AnchorBonus + (flag2 ? rule.OutsideBonus : 0f)
						});
					}
				}
			}
		}

		private static void AddTrellisCandidates(SiteContext ctx, List<Candidate> list)
		{
			//IL_0089: 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_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)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			float[] array = new float[5] { 0.3f, 0.45f, 0.6f, 0.75f, 0.88f };
			Vector3 val = default(Vector3);
			for (int i = 0; i < array.Length; i++)
			{
				float num = array[i] * ctx.Radius;
				int num2 = Mathf.Clamp(Mathf.RoundToInt(num * 2f * (float)Math.PI / 3f), 8, 24);
				for (int j = 0; j < num2; j++)
				{
					float num3 = ((float)j + 0.5f * (float)i) / (float)num2 * 2f * (float)Math.PI;
					((Vector3)(ref val))..ctor(Mathf.Sin(num3), 0f, Mathf.Cos(num3));
					list.Add(new Candidate
					{
						Position = ctx.Center + val * num,
						Forward = -val,
						Style = VineStyle.Trellis
					});
				}
			}
		}

		private static string Validate(SiteContext ctx, Candidate c, List<Special> specials)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_017b: 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_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: 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_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: 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_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d6: Unknown result type (might be due to invalid IL or missing references)
			Vector3 zonePos = ZoneSystem.GetZonePos(ctx.Zone);
			if (Mathf.Abs(c.Position.x - zonePos.x) > 29f || Mathf.Abs(c.Position.z - zonePos.z) > 29f)
			{
				return "zone edge";
			}
			bool num;
			if (!ctx.ClearArea)
			{
				num = Utils.DistanceXZ(c.Position, ctx.Center) > ctx.Radius + 1.5f;
			}
			else
			{
				if (Mathf.Abs(c.Position.x - ctx.Center.x) > ctx.Radius - 1.2f)
				{
					goto IL_00d0;
				}
				num = Mathf.Abs(c.Position.z - ctx.Center.z) > ctx.Radius - 1.2f;
			}
			if (!num)
			{
				if (!Ground(c.Position, out var y, out var normal))
				{
					return "no ground";
				}
				c.Position.y = y;
				if (c.Style == VineStyle.Wall)
				{
					if (Vector3.Dot(c.Forward, Flat(c.Position - ctx.Center)) <= 0f)
					{
						return "inside";
					}
					if (!SnapToWall(c, y))
					{
						return "no support behind";
					}
					if (!Ground(c.Position, out y, out normal))
					{
						return "no ground";
					}
					c.Position.y = y;
				}
				if (y < ZoneSystem.instance.m_waterLevel + 1f)
				{
					return "water";
				}
				if (normal.y < Mathf.Cos((float)Math.PI / 6f))
				{
					return "slope";
				}
				Quaternion val = Quaternion.LookRotation(c.Forward);
				Vector3 val2 = val * Vector3.right;
				Vector3 forward = c.Forward;
				float num2 = y;
				float num3 = y;
				Vector3[] array = (Vector3[])(object)new Vector3[4]
				{
					val2 * 0.9f,
					-val2 * 0.9f,
					forward * 0.4f,
					-forward * 0.3f
				};
				Vector3 normal2;
				foreach (Vector3 val3 in array)
				{
					if (!Ground(c.Position + val3, out var y2, out normal2))
					{
						return "no ground";
					}
					num2 = Mathf.Min(num2, y2);
					num3 = Mathf.Max(num3, y2);
				}
				if (num3 - num2 > 0.7f)
				{
					return "uneven";
				}
				if (!Ground(c.Position + forward * 1.3f, out var y3, out normal2) || Mathf.Abs(y3 - y) > 0.8f || y3 < ZoneSystem.instance.m_waterLevel + 0.3f)
				{
					return "no footing in front";
				}
				float num4 = ((c.Style == VineStyle.Wall) ? 3.2f : 14f);
				float[] array2 = new float[3] { 0f, -0.85f, 0.85f };
				RaycastHit val4 = default(RaycastHit);
				foreach (float num5 in array2)
				{
					if (Physics.Raycast(c.Position + val2 * num5 + Vector3.up * num4, Vector3.down, ref val4, num4 - 0.2f, Solid, (QueryTriggerInteraction)1))
					{
						if (!(((RaycastHit)(ref val4)).point.y < y + 0.6f))
						{
							return "roof above";
						}
						return "covered ground";
					}
				}
				RaycastHit val5 = default(RaycastHit);
				if (Physics.Raycast(c.Position + Vector3.up * 1.2f, forward, ref val5, 3.5f, Solid, (QueryTriggerInteraction)1) && IsLocationObject(ctx, ((RaycastHit)(ref val5)).collider))
				{
					return "enclosed";
				}
				if (Blocked(c.Position + val * new Vector3(0f, 1.2f, -0.02f), new Vector3(0.95f, 1f, 0.2f), val, null))
				{
					return "body blocked";
				}
				if (Blocked(c.Position + val * new Vector3(0f, 1f, 1.12f), new Vector3(0.8f, 0.75f, 0.75f), val, null))
				{
					return "front blocked";
				}
				if (c.Style == VineStyle.Trellis && Blocked(c.Position + val * new Vector3(0f, 1f, -1f), new Vector3(0.8f, 0.75f, 0.6f), val, null))
				{
					return "back blocked";
				}
				if ((Object)(object)c.Anchor != (Object)null)
				{
					float[] array3 = ((c.Style != VineStyle.Wall) ? new float[2] { 0.6f, 1f } : new float[3] { 0.5f, 1.1f, 1.7f });
					int num6 = 0;
					array2 = array3;
					RaycastHit val6 = default(RaycastHit);
					foreach (float num7 in array2)
					{
						if (Physics.SphereCast(c.Position + Vector3.up * num7, 0.08f, -forward, ref val6, 0.85f, Solid, (QueryTriggerInteraction)1))
						{
							num6++;
						}
					}
					if ((c.Style == VineStyle.Wall) ? (num6 < array3.Length) : (num6 == 0))
					{
						return "no support behind";
					}
				}
				foreach (Special special in specials)
				{
					if (Utils.DistanceXZ(special.Position, c.Position) < special.MinDistance)
					{
						return "near " + special.Kind;
					}
				}
				Heightmap val7 = Heightmap.FindHeightmap(c.Position);
				if ((Object)(object)val7 != (Object)null && val7.GetPaintMask(c.Position).b > 0.5f)
				{
					return "path";
				}
				return null;
			}
			goto IL_00d0;
			IL_00d0:
			return "outside location";
		}

		private static bool SnapToWall(Candidate c, float ground)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ac: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = c.Position + c.Forward * 2f;
			float num = float.MaxValue;
			float[] array = new float[5] { 0.3f, 0.9f, 1.5f, 2.1f, 2.6f };
			RaycastHit val2 = default(RaycastHit);
			foreach (float num2 in array)
			{
				if (Physics.Raycast(new Vector3(val.x, ground + num2, val.z), -c.Forward, ref val2, 3.2f, Solid, (QueryTriggerInteraction)1))
				{
					num = Mathf.Min(num, ((RaycastHit)(ref val2)).distance);
				}
			}
			if (num == float.MaxValue)
			{
				return false;
			}
			c.Position = val - c.Forward * (num - 0.3f);
			return true;
		}

		private static bool IsLocationObject(SiteContext ctx, Collider col)
		{
			ZNetView componentInParent = ((Component)col).GetComponentInParent<ZNetView>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return ctx.ObjectSet.Contains(((Component)componentInParent).gameObject);
			}
			return false;
		}

		private static bool Blocked(Vector3 center, Vector3 half, Quaternion rot, GameObject ignore)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapBox(center, half, rot, Solid, (QueryTriggerInteraction)1);
			foreach (Collider val in array)
			{
				if ((Object)(object)ignore == (Object)null || !((Component)val).transform.IsChildOf(ignore.transform))
				{
					return true;
				}
			}
			return false;
		}

		private static bool Ground(Vector3 p, out float y, out Vector3 normal)
		{
			//IL_0000: 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_0012: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(new Vector3(p.x, p.y + 1000f, p.z), Vector3.down, ref val, 3000f, Terrain))
			{
				y = ((RaycastHit)(ref val)).point.y;
				normal = ((RaycastHit)(ref val)).normal;
				return true;
			}
			y = p.y;
			normal = Vector3.up;
			return false;
		}

		private static Vector3 Flat(Vector3 v)
		{
			//IL_0022: 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)
			v.y = 0f;
			if (!(((Vector3)(ref v)).sqrMagnitude > 1E-06f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref v)).normalized;
		}

		private static List<Special> CollectSpecials(SiteContext ctx)
		{
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			List<Special> list = new List<Special>();
			foreach (GameObject @object in ctx.Objects)
			{
				if (!((Object)(object)@object == (Object)null))
				{
					string text = null;
					float minDistance = 0f;
					string text2 = Utils.GetPrefabName(@object).ToLowerInvariant();
					if (Object.op_Implicit((Object)(object)@object.GetComponent<Door>()))
					{
						text = "door";
						minDistance = 3.5f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<Container>()))
					{
						text = "chest";
						minDistance = 2.5f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<CreatureSpawner>()) || Object.op_Implicit((Object)(object)@object.GetComponent<SpawnArea>()))
					{
						text = "spawner";
						minDistance = 5f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<Fireplace>()))
					{
						text = "fire";
						minDistance = 6f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<Beehive>()))
					{
						text = "beehive";
						minDistance = 3f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<Bed>()))
					{
						text = "bed";
						minDistance = 2f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<CraftingStation>()))
					{
						text = "station";
						minDistance = 2.5f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<OfferingBowl>()) || Object.op_Implicit((Object)(object)@object.GetComponent<RuneStone>()))
					{
						text = "altar";
						minDistance = 3f;
					}
					else if (Object.op_Implicit((Object)(object)@object.GetComponent<Pickable>()))
					{
						text = "pickable";
						minDistance = 1.2f;
					}
					else if (text2.Contains("stair") || text2.Contains("ladder"))
					{
						text = "stairs";
						minDistance = 2.5f;
					}
					else if (text2.Contains("gate"))
					{
						text = "gate";
						minDistance = 3.5f;
					}
					else if (text2.Contains("totem"))
					{
						text = "totem";
						minDistance = 2.5f;
					}
					if (text != null)
					{
						list.Add(new Special
						{
							Position = @object.transform.position,
							MinDistance = minDistance,
							Kind = text
						});
					}
				}
			}
			return list;
		}

		internal static bool LocalBounds(GameObject root, out Bounds bounds)
		{
			//IL_0001: 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_006f: 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_00ba: 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_00c3: 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_00cd: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a5: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//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)
			bounds = default(Bounds);
			bool flag = false;
			Transform transform = root.transform;
			Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>();
			foreach (Collider val in componentsInChildren)
			{
				if (val.isTrigger || !val.enabled)
				{
					continue;
				}
				Transform val2 = ((Component)val).transform;
				Collider val3 = val;
				BoxCollider val4 = (BoxCollider)(object)((val3 is BoxCollider) ? val3 : null);
				Vector3 val6;
				Vector3 size;
				if (val4 == null)
				{
					MeshCollider val5 = (MeshCollider)(object)((val3 is MeshCollider) ? val3 : null);
					Bounds bounds2;
					if (val5 != null && (Object)(object)val5.sharedMesh != (Object)null)
					{
						bounds2 = val5.sharedMesh.bounds;
						val6 = ((Bounds)(ref bounds2)).center;
						bounds2 = val5.sharedMesh.bounds;
						size = ((Bounds)(ref bounds2)).size;
					}
					else
					{
						bounds2 = val.bounds;
						val6 = transform.InverseTransformPoint(((Bounds)(ref bounds2)).center);
						bounds2 = val.bounds;
						size = ((Bounds)(ref bounds2)).size;
						val2 = transform;
					}
				}
				else
				{
					val6 = val4.center;
					size = val4.size;
				}
				for (int j = 0; j < 8; j++)
				{
					Vector3 val7 = val6 + Vector3.Scale(size * 0.5f, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
					Vector3 val8 = transform.InverseTransformPoint(val2.TransformPoint(val7));
					if (!flag)
					{
						bounds = new Bounds(val8, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val8);
					}
				}
			}
			return flag;
		}
	}
	internal enum VineStyle
	{
		Trellis,
		Fence,
		Wall
	}
	internal static class VineModels
	{
		public const string StylesRoot = "styles";

		public const string BunchesRoot = "bunches";

		private static readonly Quaternion Face = Quaternion.Euler(0f, 90f, 0f);

		public static void Build(GameObject prefab, GrapeVariety v)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			GameObject val = new GameObject("styles");
			val.transform.SetParent(prefab.transform, false);
			GameObject val2 = new GameObject("bunches");
			val2.transform.SetParent(prefab.transform, false);
			VineStyle[] array = new VineStyle[3]
			{
				VineStyle.Trellis,
				VineStyle.Fence,
				VineStyle.Wall
			};
			for (int i = 0; i < array.Length; i++)
			{
				VineStyle vineStyle = array[i];
				GameObject val3 = new GameObject(vineStyle.ToString());
				val3.transform.SetParent(val.transform, false);
				GameObject val4 = new GameObject(vineStyle.ToString());
				val4.transform.SetParent(val2.transform, false);
				switch (vineStyle)
				{
				case VineStyle.Trellis:
					BuildTrellis(val3.transform, val4.transform, v);
					break;
				case VineStyle.Fence:
					BuildFence(val3.transform, val4.transform, v);
					break;
				case VineStyle.Wall:
					BuildWall(val3.transform, val4.transform, v);
					break;
				}
				bool active = vineStyle == VineStyle.Trellis;
				val3.SetActive(active);
				val4.SetActive(active);
			}
		}

		public static void Apply(Transform root, VineStyle style)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			string[] array = new string[2] { "styles", "bunches" };
			foreach (string text in array)
			{
				Transform val = root.Find(text);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				foreach (Transform item in val)
				{
					Transform val2 = item;
					bool flag = ((Object)val2).name == style.ToString();
					if (((Component)val2).gameObject.activeSelf != flag)
					{
						((Component)val2).gameObject.SetActive(flag);
					}
				}
			}
		}

		private static void BuildTrellis(Transform m, Transform fruit, GrapeVariety v)
		{
			//IL_0010: 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_005a: 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_008e: 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_00e0: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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_018e: 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_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: 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_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: 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_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: 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_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			VineKit.AddStake(m, new Vector3(-0.95f, 0f, -0.12f), 1.85f, 0.3f);
			VineKit.AddStake(m, new Vector3(0.95f, 0f, -0.12f), 1.8f, 0.3f);
			VineKit.AddRail(m, new Vector3(-1.08f, 1.63f, -0.12f), new Vector3(1.08f, 1.6f, -0.12f), 0.7f);
			VineKit.AddRail(m, new Vector3(-1.05f, 0.95f, -0.12f), new Vector3(1.05f, 0.97f, -0.12f), 0.5f);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, 1.58f, -0.1f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[5]
			{
				new Vector3(0.05f, -0.05f, 0.02f),
				new Vector3(0.1f, 0.4f, 0f),
				new Vector3(-0.02f, 0.85f, -0.05f),
				new Vector3(0.06f, 1.25f, -0.08f),
				val
			}, 0.6f, 0.42f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[3]
			{
				val,
				new Vector3(-0.45f, 1.67f, -0.08f),
				new Vector3(-0.97f, 1.64f, -0.1f)
			}, 0.38f, 0.22f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[3]
			{
				val,
				new Vector3(0.5f, 1.65f, -0.08f),
				new Vector3(0.97f, 1.6f, -0.1f)
			}, 0.38f, 0.22f);
			VineKit.AddLeaves(m, v, VineKit.LeafPart.Full, new Vector3(-0.05f, 1.02f, -0.1f), Face, 0.74f);
			VineKit.AddLeaves(m, v, VineKit.LeafPart.Full, new Vector3(0.12f, 1.2f, -0.16f), Face * Quaternion.Euler(0f, 180f, 0f), 0.6f);
			VineKit.AddBunches(fruit, v, (IEnumerable<Vector3>)(object)new Vector3[5]
			{
				new Vector3(-0.74f, 1.3f, 0.12f),
				new Vector3(-0.3f, 1.18f, 0.15f),
				new Vector3(0.18f, 1.28f, 0.13f),
				new Vector3(0.62f, 1.15f, 0.15f),
				new Vector3(0.9f, 1.32f, 0.12f)
			}, Vector3.forward);
			VineKit.AddBunches(fruit, v, (IEnumerable<Vector3>)(object)new Vector3[2]
			{
				new Vector3(-0.45f, 1.25f, -0.34f),
				new Vector3(0.4f, 1.2f, -0.34f)
			}, Vector3.back);
			AddCollider(m, new Vector3(0f, 1.1f, -0.1f), new Vector3(2.2f, 2.1f, 0.7f));
		}

		private static void BuildFence(Transform m, Transform fruit, GrapeVariety v)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0101: 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_0124: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_015b: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: 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_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			VineKit.AddStake(m, new Vector3(0.24f, 0f, -0.1f), 1.45f, 0.24f);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, 1.32f, -0.14f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[5]
			{
				new Vector3(0.02f, -0.05f, 0.02f),
				new Vector3(0.08f, 0.35f, 0f),
				new Vector3(-0.02f, 0.75f, -0.05f),
				new Vector3(0.04f, 1.08f, -0.1f),
				val
			}, 0.58f, 0.42f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[3]
			{
				val,
				new Vector3(-0.45f, 1.4f, -0.14f),
				new Vector3(-0.92f, 1.35f, -0.16f)
			}, 0.36f, 0.2f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[3]
			{
				val,
				new Vector3(0.46f, 1.38f, -0.14f),
				new Vector3(0.9f, 1.33f, -0.16f)
			}, 0.36f, 0.2f);
			VineKit.AddLeaves(m, v, VineKit.LeafPart.Full, new Vector3(0f, 0.8f, -0.14f), Face, 0.66f);
			VineKit.AddLeaves(m, v, VineKit.LeafPart.Full, new Vector3(-0.2f, 0.95f, -0.2f), Face * Quaternion.Euler(0f, 180f, 0f), 0.52f);
			VineKit.AddBunches(fruit, v, (IEnumerable<Vector3>)(object)new Vector3[4]
			{
				new Vector3(-0.7f, 1.08f, 0.1f),
				new Vector3(-0.27f, 0.98f, 0.13f),
				new Vector3(0.2f, 1.06f, 0.12f),
				new Vector3(0.62f, 0.97f, 0.13f)
			}, Vector3.forward);
			AddCollider(m, new Vector3(0f, 0.95f, -0.05f), new Vector3(2f, 1.8f, 0.55f));
		}

		private static void BuildWall(Transform m, Transform fruit, GrapeVariety v)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0064: 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_006c: 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_0087: 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_008f: 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_00ae: 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_00c9: 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)
			//IL_0102: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0157: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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_018e: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: 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)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(-0.04f, 1.05f, -0.08f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0.03f, 1.8f, -0.14f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[5]
			{
				new Vector3(0f, -0.05f, 0.05f),
				new Vector3(0.07f, 0.5f, -0.02f),
				val,
				new Vector3(0.05f, 1.45f, -0.12f),
				val2
			}, 0.62f, 0.42f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[3]
			{
				val2,
				new Vector3(-0.45f, 1.84f, -0.16f),
				new Vector3(-0.8f, 1.74f, -0.17f)
			}, 0.34f, 0.2f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[3]
			{
				val2,
				new Vector3(0.42f, 1.8f, -0.16f),
				new Vector3(0.75f, 1.68f, -0.17f)
			}, 0.34f, 0.2f);
			VineKit.AddTrunk(m, (IList<Vector3>)(object)new Vector3[3]
			{
				val,
				new Vector3(-0.3f, 1.2f, -0.12f),
				new Vector3(-0.62f, 1.3f, -0.15f)
			}, 0.3f, 0.18f);
			VineKit.AddLeaves(m, v, VineKit.LeafPart.Full, new Vector3(0f, 0.72f, -0.2f), Face, 0.85f);
			VineKit.AddLeaves(m, v, VineKit.LeafPart.Full, new Vector3(0.3f, 1.55f, -0.24f), Face * Quaternion.Euler(0f, 180f, 0f), 0.62f);
			VineKit.AddBunches(fruit, v, (IEnumerable<Vector3>)(object)new Vector3[5]
			{
				new Vector3(-0.66f, 1.38f, 0.1f),
				new Vector3(-0.22f, 1.2f, 0.12f),
				new Vector3(0.24f, 1.42f, 0.1f),
				new Vector3(0.68f, 1.24f, 0.1f),
				new Vector3(0.02f, 1.62f, 0.08f)
			}, Vector3.forward);
			AddCollider(m, new Vector3(0f, 1.3f, -0.06f), new Vector3(2f, 2.5f, 0.45f));
		}

		private static void AddCollider(Transform parent, Vector3 center, Vector3 size)
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			GameObject val = new GameObject("collider")
			{
				layer = LayerMask.NameToLayer("piece_nonsolid")
			};
			val.transform.SetParent(parent, false);
			BoxCollider obj = val.AddComponent<BoxCollider>();
			obj.center = center;
			obj.size = size;
		}

		public static IEnumerable<Transform> Children(Transform t)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			List<Transform> list = new List<Transform>();
			foreach (Transform item2 in t)
			{
				Transform item = item2;
				list.Add(item);
			}
			return list;
		}
	}
	internal sealed class SiteRule
	{
		public string Key;

		public GrapeVariety Variety;

		public string DefaultLocations;

		public float DefaultChance;

		public int DefaultMin;

		public int DefaultMax;

		public string Description;

		public string DescriptionEn;

		public VineStyle AnchorStyle;

		public string[] AnchorPieces = Array.Empty<string>();

		public bool AllowTrellis = true;

		public float AnchorBonus = 3f;

		public float OutsideBonus = 0.5f;

		public string[] NearPrefabs = Array.Empty<string>();

		public float NearRadius = 6f;

		public float NearBonus = 1f;

		public float EdgeBonus;

		public float Separation = 5f;

		public ConfigEntry<string> Locations;

		public ConfigEntry<float> Chance;

		public ConfigEntry<int> VinesMin;

		public ConfigEntry<int> VinesMax;

		public int Min => Math.Min(VinesMin.Value, VinesMax.Value);

		public int Max => Math.Max(VinesMin.Value, VinesMax.Value);
	}
	internal static class VineSites
	{
		public static readonly List<SiteRule> Rules = new List<SiteRule>
		{
			new SiteRule
			{
				Key = "MeadowsFarm",
				Variety = GrapeVariety.Light,
				DefaultLocations = "WoodFarm1",
				DefaultChance = 1f,
				DefaultMin = 2,
				DefaultMax = 3,
				Description = "заброшенная ферма Лугов",
				DescriptionEn = "abandoned Meadows farm",
				AnchorStyle = VineStyle.Fence,
				AnchorPieces = new string[2] { "wood_fence", "stake_wall" },
				NearPrefabs = new string[2] { "RaspberryBush", "BlueberryBush" },
				NearRadius = 7f,
				NearBonus = 1f,
				Separation = 6f
			},
			new SiteRule
			{
				Key = "MeadowsVillage",
				Variety = GrapeVariety.Light,
				DefaultLocations = "WoodVillage1,WoodVillage2",
				DefaultChance = 0.75f,
				DefaultMin = 2,
				DefaultMax = 4,
				Description = "деревня Лугов (часто с драуграми)",
				DescriptionEn = "Meadows village (often with draugr)",
				AnchorStyle = VineStyle.Fence,
				AnchorPieces = new string[2] { "wood_fence", "stake_wall" },
				Separation = 6f,
				EdgeBonus = 0.5f
			},
			new SiteRule
			{
				Key = "MeadowsHouse",
				Variety = GrapeVariety.Light,
				DefaultLocations = "WoodHouse1,WoodHouse2,WoodHouse3,WoodHouse4,WoodHouse5,WoodHouse6,WoodHouse7,WoodHouse8,WoodHouse9,WoodHouse10,WoodHouse11,WoodHouse12,WoodHouse13",
				DefaultChance = 0.15f,
				DefaultMin = 1,
				DefaultMax = 1,
				Description = "одиночные заброшенные домики Лугов",
				DescriptionEn = "single abandoned Meadows houses",
				AnchorStyle = VineStyle.Fence,
				AnchorPieces = new string[2] { "wood_fence", "stake_wall" },
				Separation = 4f
			},
			new SiteRule
			{
				Key = "BlackForestTower",
				Variety = GrapeVariety.Dark,
				DefaultLocations = "StoneTowerRuins03,StoneTowerRuins07,StoneTowerRuins08,StoneTowerRuins09,StoneTowerRuins10",
				DefaultChance = 0.55f,
				DefaultMin = 1,
				DefaultMax = 2,
				Description = "каменные башни-руины Чёрного леса; лоза растёт у уцелевшей стены снаружи",
				DescriptionEn = "ruined stone towers of the Black Forest; the vine grows outside by a surviving wall",
				AnchorStyle = VineStyle.Wall,
				AnchorPieces = new string[3] { "stone_wall_2x1", "stone_wall_4x2", "stone_wall_1x1" },
				AllowTrellis = false,
				OutsideBonus = 2f,
				Separation = 3f
			},
			new SiteRule
			{
				Key = "PlainsFulingCamp",
				Variety = GrapeVariety.Sun,
				DefaultLocations = "GoblinCamp2",
				DefaultChance = 0.65f,
				DefaultMin = 2,
				DefaultMax = 3,
				Description = "поселение фулингов на Равнинах; лоза на ограде или своей опоре у ячменя, на краю лагеря",
				DescriptionEn = "Fuling camp in the Plains; the vine grows on the fence or on its own support by the barley, at the camp edge",
				AnchorStyle = VineStyle.Fence,
				AnchorPieces = new string[3] { "goblin_woodwall_1m", "goblin_woodwall_2m", "goblin_woodwall_2m_ribs" },
				NearPrefabs = new string[1] { "Pickable_Barley_Wild" },
				NearRadius = 9f,
				NearBonus = 1.5f,
				EdgeBonus = 1f,
				Separation = 6f
			}
		};

		private static Dictionary<string, SiteRule> _byLocation = new Dictionary<string, SiteRule>();

		public static IEnumerable<string> AllLocations => _byLocation.Keys;

		public static SiteRule ForLocation(string prefabName)
		{
			if (prefabName == null || !_byLocation.TryGetValue(prefabName, out var value))
			{
				return null;
			}
			return value;
		}

		public static void Bind(ConfigFile config)
		{
			foreach (SiteRule rule in Rules)
			{
				string text = "Sites." + rule.Key;
				string id = rule.Variety.Id;
				rule.Locations = ConfigFileExtensions.BindConfig<string>(config, text, "Locations", rule.DefaultLocations, Texts.Cfg("Vanilla locations (comma-separated prefab names) where the wild " + id + " vine grows: " + rule.DescriptionEn + ". Applies only to locations that have not appeared in the world yet.", "Ванильные локации (имена prefab-ов через запятую), у которых растёт дикая лоза сорта «" + id + "»: " + rule.Description + ". Действует только на локации, которые ещё не появились в мире."), true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
				float defaultChance = rule.DefaultChance;
				string text2 = Texts.Cfg("Chance that one instance of such a location gets vines (0 = never, 1 = always).", "Вероятность, что у одного экземпляра такой локации вырастут лозы (0 — никогда, 1 — всегда).");
				AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f);
				rule.Chance = ConfigFileExtensions.BindConfig<float>(config, text, "Chance", defaultChance, text2, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
				int defaultMin = rule.DefaultMin;
				string text3 = Texts.Cfg("Minimum vines at a location when the chance succeeds.", "Минимум лоз у локации, если шанс сработал.");
				val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10);
				rule.VinesMin = ConfigFileExtensions.BindConfig<int>(config, text, "VinesMin", defaultMin, text3, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
				int defaultMax = rule.DefaultMax;
				string text4 = Texts.Cfg("Maximum vines at a location. With fewer suitable spots there will be fewer vines.", "Максимум лоз у локации. Если подходящих мест меньше, лоз будет меньше.");
				val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10);
				rule.VinesMax = ConfigFileExtensions.BindConfig<int>(config, text, "VinesMax", defaultMax, text4, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			}
			Rebuild();
			SyncedConfig.Changed += Rebuild;
		}

		private static void Rebuild()
		{
			Dictionary<string, SiteRule> dictionary = new Dictionary<string, SiteRule>();
			foreach (SiteRule rule in Rules)
			{
				foreach (string item in from s in (rule.Locations.Value ?? "").Split(new char[3] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries)
					select s.Trim())
				{
					if (!dictionary.ContainsKey(item))
					{
						dictionary[item] = rule;
					}
				}
			}
			_byLocation = dictionary;
		}
	}
	internal sealed class WildVinesFeature : Feature
	{
		public override int Order => 10;

		public override void BindConfig(ConfigFile config)
		{
			WildVineConfig.Bind(config);
			VineSites.Bind(config);
		}

		public override void Patch(Harmony harmony)
		{
			harmony.PatchAll(typeof(PickablePatches));
			harmony.PatchAll(typeof(SitePlacementPatches));
		}

		public override void RegisterPrefabs()
		{
			WildVines.Register();
		}

		public override void AddTranslations(Dictionary<string, string> en, Dictionary<string, string> ru)
		{
			en["winemaking_wildvine_light"] = "Wild pale vine";
			en["winemaking_wildvine_dark"] = "Wild dark vine";
			en["winemaking_wildvine_sun"] = "Wild sun vine";
			en["winemaking_vine_regrows"] = "<color=#aaaaaa>Picked. Grapes will ripen in $1</color>";
			en["winemaking_time_soon"] = "less than an hour";
			en["winemaking_time_h"] = "about $1 h";
			en["winemaking_time_dh"] = "about $1 d $2 h";
			ru["winemaking_wildvine_light"] = "Дикая светлая лоза";
			ru["winemaking_wildvine_dark"] = "Дикая тёмная лоза";
			ru["winemaking_wildvine_sun"] = "Дикая солнечная лоза";
			ru["winemaking_vine_regrows"] = "<color=#aaaaaa>Собрано. Грозди созреют через $1</color>";
			ru["winemaking_time_soon"] = "меньше часа";
			ru["winemaking_time_h"] = "≈ $1 ч";
			ru["winemaking_time_dh"] = "≈ $1 д $2 ч";
		}
	}
	public class WildVine : MonoBehaviour
	{
		public string VarietyId;

		internal static readonly int StyleKey = StringExtensionMethods.GetStableHashCode("winemaking_vine_style");

		internal GrapeVariety Variety => GrapeVariety.ById(VarietyId);

		internal VineStyle Style { get; private set; }

		public static float DayLengthSeconds
		{
			get
			{
				if (!((Object)(object)EnvMan.instance != (Object)null))
				{
					return 1800f;
				}
				return EnvMan.instance.m_dayLengthSec;
			}
		}

		internal float CurrentRegrowMinutes => RegrowMinutes(WildVineConfig.For(Variety).RegrowDays.Value);

		private void Awake()
		{
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			ZDO val = ((component != null) ? component.GetZDO() : null);
			ApplyStyle((val != null) ? ((VineStyle)val.GetInt(StyleKey, 0)) : VineStyle.Trellis);
		}

		internal void ApplyStyle(VineStyle style)
		{
			if (!Enum.IsDefined(typeof(VineStyle), style))
			{
				style = VineStyle.Trellis;
			}
			Style = style;
			VineModels.Apply(((Component)this).transform, style);
		}

		public static float RegrowMinutes(float days)
		{
			return Mathf.Max(0.05f, days) * DayLengthSeconds / 60f;
		}
	}
	[HarmonyPatch(typeof(Pickable))]
	internal static class PickablePatches
	{
		private static readonly DropTable EmptyDrops = new DropTable();

		private static readonly FieldRef<Pickable, long> PickedTimeField = AccessTools.FieldRefAccess<Pickable, long>("m_pickedTime");

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void Awake(Pickable __instance)
		{
			WildVine wildVine = default(WildVine);
			if (((Component)__instance).TryGetComponent<WildVine>(ref wildVine))
			{
				__instance.m_respawnTimeMinutes = wildVine.CurrentRegrowMinutes;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("RPC_Pick")]
		private static bool RPC_Pick(Pickable __instance)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_00e3: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			WildVine wildVine = default(WildVine);
			if (!((Component)__instance).TryGetComponent<WildVine>(ref wildVine))
			{
				return true;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner())
			{
				return true;
			}
			if (__instance.GetPicked() || component.GetZDO().GetBool(ZDOVars.s_picked, __instance.m_defaultPicked))
			{
				return false;
			}
			WildVineConfig.VarietyConfig varietyConfig = WildVineConfig.For(wildVine.Variety);
			int num = Mathf.Min(varietyConfig.HarvestMin.Value, varietyConfig.HarvestMax.Value);
			int num2 = Mathf.Max(varietyConfig.HarvestMin.Value, varietyConfig.HarvestMax.Value);
			__instance.m_amount = Random.Range(num, num2 + 1);
			__instance.m_respawnTimeMinutes = wildVine.CurrentRegrowMinutes;
			float value = varietyConfig.CuttingChance.Value;
			__instance.m_extraDrops = (DropTable)((value <= 0f) ? ((object)EmptyDrops) : ((object)new DropTable
			{
				m_dropMin = 1,
				m_dropMax = 1,
				m_dropChance = value,
				m_drops = 
				{
					new DropData
					{
						m_item = GrapeItems.Cuttings[wildVine.VarietyId].ItemPrefab,
						m_stackMin = 1,
						m_stackMax = 1,
						m_weight = 1f,
						m_dontScale = true
					}
				}
			}));
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("UpdateRespawn")]
		private static void UpdateRespawn(Pickable __instance)
		{
			WildVine wildVine = default(WildVine);
			if (!((Component)__instance).TryGetComponent<WildVine>(ref wildVine))
			{
				return;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				long num = component.GetZDO().GetLong(ZDOVars.s_pickedTime, 0L);
				if (num > 1)
				{
					PickedTimeField.Invoke(__instance) = num;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("ShouldRespawn")]
		private static void ShouldRespawn(Pickable __instance)
		{
			WildVine wildVine = default(WildVine);
			if (((Component)__instance).TryGetComponent<WildVine>(ref wildVine))
			{
				__instance.m_respawnTimeMinutes = wildVine.CurrentRegrowMinutes;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(Pickable __instance, ref string __result)
		{
			WildVine wildVine = default(WildVine);
			if (__instance.GetPicked() && ((Component)__instance).TryGetComponent<WildVine>(ref wildVine))
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid() && !((Object)(object)ZNet.instance == (Object)null))
				{
					long num = component.GetZDO().GetLong(ZDOVars.s_pickedTime, 0L);
					double num2 = ((num > 1) ? (ZNet.instance.GetTime() - new DateTime(num)).TotalSeconds : 0.0);
					double realSeconds = Math.Max(0.0, (double)wildVine.CurrentRegrowMinutes * 60.0 - num2);
					__result = Localization.instance.Localize(__instance.GetHoverName() + "\n$winemaking_vine_regrows", new string[1] { FormatGameTime(realSeconds) });
				}
			}
		}

		internal static string FormatGameTime(double realSeconds)
		{
			int num = Mathf.CeilToInt((float)(realSeconds / (double)WildVine.DayLengthSeconds * 24.0));
			if (num <= 1)
			{
				return Localization.instance.Localize("$winemaking_time_soon");
			}
			int num2 = num / 24;
			int num3 = num % 24;
			if (num2 <= 0)
			{
				return Localization.instance.Localize("$winemaking_time_h", new string[1] { num3.ToString() });
			}
			return Localization.instance.Localize("$winemaking_time_dh", new string[2]
			{
				num2.ToString(),
				num3.ToString()
			});
		}
	}
	internal static class WildVineConfig
	{
		internal sealed class VarietyConfig
		{
			public ConfigEntry<int> HarvestMin;

			public ConfigEntry<int> HarvestMax;

			public ConfigEntry<float> RegrowDays;

			public ConfigEntry<float> CuttingChance;
		}

		private static readonly Dictionary<string, VarietyConfig> Varieties = new Dictionary<string, VarietyConfig>();

		public static VarietyConfig For(GrapeVariety v)
		{
			return Varieties[v.Id];
		}

		public static void Bind(ConfigFile config)
		{
			foreach (GrapeVariety item in GrapeVariety.All)
			{
				string text = "Grape." + item.Id;
				VarietyConfig varietyConfig = new VarietyConfig();
				int harvestMin = item.HarvestMin;
				string text2 = Texts.Cfg("Minimum bunches per harvest.", "Минимум гроздей за сбор.");
				AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50);
				varietyConfig.HarvestMin = ConfigFileExtensions.BindConfig<int>(config, text, "HarvestMin", harvestMin, text2, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
				int harvestMax = item.HarvestMax;
				string text3 = Texts.Cfg("Maximum bunches per harvest.", "Максимум гроздей за сбор.");
				val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50);
				varietyConfig.HarvestMax = ConfigFileExtensions.BindConfig<int>(config, text, "HarvestMax", harvestMax, text3, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
				float regrowDays = item.RegrowDays;
				string text4 = Texts.Cfg("Game days (world time) until the vine bears fruit again.", "Через сколько игровых дней лоза снова плодоносит (по времени мира).");
				val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 100f);
				varietyConfig.RegrowDays = ConfigFileExtensions.BindConfig<float>(config, text, "RegrowDays", regrowDays, text4, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
				float cuttingChance = item.CuttingChance;
				string text5 = Texts.Cfg("Chance of getting one cutting per harvest (one roll per harvest).", "Шанс получить один черенок за сбор лозы (один бросок на сбор).");
				val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f);
				varietyConfig.CuttingChance = ConfigFileExtensions.BindConfig<float>(config, text, "CuttingChance", cuttingChance, text5, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
				VarietyConfig value = varietyConfig;
				Varieties[item.Id] = value;
			}
		}
	}
	internal static class WildVines
	{
		public static void Register()
		{
			foreach (GrapeVariety item in GrapeVariety.All)
			{
				CreatePrefab(item);
			}
		}

		private static void CreatePrefab(GrapeVariety v)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(v.WildVinePrefab, "RaspberryBush");
			string[] array = new string[2] { "model", "viewblock" };
			foreach (string text in array)
			{
				Transform val2 = val.transform.Find(text);
				if ((Object)(object)val2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val2).gameObject);
				}
			}
			Object.DestroyImmediate((Object)(object)val.GetComponent<DropOnDestroyed>());
			Object.DestroyImmediate((Object)(object)val.GetComponent<Destructible>());
			val.transform.localScale = Vector3.one;
			VineModels.Build(val, v);
			Pickable component = val.GetComponent<Pickable>();
			component.m_itemPrefab = GrapeItems.Grapes[v.Id].ItemPrefab;
			component.m_amount = v.HarvestMin;
			component.m_overrideName = v.WildVineToken;
			component.m_respawnTimeMinutes = WildVine.RegrowMinutes(v.RegrowDays);
			component.m_hideWhenPicked = ((Component)val.transform.Find("bunches")).gameObject;
			component.m_maxLevelBonusChance = 0f;
			component.m_extraDrops = new DropTable();
			component.m_spawnOffset = 0.9f;
			val.AddComponent<WildVine>().VarietyId = v.Id;
			PrefabManager.Instance.AddPrefab(val);
		}
	}
}
namespace Winemaking.Features.Spoilage
{
	internal static class SpoilageEffects
	{
		internal static int BlindApplied;

		internal static float LastBlindSeconds;

		internal static float LastBlindCircle;

		internal static int BlindRemoved;

		internal static int PukeAdded;

		internal static float LastPoisonAfterResistance;

		private static readonly Action<Character, float, short> AddPoisonDamage = CreateAddPoison();

		private static readonly Dictionary<float, float> InputCache = new Dictionary<float, float>();

		public static StatusEffect PukeEffect => SpoiledWine.PukeEffect;

		public static SE_Poison PoisonTemplate
		{
			get
			{
				if (!((Object)(object)ObjectDB.instance != (Object)null))
				{
					return null;
				}
				StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(SEMan.s_statusEffectPoison);
				return (SE_Poison)(object)((statusEffect is SE_Poison) ? statusEffect : null);
			}
		}

		public static bool IsSick(Player player)
		{
			StatusEffect pukeEffect = PukeEffect;
			SEMan val = (((Object)(object)player != (Object)null) ? ((Character)player).GetSEMan() : null);
			if ((Object)(object)pukeEffect != (Object)null && val != null)
			{
				if (!val.HaveStatusEffect(pukeEffect.NameHash()))
				{
					return val.HaveStatusEffectCategory(pukeEffect.m_category);
				}
				return true;
			}
			return false;
		}

		public static bool Apply(Player player, string id, int stars)
		{
			if ((Object)(object)player == (Object)null || ((Character)player).IsDead())
			{
				return false;
			}
			SpoiledEffect spoiledEffect = SpoilageTable.For(id, stars);
			if (spoiledEffect == null)
			{
				WinemakingPlugin.Log.LogWarning((object)("spoilage: unknown spoiled wine id '" + id + "', no effect applied"));
				return false;
			}
			SEMan sEMan = ((Character)player).GetSEMan();
			StatusEffect pukeEffect = PukeEffect;
			if (spoiledEffect.Puke && (Object)(object)pukeEffect == (Object)null)
			{
				WinemakingPlugin.Log.LogError((object)"spoilage: vanilla Pukeberries effect not found, the wine can't be drunk");
				return false;
			}
			if (spoiledEffect.Puke && (Object)(object)sEMan.AddStatusEffect(pukeEffect, false, 0, 0f, (short)(-1)) != (Object)null)
			{
				PukeAdded++;
			}
			if (spoiledEffect.Poison > 0f)
			{
				ApplyPoison(player, PoisonInput(spoiledEffect.Poison));
			}
			if (spoiledEffect.CarryWeight != 0f)
			{
				SE_SpoiledWine sE_SpoiledWine = Add(sEMan, SpoilageStatus.HeavyHash, spoiledEffect, spoiledEffect.CarrySeconds);
				if ((Object)(object)sE_SpoiledWine != (Object)null)
				{
					((SE_Stats)sE_SpoiledWine).m_addMaxCarryWeight = spoiledEffect.CarryWeight;
				}
			}
			if (spoiledEffect.Speed != 0f)
			{
				SE_SpoiledWine sE_SpoiledWine2 = Add(sEMan, SpoilageStatus.SlowHash, spoiledEffect, spoiledEffect.SpeedSeconds);
				if ((Object)(object)sE_SpoiledWine2 != (Object)null)
				{
					((SE_Stats)sE_SpoiledWine2).m_speedModifier = spoiledEffect.Speed;
				}
			}
			if (spoiledEffect.StaminaRegen > 0f)
			{
				SE_SpoiledWine sE_SpoiledWine3 = Add(sEMan, SpoilageStatus.SluggishHash, spoiledEffect, spoiledEffect.StaminaSeconds);
				if ((Object)(object)sE_SpoiledWine3 != (Object)null)
				{
					((SE_Stats)sE_SpoiledWine3).m_staminaRegenMultiplier = 1f - spoiledEffect.StaminaRegen;
					((StatusEffect)sE_SpoiledWine3).m_icon = SpoilageIcons.Lethargy;
				}
			}
			if (spoiledEffect.Malaise > 0f)
			{
				SE_SpoiledWine sE_SpoiledWine4 = Add(sEMan, SpoilageStatus.MalaiseHash, spoiledEffect, spoiledEffect.MalaiseSeconds);
				if ((Object)(object)sE_SpoiledWine4 != (Object)null)
				{
					((SE_Stats)sE_SpoiledWine4).m_staminaRegenMultiplier = 1f - spoiledEffect.Malaise;
					((StatusEffect)sE_SpoiledWine4).m_icon = SpoilageIcons.Weakness;
				}
			}
			if (spoiledEffect.BlindSeconds > 0f)
			{
				BlindApplied++;
				LastBlindSeconds = spoiledEffect.BlindSeconds;
				LastBlindCircle = spoiledEffect.BlindCircle;
				Winemaking.Features.Blindness.Blindness.Apply(player, spoiledEffect.BlindSeconds, spoiledEffect.BlindCircle);
			}
			WinemakingPlugin.Log.LogInfo((object)("spoilage: " + player.GetPlayerName() + " got " + Describe(spoiledEffect)));
			return true;
		}

		private static SE_SpoiledWine Add(SEMan seman, int hash, SpoiledEffect e, float seconds)
		{
			SE_SpoiledWine sE_SpoiledWine = SpoilageStatus.Template(hash);
			if ((Object)(object)sE_SpoiledWine == (Object)null)
			{
				WinemakingPlugin.Log.LogError((object)"spoilage: status effects are not registered");
				return null;
			}
			seman.RemoveStatusEffect(hash, true);
			if (!(seman.AddStatusEffect((StatusEffect)(object)sE_SpoiledWine, false, 0, 0f, (short)(-1)) is SE_SpoiledWine sE_SpoiledWine2))
			{
				return null;
			}
			sE_SpoiledWine2.m_wineId = e.Id;
			sE_SpoiledWine2.m_wineStars = e.Stars;
			((StatusEffect)sE_SpoiledWine2).m_ttl = seconds;
			((StatusEffect)sE_SpoiledWine2).m_tooltip = "$winemaking_wine_name_" + e.Id;
			return sE_SpoiledWine2;
		}

		public static float ApplyPoison(Player player, float damage)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			HitData val = new HitData();
			val.m_damage.m_poison = damage;
			DamageModifier val2 = default(DamageModifier);
			val.ApplyResistance(((Character)player).GetDamageModifiers((WeakSpot)null), ref val2);
			float num = (LastPoisonAfterResistance = val.m_damage.m_poison);
			if (num <= 0f)
			{
				return 0f;
			}
			if (AddPoisonDamage != null)
			{
				AddPoisonDamage((Character)(object)player, num, val.m_variant);
			}
			else
			{
				SEMan sEMan = ((Character)player).GetSEMan();
				StatusEffect statusEffect = sEMan.GetStatusEffect(SEMan.s_statusEffectPoison);
				object obj = ((object)((statusEffect is SE_Poison) ? statusEffect : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/);
				if (obj != null)
				{
					((SE_Poison)obj).AddDamage(num);
				}
			}
			return num;
		}

		public static void RemoveWineStatuses(Player player)
		{
			if (!((Object)(object)player == (Object)null))
			{
				SEMan sEMan = ((Character)player).GetSEMan();
				int[] hashes = SpoilageStatus.Hashes;
				foreach (int num in hashes)
				{
					sEMan.RemoveStatusEffect(num, true);
				}
				BlindRemoved++;
				Winemaking.Features.Blindness.Blindness.Remove(player);
			}
		}

		public static void PoisonForecast(float damage, out float seconds, out float total, out int ticks)
		{
			SE_Poison poisonTemplate = PoisonTemplate;
			float num = (((Object)(object)poisonTemplate != (Object)null) ? poisonTemplate.m_baseTTL : 1f);
			float num2 = (((Object)(object)poisonTemplate != (Object)null) ? poisonTemplate.m_TTLPerDamagePlayer : 5f);
			float num3 = (((Object)(object)poisonTemplate != (Object)null) ? poisonTemplate.m_TTLPower : 0.5f);
			float num4 = (((Object)(object)poisonTemplate != (Object)null && poisonTemplate.m_damageInterval > 0f) ? poisonTemplate.m_damageInterval : 1f);
			seconds = num + Mathf.Pow(damage * num2, num3);
			int num5 = Mathf.Max(1, (int)(seconds / num4));
			float num6 = ((Time.fixedDeltaTime > 0f) ? Time.fixedDeltaTime : 0.02f);
			float num7 = 0f;
			float num8 = 0f;
			ticks = 0;
			for (int i = 0; i < 100000; i++)
			{
				num7 += num6;
				num8 -= num6;
				if (num8 <= 0f)
				{
					num8 = num4;
					ticks++;
				}
				if (num7 > seconds)
				{
					break;
				}
			}
			total = damage / (float)num5 * (float)ticks;
		}

		public static float PoisonInput(float total)
		{
			if (total <= 0f)
			{
				return 0f;
			}
			if (InputCache.TryGetValue(total, out var value))
			{
				return value;
			}
			float best = total;
			float bestTotal = -1f;
			for (int i = 1; i <= 60; i++)
			{
				for (int j = i; j <= i + 2; j++)
				{
					Try(total * (float)i / (float)j);
				}
			}
			int num = Mathf.CeilToInt(total * 0.5f / 0.005f);
			for (int k = 0; k <= num; k++)
			{
				Try(total - (float)k * 0.005f);
			}
			if ((Object)(object)PoisonTemplate != (Object)null)
			{
				InputCache[total] = best;
			}
			return best;
			void Try(float d)
			{
				if (!(d <= 0f))
				{
					PoisonForecast(d, out var _, out var total2, out var _);
					if (total2 <= total + 0.001f && total2 > bestTotal)
					{
						bestTotal = total2;
						best = d;
					}
				}
			}
		}

		public static string Describe(SpoiledEffect e)
		{
			List<string> list = new List<string>();
			if (e.Puke)
			{
				list.Add("puke");
			}
			if (e.Poison > 0f)
			{
				list.Add($"poison total {e.Poison} (input {PoisonInput(e.Poison):0.###}, after resistance {LastPoisonAfterResistance:0.###})");
			}
			if (e.CarryWeight != 0f)
			{
				list.Add($"carry weight {e.CarryWeight} for {e.CarrySeconds} s");
			}
			if (e.Speed != 0f)
			{
				list.Add($"speed {e.Speed * 100f:0}% for {e.SpeedSeconds} s");
			}
			if (e.StaminaRegen > 0f)
			{
				list.Add($"stamina regen -{e.StaminaRegen * 100f:0}% for {e.StaminaSeconds} s");
			}
			if (e.Malaise > 0f)
			{
				list.Add($"malaise: stamina regen -{e.Malaise * 100f:0}% for {e.MalaiseSeconds} s");
			}
			if (e.BlindSeconds > 0f)
			{
				list.Add($"blindness {e.BlindSeconds} s, circle {e.BlindCircle * 100f:0}%");
			}
			return string.Format("{0} stars {1}: {2}", e.Id, e.Stars, string.Join(", ", list));
		}

		private static Action<Character, float, short> CreateAddPoison()
		{
			try
			{
				return AccessTools.MethodDelegate<Action<Character, float, short>>(AccessTools.Method(typeof(Character), "AddPoisonDamage", new Type[2]
				{
					typeof(float),
					typeof(short)
				}, (Type[])null), (object)null, true);
			}
			catch (Exception ex)
			{
				WinemakingPlugin.Log.LogWarning((object)("spoilage: Character.AddPoisonDamage not found (" + ex.Message + "); using SE_Poison directly"));
				return null;
			}
		}
	}
	internal sealed class SpoilageFeature : Feature
	{
		public override int Order => 65;

		public override void RegisterPrefabs()
		{
			SpoilageStatus.Register();
		}

		public override void AddTranslations(Dictionary<string, string> en, Dictionary<string, string> ru)
		{
			SpoilageTexts.Add(en, ru);
		}
	}
	internal static class SpoilageIcons
	{
		public const string WinePrefab = "Winemaking_WineSpoiled";

		private static Func<Texture2D, byte[], bool, bool> _loadImage;

		private static Sprite _slow;

		private static Sprite _weight;

		private static Sprite _lethargy;

		private static Sprite _weakness;

		private static bool _loaded;

		public static Sprite Slow
		{
			get
			{
				LoadOnce();
				return _slow;
			}
		}

		public static Sprite Weight
		{
			get
			{
				LoadOnce();
				return _weight;
			}
		}

		public static Sprite Lethargy
		{
			get
			{
				LoadOnce();
				return _lethargy;
			}
		}

		public static Sprite Weakness
		{
			get
			{
				LoadOnce();
				return _weakness;
			}
		}

		public static Sprite WineBottle
		{
			get
			{
				GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("Winemaking_WineSpoiled") : null);
				Sprite[] array = ((!((Object)(object)val != (Object)null)) ? null : val.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_icons);
				if (array == null)
				{
					return null;
				}
				Sprite[] array2 = array