Decompiled source of FireFront v1.0.4

plugins/FireFront.dll

Decompiled 17 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FireFront.Commands;
using FireFront.Config;
using FireFront.Fire;
using FireFront.Utils;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SharedMedia;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("FireFront")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyInformationalVersion("1.0.4+b53e56c2001aff39224b336b2c836c03d0b27b2d")]
[assembly: AssemblyProduct("FireFront")]
[assembly: AssemblyTitle("FireFront")]
[assembly: AssemblyVersion("1.0.4.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 SharedMedia
{
	public static class ProceduralTextures
	{
		public sealed class CrackField
		{
			public int W;

			public int H;

			public float[] Crack;

			public float[] Plate;

			public int[] PlateId;

			public float[] Edge;
		}

		public struct CharParams
		{
			public float PlateLight;

			public float PlateDark;

			public float GrainKeep;

			public float AshAmount;

			public float AshR;

			public float AshG;

			public float AshB;

			public float PocketDarken;

			public static CharParams Default => new CharParams
			{
				PlateLight = 0.13f,
				PlateDark = 0.03f,
				GrainKeep = 0.7f,
				AshAmount = 0.14f,
				AshR = 0.66f,
				AshG = 0.64f,
				AshB = 0.6f,
				PocketDarken = 0.25f
			};
		}

		private static uint[] s_crcTable;

		public static float Hash(int x, int y, int seed)
		{
			int num = (x * -1918454973) ^ (y * -669632447) ^ (seed * -887442657);
			int num2 = (num ^ (num >>> 15)) * 739982445;
			int num3 = (num2 ^ (num2 >>> 12)) * 695872825;
			return (float)(uint)((num3 ^ (num3 >>> 15)) & 0xFFFFFF) / 16777216f;
		}

		private static float Quintic(float t)
		{
			return t * t * t * (t * (t * 6f - 15f) + 10f);
		}

		public static float ValueNoise(float u, float v, int px, int py, int seed)
		{
			float num = u * (float)px;
			float num2 = v * (float)py;
			int num3 = (int)Math.Floor(num);
			int num4 = (int)Math.Floor(num2);
			float t = num - (float)num3;
			float t2 = num2 - (float)num4;
			int a = num3 + 1;
			int a2 = num4 + 1;
			int x = Mod(num3, px);
			int x2 = Mod(a, px);
			int y = Mod(num4, py);
			int y2 = Mod(a2, py);
			float num5 = Quintic(t);
			float num6 = Quintic(t2);
			float num7 = Hash(x, y, seed);
			float num8 = Hash(x2, y, seed);
			float num9 = Hash(x, y2, seed);
			float num10 = Hash(x2, y2, seed);
			float num11 = num7 + (num8 - num7) * num5;
			float num12 = num9 + (num10 - num9) * num5;
			return num11 + (num12 - num11) * num6;
		}

		public static float Fbm(float u, float v, int px, int py, int octaves, int seed, float gain = 0.5f)
		{
			float num = 0f;
			float num2 = 1f;
			float num3 = 0f;
			int num4 = Math.Max(1, px);
			int num5 = Math.Max(1, py);
			for (int i = 0; i < octaves; i++)
			{
				num += ValueNoise(u, v, num4, num5, seed + i * 131) * num2;
				num3 += num2;
				num2 *= gain;
				num4 *= 2;
				num5 *= 2;
			}
			if (!(num3 > 0f))
			{
				return 0f;
			}
			return num / num3;
		}

		public static void Worley(float u, float v, int cx, int cy, int seed, float jitter, out float d1, out float d2, out int cellId)
		{
			float num = u * (float)cx;
			float num2 = v * (float)cy;
			int num3 = (int)Math.Floor(num);
			int num4 = (int)Math.Floor(num2);
			d1 = float.MaxValue;
			d2 = float.MaxValue;
			cellId = 0;
			float num5 = 1f;
			float num6 = (float)cx / (float)cy;
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					int num7 = num3 + j;
					int num8 = num4 + i;
					int num9 = Mod(num7, cx);
					int num10 = Mod(num8, cy);
					float num11 = (float)num7 + 0.5f + (Hash(num9, num10, seed) - 0.5f) * jitter;
					float num12 = (float)num8 + 0.5f + (Hash(num9, num10, seed + 7919) - 0.5f) * jitter;
					float num13 = (num - num11) * num5;
					float num14 = (num2 - num12) * num6;
					float num15 = (float)Math.Sqrt(num13 * num13 + num14 * num14);
					if (num15 < d1)
					{
						d2 = d1;
						d1 = num15;
						cellId = num10 * cx + num9;
					}
					else if (num15 < d2)
					{
						d2 = num15;
					}
				}
			}
		}

		private static int Mod(int a, int m)
		{
			int num = a % m;
			if (num >= 0)
			{
				return num;
			}
			return num + m;
		}

		public static float Smooth(float a, float b, float x)
		{
			if (b <= a)
			{
				if (!(x >= b))
				{
					return 0f;
				}
				return 1f;
			}
			float num = Mathf.Clamp01((x - a) / (b - a));
			return num * num * (3f - 2f * num);
		}

		public static CrackField BuildCrackField(int w, int h, int cellsX, int cellsY, int seed, float width = 0.1f, float widthNoise = 0.05f, float fineWeight = 0.55f, float warp = 0.05f)
		{
			CrackField crackField = new CrackField
			{
				W = w,
				H = h,
				Crack = new float[w * h],
				Plate = new float[w * h],
				PlateId = new int[w * h],
				Edge = new float[w * h]
			};
			int cx = cellsX * 2 + 1;
			int cy = cellsY * 2 + 1;
			for (int i = 0; i < h; i++)
			{
				float num = ((float)i + 0.5f) / (float)h;
				for (int j = 0; j < w; j++)
				{
					float num2 = ((float)j + 0.5f) / (float)w;
					float u = num2 + (Fbm(num2, num, 3, 3, 2, seed + 901) - 0.5f) * warp;
					float v = num + (Fbm(num2, num, 3, 3, 2, seed + 907) - 0.5f) * warp;
					Worley(u, v, cellsX, cellsY, seed, 0.65f, out var d, out var d2, out var cellId);
					float num3 = d2 - d;
					float val = width + widthNoise * (Fbm(num2, num, 9, 9, 2, seed + 3) - 0.5f) * 2f;
					float num4 = 1f - Smooth(0f, Math.Max(0.02f, val), num3);
					Worley(u, v, cx, cy, seed + 17, 0.8f, out var d3, out var d4, out var _);
					float num5 = 1f - Smooth(0f, width * 0.45f, d4 - d3);
					num5 *= (1f - num4) * (0.6f + 0.4f * Fbm(num2, num, 5, 5, 2, seed + 11));
					int num6 = i * w + j;
					crackField.Crack[num6] = Mathf.Clamp01(Math.Max(num4, num5 * fineWeight));
					crackField.Plate[num6] = Mathf.Clamp01(num3 / 0.55f) * (1f - num4);
					crackField.PlateId[num6] = cellId;
					crackField.Edge[num6] = num3;
				}
			}
			return crackField;
		}

		public static float[] PocketField(int w, int h, float coverage, int seed, int period = 3, float softness = 0.1f)
		{
			float[] array = new float[w * h];
			coverage = Mathf.Clamp01(coverage);
			if (coverage <= 0f)
			{
				return array;
			}
			float[] array2 = new float[w * h];
			for (int i = 0; i < h; i++)
			{
				float v = ((float)i + 0.5f) / (float)h;
				for (int j = 0; j < w; j++)
				{
					float u = ((float)j + 0.5f) / (float)w;
					array2[i * w + j] = Fbm(u, v, period, period, 3, seed, 0.55f);
				}
			}
			if (coverage >= 1f)
			{
				for (int k = 0; k < array2.Length; k++)
				{
					array[k] = 1f;
				}
				return array;
			}
			List<float> list = new List<float>(4096);
			int num = Math.Max(1, array2.Length / 4096);
			for (int l = 0; l < array2.Length; l += num)
			{
				list.Add(array2[l]);
			}
			list.Sort();
			float num2 = list[Mathf.Clamp((int)((1f - coverage) * (float)(list.Count - 1)), 0, list.Count - 1)];
			for (int m = 0; m < array2.Length; m++)
			{
				array[m] = Smooth(num2, num2 + softness, array2[m]);
			}
			return array;
		}

		public static Color32[] CharredAlbedo(Color32[] src, int w, int h, CrackField cf, float[] pocket, int seed, CharParams p)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_0275: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[w * h];
			for (int i = 0; i < h; i++)
			{
				float v = ((float)i + 0.5f) / (float)h;
				for (int j = 0; j < w; j++)
				{
					int num = i * w + j;
					float u = ((float)j + 0.5f) / (float)w;
					float num2 = 0.5f;
					byte b = byte.MaxValue;
					if (src != null)
					{
						Color32 val = src[num];
						num2 = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 255f;
						b = val.a;
					}
					float num3 = 0.5f + (num2 - 0.5f) * p.GrainKeep;
					float num4 = p.PlateDark + (p.PlateLight - p.PlateDark) * num3;
					float num5 = ((cf != null) ? cf.Plate[num] : 0.5f);
					float num6 = ((cf != null) ? (0.75f + 0.5f * Hash(cf.PlateId[num], 3, seed + 5)) : 1f);
					float num7 = num4 * ((0.85f + 0.3f * num5) * num6);
					float num8 = num7 * 1f;
					float num9 = num7 * 0.93f;
					float num10 = num7 * 0.86f;
					float num11 = ((cf != null) ? cf.Crack[num] : 0f);
					float num12 = 1f - 0.85f * num11;
					num8 *= num12;
					num9 *= num12;
					num10 *= num12;
					float x = Fbm(u, v, 20, 20, 3, seed + 41, 0.6f);
					float num13 = ((cf != null) ? (0.5f + Hash(cf.PlateId[num], 9, seed + 13)) : 1f);
					float num14 = Smooth(1f - p.AshAmount * 1.8f * num13, 1f - p.AshAmount * 0.3f * num13, x) * (1f - num11) * num5 * num5;
					num8 += (p.AshR - num8) * num14;
					num9 += (p.AshG - num9) * num14;
					num10 += (p.AshB - num10) * num14;
					float num15 = ((pocket != null) ? pocket[num] : 0f);
					float num16 = 1f - p.PocketDarken * num15;
					num8 *= num16;
					num9 *= num16;
					num10 *= num16;
					array[num] = new Color32(ToByte(num8), ToByte(num9), ToByte(num10), b);
				}
			}
			return array;
		}

		public static Color32[] EmberMask(int w, int h, CrackField cf, float[] pocket, int seed, float dotDensity = 0.25f, float crackGlow = 1f, float glowWidth = 0.3f, float[] region = null)
		{
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[w * h];
			int cx = 40;
			int cy = 40;
			for (int i = 0; i < h; i++)
			{
				float v = ((float)i + 0.5f) / (float)h;
				for (int j = 0; j < w; j++)
				{
					int num = i * w + j;
					float u = ((float)j + 0.5f) / (float)w;
					float num2 = ((pocket != null) ? pocket[num] : 1f);
					float num3 = ((cf != null) ? cf.Crack[num] : 0f);
					float num4 = 0.4f + 0.6f * Fbm(u, v, 7, 7, 3, seed + 5);
					float x = ((cf != null) ? cf.Edge[num] : 1f);
					float num5 = 1f - Smooth(0f, glowWidth, x);
					float num6 = (num5 * num5 * 0.85f + num3 * 0.35f) * num4 * crackGlow;
					Worley(u, v, cx, cy, seed + 23, 0.9f, out var d, out var _, out var cellId);
					float num7 = ((Hash(cellId, 77, seed) < dotDensity) ? 1f : 0f);
					float num8 = (1f - Smooth(0.04f, 0.15f, d)) * num7 * (1f - num3 * 0.6f) * (0.5f + 0.5f * Hash(cellId, 5, seed + 3));
					float num9 = Mathf.Clamp01(num6 + num8 * 0.75f) * num2 * num2;
					if (region != null)
					{
						num9 *= region[num];
					}
					float num10 = num9 * num9;
					float v2 = 1f * num9;
					float v3 = (0.28f + 0.5f * num10) * num9;
					float v4 = (0.04f + 0.3f * num10) * num9;
					array[num] = new Color32(ToByte(v2), ToByte(v3), ToByte(v4), byte.MaxValue);
				}
			}
			return array;
		}

		public static float[] CharHeight(CrackField cf, int w, int h, int seed, float crackDepth = 1f, float domeHeight = 0.6f, float grit = 0.12f)
		{
			float[] array = new float[w * h];
			for (int i = 0; i < h; i++)
			{
				float v = ((float)i + 0.5f) / (float)h;
				for (int j = 0; j < w; j++)
				{
					int num = i * w + j;
					float num2 = (Fbm(((float)j + 0.5f) / (float)w, v, 32, 32, 2, seed + 61) - 0.5f) * 2f;
					array[num] = domeHeight * cf.Plate[num] - crackDepth * cf.Crack[num] + grit * num2;
				}
			}
			return array;
		}

		public static Color32[] NormalFromHeight(float[] height, int w, int h, float strength, Color32[] baseNormalAG = null, float baseWeight = 1f)
		{
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[w * h];
			for (int i = 0; i < h; i++)
			{
				int num = (i - 1 + h) % h;
				int num2 = (i + 1) % h;
				for (int j = 0; j < w; j++)
				{
					int num3 = (j - 1 + w) % w;
					int num4 = (j + 1) % w;
					float num5 = (height[i * w + num4] - height[i * w + num3]) * 2f + (height[num2 * w + num4] - height[num2 * w + num3]) + (height[num * w + num4] - height[num * w + num3]);
					float num6 = (height[num2 * w + j] - height[num * w + j]) * 2f + (height[num2 * w + num4] - height[num * w + num4]) + (height[num2 * w + num3] - height[num * w + num3]);
					float num7 = (0f - num5) * strength / 8f;
					float num8 = (0f - num6) * strength / 8f;
					float num9 = 1f;
					if (baseNormalAG != null)
					{
						Color32 val = baseNormalAG[i * w + j];
						float num10 = (float)(int)val.a / 255f * 2f - 1f;
						float num11 = (float)(int)val.g / 255f * 2f - 1f;
						float val2 = (float)Math.Sqrt(Math.Max(0f, 1f - num10 * num10 - num11 * num11));
						num7 += num10 * baseWeight;
						num8 += num11 * baseWeight;
						num9 *= Math.Max(0.2f, val2);
					}
					float num12 = (float)Math.Sqrt(num7 * num7 + num8 * num8 + num9 * num9);
					num7 /= num12;
					num8 /= num12;
					array[i * w + j] = new Color32(byte.MaxValue, ToByte(num8 * 0.5f + 0.5f), byte.MaxValue, ToByte(num7 * 0.5f + 0.5f));
				}
			}
			return array;
		}

		public static Color32[] PreviewShade(Color32[] albedo, Color32[] normalAG, Color32[] emission, float emissionScale, int w, int h)
		{
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[w * h];
			float num = -0.45f;
			float num2 = 0.55f;
			float num3 = 0.7f;
			float num4 = (float)Math.Sqrt(num * num + num2 * num2 + num3 * num3);
			num /= num4;
			num2 /= num4;
			num3 /= num4;
			for (int i = 0; i < w * h; i++)
			{
				float num5 = 0f;
				float num6 = 0f;
				float num7 = 1f;
				if (normalAG != null)
				{
					num5 = (float)(int)normalAG[i].a / 255f * 2f - 1f;
					num6 = (float)(int)normalAG[i].g / 255f * 2f - 1f;
					num7 = (float)Math.Sqrt(Math.Max(0f, 1f - num5 * num5 - num6 * num6));
				}
				float num8 = Math.Max(0f, num5 * num + num6 * num2 + num7 * num3);
				float num9 = 0.18f + 0.82f * num8;
				float num10 = ((albedo != null) ? ((float)(int)albedo[i].r / 255f) : 0.5f);
				float num11 = ((albedo != null) ? ((float)(int)albedo[i].g / 255f) : 0.5f);
				float num12 = ((albedo != null) ? ((float)(int)albedo[i].b / 255f) : 0.5f);
				num10 *= num9;
				num11 *= num9;
				num12 *= num9;
				if (emission != null)
				{
					float num13 = (float)(int)emission[i].a / 255f * emissionScale;
					num10 += (float)(int)emission[i].r / 255f * num13;
					num11 += (float)(int)emission[i].g / 255f * num13;
					num12 += (float)(int)emission[i].b / 255f * num13;
				}
				array[i] = new Color32(ToByte(num10), ToByte(num11), ToByte(num12), byte.MaxValue);
			}
			return array;
		}

		public static float[] OpaqueBlockMask(Color32[] src, int w, int h, int erode, byte opaque = 250, float keepFractionOfLargest = 0.4f)
		{
			float[] array = ErodedOpaque(src, w, h, erode, opaque);
			if (!(keepFractionOfLargest > 0f))
			{
				return array;
			}
			return KeepLargestComponents(array, w, h, keepFractionOfLargest);
		}

		private static float[] ErodedOpaque(Color32[] src, int w, int h, int erode, byte opaque)
		{
			float[] array = new float[w * h];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = ((src[i].a >= opaque) ? 1f : 0f);
			}
			if (erode <= 0)
			{
				return array;
			}
			float[] array2 = new float[w * h];
			for (int j = 0; j < h; j++)
			{
				for (int k = 0; k < w; k++)
				{
					float num = 1f;
					for (int l = -erode; l <= erode; l++)
					{
						int num2 = k + l;
						if (num2 < 0 || num2 >= w)
						{
							num = 0f;
							break;
						}
						if (array[j * w + num2] < 1f)
						{
							num = 0f;
							break;
						}
					}
					array2[j * w + k] = num;
				}
			}
			for (int m = 0; m < w; m++)
			{
				for (int n = 0; n < h; n++)
				{
					float num3 = 1f;
					for (int num4 = -erode; num4 <= erode; num4++)
					{
						int num5 = n + num4;
						if (num5 < 0 || num5 >= h)
						{
							num3 = 0f;
							break;
						}
						if (array2[num5 * w + m] < 1f)
						{
							num3 = 0f;
							break;
						}
					}
					array[n * w + m] = num3;
				}
			}
			return array;
		}

		public static float[] KeepLargestComponents(float[] mask, int w, int h, float fractionOfLargest)
		{
			int[] array = new int[w * h];
			List<int> list = new List<int> { 0 };
			Stack<int> stack = new Stack<int>();
			for (int i = 0; i < mask.Length; i++)
			{
				if (mask[i] <= 0f || array[i] != 0)
				{
					continue;
				}
				int count = list.Count;
				list.Add(0);
				stack.Push(i);
				array[i] = count;
				while (stack.Count > 0)
				{
					int num = stack.Pop();
					list[count]++;
					int num2 = num % w;
					int num3 = num / w;
					if (num2 > 0 && mask[num - 1] > 0f && array[num - 1] == 0)
					{
						array[num - 1] = count;
						stack.Push(num - 1);
					}
					if (num2 < w - 1 && mask[num + 1] > 0f && array[num + 1] == 0)
					{
						array[num + 1] = count;
						stack.Push(num + 1);
					}
					if (num3 > 0 && mask[num - w] > 0f && array[num - w] == 0)
					{
						array[num - w] = count;
						stack.Push(num - w);
					}
					if (num3 < h - 1 && mask[num + w] > 0f && array[num + w] == 0)
					{
						array[num + w] = count;
						stack.Push(num + w);
					}
				}
			}
			int num4 = 0;
			for (int j = 1; j < list.Count; j++)
			{
				if (list[j] > num4)
				{
					num4 = list[j];
				}
			}
			float[] array2 = new float[w * h];
			if (num4 == 0)
			{
				return array2;
			}
			for (int k = 0; k < mask.Length; k++)
			{
				array2[k] = ((array[k] != 0 && (float)list[array[k]] >= (float)num4 * fractionOfLargest) ? 1f : 0f);
			}
			return array2;
		}

		public static Color32[] SootBlot(int size, int seed, float sootTone = 0.3f, float feather = 0.45f)
		{
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[size * size];
			for (int i = 0; i < size; i++)
			{
				float num = ((float)i + 0.5f) / (float)size;
				for (int j = 0; j < size; j++)
				{
					float num2 = ((float)j + 0.5f) / (float)size;
					float num3 = num2 - 0.5f;
					float num4 = num - 0.5f;
					float num5 = (float)Math.Atan2(num4, num3);
					float num6 = 0.78f + 0.22f * Fbm(0.5f + 0.5f * (float)Math.Cos(num5), 0.5f + 0.5f * (float)Math.Sin(num5), 3, 3, 2, seed);
					float x = (float)Math.Sqrt(num3 * num3 + num4 * num4) * 2f / num6;
					float num7 = 1f - Smooth(1f - feather, 1f, x);
					float num8 = 0.75f + 0.25f * Fbm(num2, num, 6, 6, 3, seed + 7);
					float num9 = num7 * num8;
					float num10 = 1f - (1f - sootTone) * num9;
					float num11 = Smooth(0.74f, 0.92f, Fbm(num2, num, 14, 14, 3, seed + 19, 0.55f)) * num7 * 0.5f;
					num10 += (0.85f - num10) * num11 * Mathf.Clamp01((0.85f - num10 > 0f) ? 1f : 0f);
					array[i * size + j] = new Color32(ToByte(num10), ToByte(num10 * 0.96f + 0.04f * (1f - num9)), ToByte(num10 * 0.92f + 0.08f * (1f - num9)), byte.MaxValue);
				}
			}
			return array;
		}

		public static byte ToByte(float v)
		{
			return (byte)Mathf.Clamp(Mathf.RoundToInt(v * 255f), 0, 255);
		}

		public static float SrgbToLinear(float c)
		{
			if (!(c <= 0.04045f))
			{
				return (float)Math.Pow(((double)c + 0.055) / 1.055, 2.4);
			}
			return c / 12.92f;
		}

		public static float LinearToSrgb(float c)
		{
			if (!(c <= 0.0031308f))
			{
				return 1.055f * (float)Math.Pow(c, 5.0 / 12.0) - 0.055f;
			}
			return c * 12.92f;
		}

		public static Color32[] Resample(Color32[] src, int sw, int sh, int dw, int dh)
		{
			//IL_0039: 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)
			Color32[] array = (Color32[])(object)new Color32[dw * dh];
			for (int i = 0; i < dh; i++)
			{
				int num = Math.Min(sh - 1, i * sh / dh);
				for (int j = 0; j < dw; j++)
				{
					array[i * dw + j] = src[num * sw + Math.Min(sw - 1, j * sw / dw)];
				}
			}
			return array;
		}

		public static byte[] EncodePng(int w, int h, Color32[] px)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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)
			byte[] array = new byte[h * (w * 4 + 1)];
			int num = 0;
			for (int num2 = h - 1; num2 >= 0; num2--)
			{
				array[num++] = 0;
				for (int i = 0; i < w; i++)
				{
					Color32 val = px[num2 * w + i];
					array[num++] = val.r;
					array[num++] = val.g;
					array[num++] = val.b;
					array[num++] = val.a;
				}
			}
			byte[] body = Zlib(array);
			using MemoryStream memoryStream = new MemoryStream();
			memoryStream.Write(new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }, 0, 8);
			byte[] array2 = new byte[13];
			WriteBE(array2, 0, (uint)w);
			WriteBE(array2, 4, (uint)h);
			array2[8] = 8;
			array2[9] = 6;
			array2[10] = 0;
			array2[11] = 0;
			array2[12] = 0;
			Chunk(memoryStream, "IHDR", array2);
			Chunk(memoryStream, "IDAT", body);
			Chunk(memoryStream, "IEND", new byte[0]);
			return memoryStream.ToArray();
		}

		public static Color32[] DecodePng(byte[] data, out int w, out int h)
		{
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			if (data.Length < 8 || data[0] != 137 || data[1] != 80)
			{
				throw new InvalidDataException("not a PNG");
			}
			int num = 8;
			w = 0;
			h = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			MemoryStream memoryStream = new MemoryStream();
			int num5;
			int num6;
			for (; num + 8 <= data.Length; num = num6 + num5 + 4)
			{
				num5 = (int)ReadBE(data, num);
				string text = Encoding.ASCII.GetString(data, num + 4, 4);
				num6 = num + 8;
				switch (text)
				{
				case "IHDR":
					w = (int)ReadBE(data, num6);
					h = (int)ReadBE(data, num6 + 4);
					num2 = data[num6 + 8];
					num3 = data[num6 + 9];
					num4 = data[num6 + 12];
					continue;
				case "IDAT":
					memoryStream.Write(data, num6, num5);
					continue;
				default:
					continue;
				case "IEND":
					break;
				}
				break;
			}
			if (num2 != 8)
			{
				throw new InvalidDataException("only 8-bit PNGs are supported (got " + num2 + ")");
			}
			if (num4 != 0)
			{
				throw new InvalidDataException("interlaced PNGs are not supported");
			}
			int num7 = num3 switch
			{
				6 => 4, 
				4 => 2, 
				2 => 3, 
				0 => 1, 
				_ => -1, 
			};
			if (num7 < 0)
			{
				throw new InvalidDataException("unsupported PNG colour type " + num3);
			}
			byte[] array = memoryStream.ToArray();
			byte[] array2;
			using (MemoryStream stream = new MemoryStream(array, 2, array.Length - 2))
			{
				using DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress);
				using MemoryStream memoryStream2 = new MemoryStream();
				deflateStream.CopyTo(memoryStream2);
				array2 = memoryStream2.ToArray();
			}
			int num8 = w * num7;
			byte[] array3 = new byte[num8];
			byte[] array4 = new byte[num8];
			Color32[] array5 = (Color32[])(object)new Color32[w * h];
			int num9 = 0;
			Color32 val = default(Color32);
			for (int i = 0; i < h; i++)
			{
				int num10 = array2[num9++];
				Array.Copy(array2, num9, array4, 0, num8);
				num9 += num8;
				for (int j = 0; j < num8; j++)
				{
					int num11 = ((j >= num7) ? array4[j - num7] : 0);
					int num12 = array3[j];
					int num13 = ((j >= num7) ? array3[j - num7] : 0);
					int num14 = array4[j];
					switch (num10)
					{
					case 1:
						num14 += num11;
						break;
					case 2:
						num14 += num12;
						break;
					case 3:
						num14 += (num11 + num12) / 2;
						break;
					case 4:
					{
						int num15 = num11 + num12 - num13;
						int num16 = Math.Abs(num15 - num11);
						int num17 = Math.Abs(num15 - num12);
						int num18 = Math.Abs(num15 - num13);
						num14 += ((num16 <= num17 && num16 <= num18) ? num11 : ((num17 <= num18) ? num12 : num13));
						break;
					}
					}
					array4[j] = (byte)num14;
				}
				int num19 = h - 1 - i;
				for (int k = 0; k < w; k++)
				{
					int num20 = k * num7;
					switch (num7)
					{
					case 1:
						((Color32)(ref val))..ctor(array4[num20], array4[num20], array4[num20], byte.MaxValue);
						break;
					case 2:
						((Color32)(ref val))..ctor(array4[num20], array4[num20], array4[num20], array4[num20 + 1]);
						break;
					case 3:
						((Color32)(ref val))..ctor(array4[num20], array4[num20 + 1], array4[num20 + 2], byte.MaxValue);
						break;
					default:
						((Color32)(ref val))..ctor(array4[num20], array4[num20 + 1], array4[num20 + 2], array4[num20 + 3]);
						break;
					}
					array5[num19 * w + k] = val;
				}
				byte[] array6 = array3;
				array3 = array4;
				array4 = array6;
			}
			return array5;
		}

		private static byte[] Zlib(byte[] raw)
		{
			using MemoryStream memoryStream = new MemoryStream();
			memoryStream.WriteByte(120);
			memoryStream.WriteByte(156);
			using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
			{
				deflateStream.Write(raw, 0, raw.Length);
			}
			uint num = 1u;
			uint num2 = 0u;
			for (int i = 0; i < raw.Length; i++)
			{
				num = (num + raw[i]) % 65521;
				num2 = (num2 + num) % 65521;
			}
			uint num3 = (num2 << 16) | num;
			memoryStream.WriteByte((byte)(num3 >> 24));
			memoryStream.WriteByte((byte)(num3 >> 16));
			memoryStream.WriteByte((byte)(num3 >> 8));
			memoryStream.WriteByte((byte)num3);
			return memoryStream.ToArray();
		}

		private static void Chunk(Stream s, string type, byte[] body)
		{
			byte[] bytes = Encoding.ASCII.GetBytes(type);
			byte[] array = new byte[4];
			WriteBE(array, 0, (uint)body.Length);
			s.Write(array, 0, 4);
			s.Write(bytes, 0, 4);
			s.Write(body, 0, body.Length);
			uint crc = Crc32(bytes, uint.MaxValue);
			crc = Crc32(body, crc) ^ 0xFFFFFFFFu;
			byte[] array2 = new byte[4];
			WriteBE(array2, 0, crc);
			s.Write(array2, 0, 4);
		}

		private static uint Crc32(byte[] buf, uint crc)
		{
			if (s_crcTable == null)
			{
				s_crcTable = new uint[256];
				for (uint num = 0u; num < 256; num++)
				{
					uint num2 = num;
					for (int i = 0; i < 8; i++)
					{
						num2 = (((num2 & 1) != 0) ? (0xEDB88320u ^ (num2 >> 1)) : (num2 >> 1));
					}
					s_crcTable[num] = num2;
				}
			}
			for (int j = 0; j < buf.Length; j++)
			{
				crc = s_crcTable[(crc ^ buf[j]) & 0xFF] ^ (crc >> 8);
			}
			return crc;
		}

		private static void WriteBE(byte[] b, int o, uint v)
		{
			b[o] = (byte)(v >> 24);
			b[o + 1] = (byte)(v >> 16);
			b[o + 2] = (byte)(v >> 8);
			b[o + 3] = (byte)v;
		}

		private static uint ReadBE(byte[] b, int o)
		{
			return (uint)((b[o] << 24) | (b[o + 1] << 16) | (b[o + 2] << 8) | b[o + 3]);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
}
namespace FireFront
{
	[BepInPlugin("com.raveniron.firefront", "FireFront", "1.0.4")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.raveniron.firefront";

		public const string NAME = "FireFront";

		public const string VERSION = "1.0.4";

		public const int WireProtocol = 1;

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			Instance = this;
			FireLogger.Init(((BaseUnityPlugin)this).Logger);
			FireConfig.Bind(((BaseUnityPlugin)this).Config);
			FireDevCommands.HookLiveConfigSync(((BaseUnityPlugin)this).Config);
			((Component)this).gameObject.AddComponent<FireManager>();
			if (FireVFXController.GraphicsAvailable)
			{
				CharredTextures.Prewarm();
			}
			_harmony = new Harmony("com.raveniron.firefront");
			_harmony.PatchAll();
			FireLogger.Info("FireFront 1.0.4 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			CharredTreeSkin.ReleaseAll();
		}
	}
}
namespace FireFront.Utils
{
	public static class AuthLog
	{
		private struct Gate
		{
			public float NextAt;

			public int Suppressed;
		}

		public const string Prefix = "[AUTH]";

		private const float WindowSeconds = 10f;

		private const int MaxTrackedGates = 1024;

		private static readonly Dictionary<(long peer, string kind), Gate> _gates = new Dictionary<(long, string), Gate>();

		public static void Refused(long peer, string kind, string what)
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			(long, string) key = (peer, kind ?? "");
			_gates.TryGetValue(key, out var value);
			if (realtimeSinceStartup < value.NextAt)
			{
				value.Suppressed++;
				_gates[key] = value;
				return;
			}
			string text = ((value.Suppressed > 0) ? $" ({value.Suppressed} more of these from this peer in the last {10f:F0} s not logged)" : "");
			FireLogger.Warn(string.Format("{0} {1} — peer {2}.{3}", "[AUTH]", what, peer, text));
			if (_gates.Count >= 1024)
			{
				_gates.Clear();
			}
			_gates[key] = new Gate
			{
				NextAt = realtimeSinceStartup + 10f,
				Suppressed = 0
			};
		}
	}
	public static class FireLogger
	{
		[InterpolatedStringHandler]
		public ref struct DebugMessage
		{
			private readonly StringBuilder _sb;

			internal bool Enabled => _sb != null;

			public DebugMessage(int literalLength, int formattedCount, out bool shouldAppend)
			{
				shouldAppend = DebugEnabled;
				_sb = (shouldAppend ? new StringBuilder(literalLength + formattedCount * 16) : null);
			}

			public void AppendLiteral(string value)
			{
				_sb.Append(value);
			}

			public void AppendFormatted(string value)
			{
				_sb.Append(value);
			}

			public void AppendFormatted<T>(T value)
			{
				_sb.Append(value);
			}

			public void AppendFormatted<T>(T value, string format)
			{
				if (value is IFormattable formattable)
				{
					_sb.Append(formattable.ToString(format, null));
				}
				else
				{
					_sb.Append(value);
				}
			}

			internal string GetText()
			{
				return _sb?.ToString() ?? string.Empty;
			}
		}

		private static ManualLogSource _log;

		public static bool DebugEnabled
		{
			get
			{
				if (FireConfig.VerboseLogging != null)
				{
					return FireConfig.VerboseLogging.Value;
				}
				return false;
			}
		}

		public static void Init(ManualLogSource log)
		{
			_log = log;
		}

		public static void Info(string msg)
		{
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogInfo((object)msg);
			}
		}

		public static void Warn(string msg)
		{
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogWarning((object)msg);
			}
		}

		public static void Error(string msg)
		{
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogError((object)msg);
			}
		}

		public static void Debug(string msg)
		{
			if (DebugEnabled)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)("[debug] " + msg));
				}
			}
		}

		public static void Debug(ref DebugMessage message)
		{
			if (message.Enabled)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)("[debug] " + message.GetText()));
				}
			}
		}
	}
	public static class InvariantNumbers
	{
		private static readonly CultureInfo Inv = CultureInfo.InvariantCulture;

		public static string Normalize(string raw)
		{
			if (raw == null)
			{
				return null;
			}
			string text = raw.Trim().Replace('−', '-');
			int num = text.IndexOf(',');
			if (num >= 0 && text.IndexOf('.') < 0 && text.IndexOf(',', num + 1) < 0)
			{
				text = text.Substring(0, num) + "." + text.Substring(num + 1);
			}
			return text;
		}

		public static bool TryParseFloat(string raw, out float value)
		{
			value = 0f;
			if (raw == null)
			{
				return false;
			}
			if (!float.TryParse(Normalize(raw), NumberStyles.Float, Inv, out var result))
			{
				return false;
			}
			if (float.IsNaN(result) || float.IsInfinity(result))
			{
				return false;
			}
			value = result;
			return true;
		}

		public static bool TryParseInt(string raw, out int value)
		{
			value = 0;
			if (raw != null)
			{
				return int.TryParse(Normalize(raw), NumberStyles.Integer, Inv, out value);
			}
			return false;
		}

		public static bool TryParseLong(string raw, out long value)
		{
			value = 0L;
			if (raw != null)
			{
				return long.TryParse(Normalize(raw), NumberStyles.Integer, Inv, out value);
			}
			return false;
		}

		public static bool TryParseUInt(string raw, out uint value)
		{
			value = 0u;
			if (raw != null)
			{
				return uint.TryParse(Normalize(raw), NumberStyles.Integer, Inv, out value);
			}
			return false;
		}

		public static float ParseFloat(string raw)
		{
			if (!TryParseFloat(raw, out var value))
			{
				throw new FormatException("not a finite number: '" + raw + "'");
			}
			return value;
		}

		public static int ParseInt(string raw)
		{
			if (!TryParseInt(raw, out var value))
			{
				throw new FormatException("not an integer: '" + raw + "'");
			}
			return value;
		}

		public static long ParseLong(string raw)
		{
			if (!TryParseLong(raw, out var value))
			{
				throw new FormatException("not an integer: '" + raw + "'");
			}
			return value;
		}

		public static string Format(float value)
		{
			return value.ToString("R", Inv);
		}

		public static string Format(int value)
		{
			return value.ToString(Inv);
		}

		public static string Format(long value)
		{
			return value.ToString(Inv);
		}

		public static string Format(uint value)
		{
			return value.ToString(Inv);
		}
	}
	public static class ValheimBridge
	{
		public struct ZdoBurnable
		{
			public ZDOID Id;

			public Vector3 Position;

			public int PrefabHash;
		}

		public struct PaintJob
		{
			public Vector3 Position;

			public bool MayCreate;
		}

		private sealed class ZoneBatch
		{
			public readonly List<Vector3> Positions = new List<Vector3>();

			public bool Assigned;
		}

		public struct PaintCandidate
		{
			public long PeerId;

			public Vector3 Position;
		}

		public struct PlayerTarget
		{
			public long PeerId;

			public Vector3 Position;

			public string Name;
		}

		public static readonly HashSet<Component> SuppressIgnition = new HashSet<Component>();

		private const BindingFlags AnyInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private const BindingFlags AnyStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly FieldInfo AllInstancesField = typeof(WearNTear).GetField("s_allInstances", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo BurnableField = typeof(WearNTear).GetField("m_burnable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo WntNviewField = typeof(WearNTear).GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo PieceField = typeof(WearNTear).GetField("m_piece", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo PieceNameField = typeof(Piece).GetField("m_name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo WntDestroyMethod = typeof(WearNTear).GetMethod("Destroy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(HitData),
			typeof(bool)
		}, null);

		private static readonly FieldInfo TreeNviewField = typeof(TreeBase).GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo TreeSpawnLogMethod = typeof(TreeBase).GetMethod("SpawnLog", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);

		private static readonly FieldInfo LogNviewField = typeof(TreeLog).GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo LogDestroyMethod = typeof(TreeLog).GetMethod("Destroy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(HitData),
			typeof(bool)
		}, null);

		private static readonly Type VanillaFireType = typeof(WearNTear).Assembly.GetType("Fire");

		private static readonly FieldInfo GameCameraInstanceField = typeof(GameCamera).GetField("m_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo GameCameraCameraField = typeof(GameCamera).GetField("m_camera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo LocalPlayerField = typeof(Player).GetField("m_localPlayer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo ZNetScenePrefabsField = typeof(ZNetScene).GetField("m_prefabs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo ZNetSceneInstanceField = typeof(ZNetScene).GetField("s_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo ZNetLocalPlayerIsAdminMethod = typeof(ZNet).GetMethod("LocalPlayerIsAdminOrHost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private static readonly MethodInfo ZNetSceneCreateObjectMethod = typeof(ZNetScene).GetMethod("CreateObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(ZDO) }, null);

		private static readonly MethodInfo ZdoManFindSectorObjectsMethod = typeof(ZDOMan).GetMethod("FindSectorObjects", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[4]
		{
			typeof(Vector2s),
			typeof(SimulationDistance),
			typeof(List<ZDO>),
			typeof(List<ZDO>)
		}, null);

		private static readonly FieldInfo ZNetSceneNamedPrefabsField = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static Dictionary<int, bool> _burnablePrefabKinds;

		private static bool _zdoScanFailureLogged;

		private static readonly List<ZDO> _zdoScanScratch = new List<ZDO>(512);

		private static readonly int CreatorZdoHash = StringExtensionMethods.GetStableHashCode("creator");

		private static readonly HashSet<string> _killFailuresLogged = new HashSet<string>();

		private static Vector3? _positionOverride;

		private static readonly string[] CandidateParticleShaders = new string[6] { "Particles/Standard Unlit", "Particles/Standard Surface", "Legacy Shaders/Particles/Additive", "Legacy Shaders/Particles/Alpha Blended", "Sprites/Default", "UI/Default" };

		private static bool _loggedResolvedParticleShader;

		private static readonly FieldInfo EffectAreaTypeField = typeof(EffectArea).GetField("m_type", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo EffectAreaPlayerOnlyField = typeof(EffectArea).GetField("m_playerOnly", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo EffectAreaIsHeatField = typeof(EffectArea).GetField("m_isHeatType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo EffectAreaColliderField = typeof(EffectArea).GetField("m_collider", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo HeightmapFindMethod = typeof(Heightmap).GetMethod("FindHeightmap", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);

		private static readonly MethodInfo HeightmapIsClearedMethod = typeof(Heightmap).GetMethod("IsCleared", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);

		private static readonly MethodInfo HeightmapIsCultivatedMethod = typeof(Heightmap).GetMethod("IsCultivated", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);

		private static readonly MethodInfo TerrainCompPaintClearedMethod = typeof(TerrainComp).GetMethod("PaintCleared", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3]
		{
			typeof(Vector3),
			typeof(Vector3),
			typeof(Settings)
		}, null);

		private static readonly FieldInfo TerrainCompNviewField = typeof(TerrainComp).GetField("m_nview", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo TerrainCompHmapField = typeof(TerrainComp).GetField("m_hmap", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo TerrainCompOperationsField = typeof(TerrainComp).GetField("m_operations", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo TerrainCompLastOpPointField = typeof(TerrainComp).GetField("m_lastOpPoint", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo TerrainCompLastOpRadiusField = typeof(TerrainComp).GetField("m_lastOpRadius", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo TerrainCompSaveMethod = typeof(TerrainComp).GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(bool) }, null);

		private static bool _paintReflectionFailureLogged;

		private static readonly List<Heightmap> _paintHeightmapScratch = new List<Heightmap>(4);

		private static readonly MethodInfo ZNetSceneSpawnObjectMethod = typeof(ZNetScene).GetMethod("SpawnObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3]
		{
			typeof(Vector3),
			typeof(Quaternion),
			typeof(GameObject)
		}, null);

		private static readonly MethodInfo ZNetSceneIsAreaReadyMethod = typeof(ZNetScene).GetMethod("IsAreaReady", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);

		private static readonly MethodInfo PlayerPlacePieceMethod = typeof(Player).GetMethod("PlacePiece", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[5]
		{
			typeof(Piece),
			typeof(Vector3),
			typeof(Quaternion),
			typeof(bool),
			typeof(bool)
		}, null);

		private static readonly FieldInfo PiecePlaceEffectField = typeof(Piece).GetField("m_placeEffect", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly char[] PrefabNameTerminators = new char[2] { '(', ' ' };

		private static readonly int TerrainCompilerPrefabHash = StringExtensionMethods.GetStableHashCode("_TerrainCompiler");

		private static readonly List<ZDO> _compilerScanScratch = new List<ZDO>(64);

		private static readonly MethodInfo ZoneSystemGetGroundHeightMethod = typeof(ZoneSystem).GetMethod("GetGroundHeight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);

		private static readonly FieldInfo ZoneSystemInstanceField = typeof(ZoneSystem).GetField("s_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(ZoneSystem).GetField("m_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly int TerrainLayerMask = LayerMask.GetMask(new string[1] { "terrain" });

		private static bool _groundHeightLoggedOnce;

		private static bool _terrainLayerMaskLoggedOnce;

		private static readonly PropertyInfo WorldGeneratorInstanceProp = typeof(WorldGenerator).GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo WorldGeneratorGetHeightMethod = typeof(WorldGenerator).GetMethod("GetHeight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(float),
			typeof(float)
		}, null);

		private static bool _worldGenHeightLoggedOnce;

		private static readonly FieldInfo ZoneSystemWaterLevelField = typeof(ZoneSystem).GetField("m_waterLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static bool _waterLevelLogged;

		private static readonly FieldInfo EnvManEnvDurationField = typeof(EnvMan).GetField("m_environmentDuration", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo EnvManDebugEnvField = typeof(EnvMan).GetField("m_debugEnv", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo EnvManForceEnvField = typeof(EnvMan).GetField("m_forceEnv", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo EnvManGetEnvMethod = typeof(EnvMan).GetMethod("GetEnv", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);

		private static readonly MethodInfo EnvManGetAvailableEnvironmentsMethod = typeof(EnvMan).GetMethod("GetAvailableEnvironments", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(BiomeSector) }, null);

		private static readonly MethodInfo EnvManSelectWeightedEnvironmentMethod = typeof(EnvMan).GetMethod("SelectWeightedEnvironment", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(List<EnvEntry>) }, null);

		private static readonly MethodInfo EnvManGetCurrentEnvironmentMethod = typeof(EnvMan).GetMethod("GetCurrentEnvironment", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private static bool _weatherFailureLogged;

		private static readonly Dictionary<long, bool> _wetByZoneAndPeriod = new Dictionary<long, bool>();

		private static long _wetCachePeriod = long.MinValue;

		private static string _seenForceEnv;

		private static string _seenDebugEnv;

		private static RandomEvent _seenRandomEvent;

		private static int _seenPersistentEventCount = -1;

		private static readonly FieldInfo EnvManInstanceField = typeof(EnvMan).GetField("s_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo EnvManGetWindDirMethod = typeof(EnvMan).GetMethod("GetWindDir", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null);

		private static readonly MethodInfo EnvManGetWindIntensityMethod = typeof(EnvMan).GetMethod("GetWindIntensity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null);

		private static bool _windIntensityFailureLogged;

		private static int _windFrame = -1;

		private static Vector3? _windDirCache;

		private static float? _windIntensityCache;

		private static readonly FieldRef<LightFlicker, float> FlickerBaseIntensityRef = ResolveFlickerBaseIntensityRef();

		private static readonly FieldInfo LightLodBaseRangeField = typeof(LightLod).GetField("m_baseRange", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static bool _flickerRefFailureLogged;

		private static readonly MethodInfo PlayerMessageMethod = typeof(Player).GetMethod("Message", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[5]
		{
			typeof(MessageType),
			typeof(string),
			typeof(int),
			typeof(Sprite),
			typeof(bool)
		}, null);

		private static readonly MethodInfo CharacterAddFireDamageMethod = typeof(Character).GetMethod("AddFireDamage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(float),
			typeof(short)
		}, null);

		private static readonly MethodInfo CharacterGetSEManMethod = typeof(Character).GetMethod("GetSEMan", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private static readonly FieldInfo SEManBurningStatusField = typeof(SEMan).GetField("s_statusEffectBurning", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo SEManAddStatusEffectIntMethod = typeof(SEMan).GetMethod("AddStatusEffect", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[5]
		{
			typeof(int),
			typeof(bool),
			typeof(int),
			typeof(float),
			typeof(short)
		}, null);

		private static readonly MethodInfo SEManAddStatusEffectObjMethod = typeof(SEMan).GetMethod("AddStatusEffect", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[5]
		{
			typeof(StatusEffect),
			typeof(bool),
			typeof(int),
			typeof(float),
			typeof(short)
		}, null);

		private static readonly FieldInfo EffectAreaCharacterMaskField = typeof(EffectArea).GetField("s_characterMask", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static bool _characterMaskLoggedOnce;

		private static bool _fireDamageTickLoggedOnce;

		private static Texture2D _cachedScorchTexture;

		private static int _scorchLogged;

		private static readonly Vector3[] _scorchCornerScratch = (Vector3[])(object)new Vector3[4];

		private static Mesh _cachedQuadMesh;

		private static Mesh _cachedBlackQuadMesh;

		private static Material _cachedScorchMaterial;

		private static Texture2D _cachedSootTexture;

		private static Texture2D _cachedSoftParticleTexture;

		private static Material _cachedParticleMaterial;

		private static Texture2D _cachedAdditiveTexture;

		private static Material _cachedAdditiveMaterial;

		private static bool _additiveUnavailable;

		private static readonly List<GameObject> _tallVfx = new List<GameObject>();

		private const float TallBurnerMinHeight = 3f;

		private const float CostHeightCeiling = 14f;

		private const string RpcIgniteRequest = "FireFront_IgniteRequest2";

		private static readonly MethodInfo ZRoutedRpcGetServerPeerIdMethod = typeof(ZRoutedRpc).GetMethod("GetServerPeerID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private static readonly MethodInfo ZNetIsDedicatedMethod = typeof(ZNet).GetMethod("IsDedicated", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private static readonly FieldInfo ZRoutedRpcEverybodyField = typeof(ZRoutedRpc).GetField("Everybody", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private const string RpcFireEvent = "FireFront_FireEvent";

		private const string RpcPaintAssign = "FireFront_PaintAssign";

		private const string RpcGroundFireSync = "FireFront_GroundFireSync";

		private const string RpcExtinguishRequest = "FireFront_ExtinguishRequest";

		private const string RpcConfigSet = "FireFront_ConfigSet";

		private const string RpcStatusRequest = "FireFront_StatusRequest";

		private const string RpcStatusResponse = "FireFront_StatusResponse";

		private const string RpcCommandRelay = "FireFront_CommandRelay";

		private const string RpcFireDamage = "FireFront_FireDamage";

		private const string RpcGroundSyncRequest = "FireFront_GroundSyncRequest";

		private const string RpcObjectFireSync = "FireFront_ObjectFireSync";

		private const string RpcVersion = "FireFront_Version";

		private static readonly FieldInfo ZNetAdminListField = typeof(ZNet).GetField("m_adminList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo ZNetListContainsIdMethod = typeof(ZNet).GetMethod("ListContainsId", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo ZNetPeersField = typeof(ZNet).GetField("m_peers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static bool _playerTargetsFailureLogged;

		private static readonly MethodInfo CharacterOnNearFireMethod = typeof(Character).GetMethod("OnNearFire", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Vector3) }, null);

		private static bool _nearFireFailureLogged;

		private static readonly HashSet<int> GuardedRoutedMethods = new HashSet<int>
		{
			StringExtensionMethods.GetStableHashCode("FireFront_IgniteRequest2"),
			StringExtensionMethods.GetStableHashCode("FireFront_FireEvent"),
			StringExtensionMethods.GetStableHashCode("FireFront_PaintAssign"),
			StringExtensionMethods.GetStableHashCode("FireFront_GroundFireSync"),
			StringExtensionMethods.GetStableHashCode("FireFront_ExtinguishRequest"),
			StringExtensionMethods.GetStableHashCode("FireFront_ConfigSet"),
			StringExtensionMethods.GetStableHashCode("FireFront_StatusRequest"),
			StringExtensionMethods.GetStableHashCode("FireFront_StatusResponse"),
			StringExtensionMethods.GetStableHashCode("FireFront_CommandRelay"),
			StringExtensionMethods.GetStableHashCode("FireFront_FireDamage"),
			StringExtensionMethods.GetStableHashCode("FireFront_GroundSyncRequest"),
			StringExtensionMethods.GetStableHashCode("FireFront_ObjectFireSync"),
			StringExtensionMethods.GetStableHashCode("FireFront_Version"),
			StringExtensionMethods.GetStableHashCode("RPC_Damage")
		};

		public static List<WearNTear> AllPieces => (AllInstancesField?.GetValue(null) as List<WearNTear>) ?? new List<WearNTear>();

		public static bool RoutedSenderGuardArmed => ZNetPeersField != null;

		public static BurnKind KindOf(Component target)
		{
			if (target is WearNTear)
			{
				return BurnKind.Piece;
			}
			if (target is TreeLog)
			{
				return BurnKind.Log;
			}
			if (target is TreeBase)
			{
				return BurnKind.Tree;
			}
			return BurnKind.Unknown;
		}

		public static bool IsAlive(Component target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			switch (KindOf(target))
			{
			case BurnKind.Piece:
			{
				ZNetView val3 = AsZNetView(WntNviewField, target);
				if (val3 != null)
				{
					return val3.IsValid();
				}
				return false;
			}
			case BurnKind.Tree:
			{
				ZNetView val2 = AsZNetView(TreeNviewField, target);
				if (val2 != null)
				{
					return val2.IsValid();
				}
				return false;
			}
			case BurnKind.Log:
			{
				ZNetView val = AsZNetView(LogNviewField, target);
				if (val != null)
				{
					return val.IsValid();
				}
				return false;
			}
			default:
				return (Object)(object)target != (Object)null;
			}
		}

		private static ZNetView AsZNetView(FieldInfo field, Component target)
		{
			object? obj = field?.GetValue(target);
			return (ZNetView)((obj is ZNetView) ? obj : null);
		}

		public static bool IsLocalPlayerAdmin()
		{
			if ((Object)(object)ZNet.instance == (Object)null || ZNetLocalPlayerIsAdminMethod == null)
			{
				return false;
			}
			try
			{
				return (bool)ZNetLocalPlayerIsAdminMethod.Invoke(ZNet.instance, null);
			}
			catch (Exception ex)
			{
				bool shouldAppend;
				FireLogger.DebugMessage message = new FireLogger.DebugMessage(59, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("[IGNITE-TRACE] IsLocalPlayerAdmin reflection invoke threw: ");
					message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
				}
				FireLogger.Debug(ref message);
				return false;
			}
		}

		private static GameObject CreateObjectReflected(ZNetScene scene, ZDO zdo)
		{
			if (ZNetSceneCreateObjectMethod == null)
			{
				return null;
			}
			object? obj = ZNetSceneCreateObjectMethod.Invoke(scene, new object[1] { zdo });
			return (GameObject)((obj is GameObject) ? obj : null);
		}

		public static ZNetView ZNetViewOf(Component target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return null;
			}
			return (ZNetView)(KindOf(target) switch
			{
				BurnKind.Piece => AsZNetView(WntNviewField, target), 
				BurnKind.Tree => AsZNetView(TreeNviewField, target), 
				BurnKind.Log => AsZNetView(LogNviewField, target), 
				_ => null, 
			});
		}

		public static ZDOID? ZDOIDOf(Component target)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			ZNetView val = ZNetViewOf(target);
			if (!((Object)(object)val != (Object)null) || !val.IsValid())
			{
				return null;
			}
			return val.GetZDO().m_uid;
		}

		private static Dictionary<int, bool> EnsureBurnablePrefabKinds()
		{
			if (_burnablePrefabKinds != null)
			{
				return _burnablePrefabKinds;
			}
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			if (!(ZNetSceneNamedPrefabsField?.GetValue(instance) is Dictionary<int, GameObject> { Count: not 0 } dictionary))
			{
				if (!_zdoScanFailureLogged)
				{
					_zdoScanFailureLogged = true;
					FireLogger.Debug("[ZDO-SCAN] m_namedPrefabs unreadable or empty — ZDO-layer spread candidates unavailable.");
				}
				return null;
			}
			Dictionary<int, bool> dictionary2 = new Dictionary<int, bool>();
			foreach (KeyValuePair<int, GameObject> item in dictionary)
			{
				GameObject value = item.Value;
				if ((Object)(object)value == (Object)null)
				{
					continue;
				}
				if ((Object)(object)value.GetComponent<TreeBase>() != (Object)null || (Object)(object)value.GetComponent<TreeLog>() != (Object)null)
				{
					dictionary2[item.Key] = true;
					continue;
				}
				WearNTear component = value.GetComponent<WearNTear>();
				if ((Object)(object)component != (Object)null && BurnableField != null && (bool)BurnableField.GetValue(component))
				{
					dictionary2[item.Key] = false;
				}
			}
			_burnablePrefabKinds = dictionary2;
			bool shouldAppend;
			FireLogger.DebugMessage message = new FireLogger.DebugMessage(55, 1, out shouldAppend);
			if (shouldAppend)
			{
				message.AppendLiteral("[ZDO-SCAN] burnable prefab table built: ");
				message.AppendFormatted(dictionary2.Count);
				message.AppendLiteral(" prefab hashes.");
			}
			FireLogger.Debug(ref message);
			return dictionary2;
		}

		public static void RegisterPrefabWithZNetScene(ZNetScene scene, GameObject prefab)
		{
			if ((Object)(object)scene == (Object)null || (Object)(object)prefab == (Object)null)
			{
				return;
			}
			if (!(ZNetSceneNamedPrefabsField?.GetValue(scene) is Dictionary<int, GameObject> dictionary))
			{
				FireLogger.Warn("[DOUSING] m_namedPrefabs unreadable — '" + ((Object)prefab).name + "' not visible to network spawns.");
				return;
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
			if (!dictionary.ContainsKey(stableHashCode))
			{
				dictionary.Add(stableHashCode, prefab);
			}
		}

		public static bool IsPlayerBuilt(Component target)
		{
			ZNetView val = ZNetViewOf(target);
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				return false;
			}
			return val.GetZDO().GetLong(CreatorZdoHash, 0L) != 0;
		}

		public static bool CollectBurnableZdosNear(Vector3 center, float radius, bool includeTreesAndLogs, bool includePlayerBuildings, List<ZdoBurnable> into)
		{
			//IL_00a6: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_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_01b9: 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_01c5: 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)
			into.Clear();
			ZDOMan instance = ZDOMan.instance;
			if (instance == null || ZdoManFindSectorObjectsMethod == null)
			{
				if (!_zdoScanFailureLogged)
				{
					_zdoScanFailureLogged = true;
					FireLogger.Debug($"[ZDO-SCAN] unavailable (ZDOMan null: {instance == null}, " + $"FindSectorObjects null: {ZdoManFindSectorObjectsMethod == null}) — " + "spread falls back to instance candidates only.");
				}
				return false;
			}
			Dictionary<int, bool> dictionary = EnsureBurnablePrefabKinds();
			if (dictionary == null || dictionary.Count == 0)
			{
				return false;
			}
			_zdoScanScratch.Clear();
			int num = Mathf.Max(1, Mathf.CeilToInt(radius / 64f));
			try
			{
				ZdoManFindSectorObjectsMethod.Invoke(instance, new object[4]
				{
					ZoneSystem.GetZone(center),
					(object)new SimulationDistance(num, 0, true),
					_zdoScanScratch,
					null
				});
			}
			catch (Exception ex)
			{
				bool shouldAppend;
				if (!_zdoScanFailureLogged)
				{
					_zdoScanFailureLogged = true;
					FireLogger.DebugMessage message = new FireLogger.DebugMessage(36, 1, out shouldAppend);
					if (shouldAppend)
					{
						message.AppendLiteral("[ZDO-SCAN] FindSectorObjects threw: ");
						message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
					}
					FireLogger.Debug(ref message);
				}
				shouldAppend = false;
				return shouldAppend;
			}
			float num2 = radius * radius;
			for (int i = 0; i < _zdoScanScratch.Count; i++)
			{
				ZDO val = _zdoScanScratch[i];
				if (val != null && dictionary.TryGetValue(val.GetPrefab(), out var value) && (!value || includeTreesAndLogs) && (!value || !CharredTreeLifecycle.IsCharred(val)) && (value || includePlayerBuildings || val.GetLong(CreatorZdoHash, 0L) == 0L))
				{
					Vector3 position = val.GetPosition();
					Vector3 val2 = position - center;
					if (!(((Vector3)(ref val2)).sqrMagnitude > num2))
					{
						into.Add(new ZdoBurnable
						{
							Id = val.m_uid,
							Position = position,
							PrefabHash = val.GetPrefab()
						});
					}
				}
			}
			return true;
		}

		public static bool ZdoExists(ZDOID id)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZDOMan instance = ZDOMan.instance;
			return ((instance != null) ? instance.GetZDO(id) : null) != null;
		}

		public static bool TryGetBurnableZdo(ZDOID id, out Vector3 position)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			if (id == ZDOID.None)
			{
				return false;
			}
			ZDOMan instance = ZDOMan.instance;
			ZDO val = ((instance != null) ? instance.GetZDO(id) : null);
			if (val == null)
			{
				return false;
			}
			Dictionary<int, bool> dictionary = EnsureBurnablePrefabKinds();
			if (dictionary == null || !dictionary.TryGetValue(val.GetPrefab(), out var value))
			{
				return false;
			}
			if (value && CharredTreeLifecycle.IsCharred(val))
			{
				return false;
			}
			position = val.GetPosition();
			return true;
		}

		public static Component InstanceComponentOf(ZDOID id)
		{
			//IL_000f: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null || id == ZDOID.None)
			{
				return null;
			}
			GameObject val = instance.FindInstance(id);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Component component = (Component)(object)val.GetComponent<WearNTear>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			component = (Component)(object)val.GetComponent<TreeBase>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			return (Component)(object)val.GetComponent<TreeLog>();
		}

		public static Component ComponentFromZdoid(ZDOID id)
		{
			//IL_0048: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00e3: 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)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			FireLogger.DebugMessage message;
			bool shouldAppend;
			if ((Object)(object)instance == (Object)null)
			{
				message = new FireLogger.DebugMessage(64, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
					message.AppendFormatted<ZDOID>(id);
					message.AppendLiteral("): ZNetScene.instance is null.");
				}
				FireLogger.Debug(ref message);
				return null;
			}
			GameObject val = instance.FindInstance(id);
			if ((Object)(object)val == (Object)null)
			{
				ZDOMan instance2 = ZDOMan.instance;
				ZDO val2 = ((instance2 != null) ? instance2.GetZDO(id) : null);
				if (val2 == null)
				{
					message = new FireLogger.DebugMessage(93, 1, out shouldAppend);
					if (shouldAppend)
					{
						message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
						message.AppendFormatted<ZDOID>(id);
						message.AppendLiteral("): ZDO not found in ZDOMan either — nothing to instantiate.");
					}
					FireLogger.Debug(ref message);
					return null;
				}
				Dictionary<int, bool> dictionary = EnsureBurnablePrefabKinds();
				if (dictionary != null && !dictionary.ContainsKey(val2.GetPrefab()))
				{
					message = new FireLogger.DebugMessage(79, 2, out shouldAppend);
					if (shouldAppend)
					{
						message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
						message.AppendFormatted<ZDOID>(id);
						message.AppendLiteral("): prefab ");
						message.AppendFormatted(val2.GetPrefab());
						message.AppendLiteral(" is not burnable — not creating it.");
					}
					FireLogger.Debug(ref message);
					return null;
				}
				message = new FireLogger.DebugMessage(93, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
					message.AppendFormatted<ZDOID>(id);
					message.AppendLiteral("): ZDO exists but no local instance — forcing CreateObject.");
				}
				FireLogger.Debug(ref message);
				try
				{
					val = CreateObjectReflected(instance, val2);
				}
				catch (Exception ex)
				{
					message = new FireLogger.DebugMessage(57, 2, out shouldAppend);
					if (shouldAppend)
					{
						message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
						message.AppendFormatted<ZDOID>(id);
						message.AppendLiteral("): CreateObject threw: ");
						message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
					}
					FireLogger.Debug(ref message);
					return null;
				}
				if ((Object)(object)val == (Object)null)
				{
					message = new FireLogger.DebugMessage(68, 1, out shouldAppend);
					if (shouldAppend)
					{
						message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
						message.AppendFormatted<ZDOID>(id);
						message.AppendLiteral("): CreateObject returned null too.");
					}
					FireLogger.Debug(ref message);
					return null;
				}
				ZNetView component = val.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					ClaimOwnershipIfNeeded(component);
					message = new FireLogger.DebugMessage(85, 1, out shouldAppend);
					if (shouldAppend)
					{
						message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
						message.AppendFormatted<ZDOID>(id);
						message.AppendLiteral("): claimed ownership on the force-created instance.");
					}
					FireLogger.Debug(ref message);
				}
			}
			Component component2 = (Component)(object)val.GetComponent<WearNTear>();
			if ((Object)(object)component2 != (Object)null)
			{
				return component2;
			}
			component2 = (Component)(object)val.GetComponent<TreeBase>();
			if ((Object)(object)component2 != (Object)null)
			{
				return component2;
			}
			component2 = (Component)(object)val.GetComponent<TreeLog>();
			if ((Object)(object)component2 != (Object)null)
			{
				return component2;
			}
			message = new FireLogger.DebugMessage(111, 2, out shouldAppend);
			if (shouldAppend)
			{
				message.AppendLiteral("[IGNITE-TRACE] ComponentFromZdoid(");
				message.AppendFormatted<ZDOID>(id);
				message.AppendLiteral("): found/created GameObject ");
				message.AppendLiteral("'");
				message.AppendFormatted(((Object)val).name);
				message.AppendLiteral("' but it has none of WearNTear/TreeBase/TreeLog.");
			}
			FireLogger.Debug(ref message);
			return null;
		}

		public static bool IsBurnable(Component target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			switch (KindOf(target))
			{
			case BurnKind.Piece:
				if (!FireConfig.BurnPlayerBuildings.Value && IsPlayerBuilt(target))
				{
					return false;
				}
				if (BurnableField != null)
				{
					return (bool)BurnableField.GetValue(target);
				}
				return false;
			case BurnKind.Tree:
			case BurnKind.Log:
				if (!FireConfig.BurnTreesAndLogs.Value)
				{
					return false;
				}
				return !CharredTreeLifecycle.IsCharred(target.GetComponent<ZNetView>());
			default:
				return false;
			}
		}

		public static Vector3 PositionOf(Component target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return target.transform.position;
		}

		public static string PrefabNameOf(Component target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return null;
			}
			string name = ((Object)target.gameObject).name;
			if (!name.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				return name;
			}
			return name.Substring(0, name.Length - "(Clone)".Length);
		}

		public static string NameOf(Component target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return "<null>";
			}
			if (KindOf(target) == BurnKind.Piece && PieceField != null)
			{
				object? value = PieceField.GetValue(target);
				Piece val = (Piece)((value is Piece) ? value : null);
				if ((Object)(object)val != (Object)null && PieceNameField != null)
				{
					string text = PieceNameField.GetValue(val) as string;
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
			}
			return ((Object)target.gameObject).name;
		}

		public static void KillBurningTarget(Component target)
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			if (!IsAlive(target))
			{
				return;
			}
			switch (KindOf(target))
			{
			case BurnKind.Piece:
			{
				ZNetView val2 = AsZNetView(WntNviewField, target);
				ClaimOwnershipIfNeeded(val2);
				if (WntDestroyMethod != null)
				{
					WntDestroyMethod.Invoke(target, new object[2] { null, false });
				}
				else
				{
					LogKillReflectionFailureOnce("WearNTear.Destroy(HitData, bool)");
				}
				if (IsAlive(target) && (Object)(object)val2 != (Object)null)
				{
					val2.Destroy();
				}
				break;
			}
			case BurnKind.Log:
			{
				ZNetView val3 = AsZNetView(LogNviewField, target);
				ClaimOwnershipIfNeeded(val3);
				if (LogDestroyMethod != null)
				{
					LogDestroyMethod.Invoke(target, new object[2] { null, false });
				}
				else
				{
					LogKillReflectionFailureOnce("TreeLog.Destroy(HitData, bool)");
				}
				if (IsAlive(target) && (Object)(object)val3 != (Object)null)
				{
					val3.Destroy();
				}
				break;
			}
			case BurnKind.Tree:
			{
				ZNetView val = AsZNetView(TreeNviewField, target);
				if ((Object)(object)val != (Object)null && !val.IsOwner())
				{
					val.ClaimOwnership();
				}
				TreeSpawnLogMethod?.Invoke(target, new object[1] { Vector3.up });
				if (IsAlive(target) && (Object)(object)val != (Object)null)
				{
					val.Destroy();
				}
				break;
			}
			}
		}

		private static void LogKillReflectionFailureOnce(string member)
		{
			if (_killFailuresLogged.Add(member))
			{
				FireLogger.Warn("Could not resolve " + member + ", so burnt-down objects of that kind are being removed through ZNetView.Destroy instead. They still disappear; their drops may differ from a normal destruction.");
			}
		}

		private static void ClaimOwnershipIfNeeded(ZNetView nv)
		{
			if ((Object)(object)nv != (Object)null && !nv.IsOwner())
			{
				nv.ClaimOwnership();
			}
		}

		public static float FireDamageOf(HitData hit)
		{
			return hit?.m_damage.m_fire ?? 0f;
		}

		public static Component RaycastBurnable(float maxDistance = 50f)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			object? obj = GameCameraInstanceField?.GetValue(null);
			GameCamera val = (GameCamera)((obj is GameCamera) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			object? obj2 = GameCameraCameraField?.GetValue(val);
			Camera val2 = (Camera)((obj2 is Camera) ? obj2 : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			Transform transform = ((Component)val2).transform;
			RaycastHit val3 = default(RaycastHit);
			if (!Physics.Raycast(transform.position, transform.forward, ref val3, maxDistance))
			{
				return null;
			}
			if ((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null)
			{
				return null;
			}
			Component componentInParent = (Component)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<WearNTear>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			componentInParent = (Component)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<TreeLog>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			return (Component)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<TreeBase>();
		}

		public static void SetPositionOverride(Vector3? position)
		{
			_positionOverride = position;
		}

		public static Vector3? LocalPlayerPosition()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (_positionOverride.HasValue)
			{
				return _positionOverride;
			}
			object? obj = LocalPlayerField?.GetValue(null);
			Player val = (Player)((obj is Player) ? obj : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return ((Component)val).transform.position;
		}

		public static List<string> FindPrefabNamesContaining(string filter)
		{
			List<string> list = new List<string>();
			List<GameObject> list2 = AllPrefabs();
			string value = (filter ?? "").ToLowerInvariant();
			foreach (GameObject item in list2)
			{
				if (!((Object)(object)item == (Object)null) && (string.IsNullOrEmpty(value) || ((Object)item).name.ToLowerInvariant().Contains(value)))
				{
					list.Add(((Object)item).name);
				}
			}
			return list;
		}

		public static GameObject FindPrefabByName(string exactName)
		{
			if (string.IsNullOrEmpty(exactName))
			{
				return null;
			}
			foreach (GameObject item in AllPrefabs())
			{
				if ((Object)(object)item != (Object)null && string.Equals(((Object)item).name, exactName, StringComparison.OrdinalIgnoreCase))
				{
					return item;
				}
			}
			return null;
		}

		private static List<GameObject> AllPrefabs()
		{
			object obj = ZNetSceneInstanceField?.GetValue(null);
			if (obj == null)
			{
				return new List<GameObject>();
			}
			return (ZNetScenePrefabsField?.GetValue(obj) as List<GameObject>) ?? new List<GameObject>();
		}

		public static (bool found, bool hasZNetView, List<string> scriptNames) InspectPrefab(string exactName)
		{
			GameObject val = FindPrefabByName(exactName);
			if ((Object)(object)val == (Object)null)
			{
				return (found: false, hasZNetView: false, scriptNames: new List<string>());
			}
			bool item = (Object)(object)val.GetComponentInChildren<ZNetView>(true) != (Object)null;
			List<string> list = new List<string>();
			MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(((object)val2).GetType().Name);
				}
			}
			return (found: true, hasZNetView: item, scriptNames: list);
		}

		private static Shader FindUsableParticleShader()
		{
			string[] candidateParticleShaders = CandidateParticleShaders;
			foreach (string text in candidateParticleShaders)
			{
				Shader val = Shader.Find(text);
				if ((Object)(object)val != (Object)null)
				{
					if (!_loggedResolvedParticleShader)
					{
						_loggedResolvedParticleShader = true;
						FireLogger.Info("[SHADER-DIAG] particle shader resolved to \"" + text + "\" " + $"(candidate {Array.IndexOf(CandidateParticleShaders, text) + 1} " + $"of {CandidateParticleShaders.Length}).");
					}
					return val;
				}
			}
			if (!_loggedResolvedParticleShader)
			{
				_loggedResolvedParticleShader = true;
				FireLogger.Warn("[SHADER-DIAG] none of the " + CandidateParticleShaders.Length + " candidate particle shaders resolved in this build.");
			}
			return null;
		}

		public static string InspectNearestEffectArea(Vector3 near, float maxDistance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			EffectArea[] array = Object.FindObjectsOfType<EffectArea>();
			EffectArea val = null;
			float num = maxDistance * maxDistance;
			EffectArea[] array2 = array;
			Vector3 val3;
			foreach (EffectArea val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val3 = ((Component)val2).transform.position - near;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude <= num)
					{
						num = sqrMagnitude;
						val = val2;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return $"No EffectArea found within {maxDistance}m.";
			}
			object obj = EffectAreaTypeField?.GetValue(val);
			object arg = EffectAreaPlayerOnlyField?.GetValue(val);
			object arg2 = EffectAreaIsHeatField?.GetValue(val);
			object obj2 = EffectAreaColliderField?.GetValue(val);
			float num2;
			if (!(num <= maxDistance * maxDistance))
			{
				num2 = 0f;
			}
			else
			{
				val3 = ((Component)val).transform.position - near;
				num2 = ((Vector3)(ref val3)).sqrMagnitude;
			}
			float num3 = Mathf.Sqrt(num2);
			return $"Nearest EffectArea '{((Object)((Component)val).gameObject).name}' at {num3:F1}m: " + $"type={obj} (underlying={Convert.ToInt32(obj)}), " + $"playerOnly={arg}, isHeatType={arg2}, " + "collider=" + ((obj2 != null) ? obj2.GetType().Name : "null");
		}

		public static bool IsClearedOrCultivated(Vector3 worldPos)
		{
			//IL_001e: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (HeightmapFindMethod == null)
			{
				return false;
			}
			object obj;
			try
			{
				obj = HeightmapFindMethod.Invoke(null, new object[1] { worldPos });
			}
			catch (Exception ex)
			{
				bool shouldAppend;
				FireLogger.DebugMessage message = new FireLogger.DebugMessage(44, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("IsClearedOrCultivated: FindHeightmap threw: ");
					message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
				}
				FireLogger.Debug(ref message);
				shouldAppend = false;
				return shouldAppend;
			}
			if (obj == null)
			{
				return false;
			}
			bool flag = HeightmapIsClearedMethod != null && (bool)HeightmapIsClearedMethod.Invoke(obj, new object[1] { worldPos });
			bool flag2 = HeightmapIsCultivatedMethod != null && (bool)HeightmapIsCultivatedMethod.Invoke(obj, new object[1] { worldPos });
			return flag || flag2;
		}

		public static bool TrySpawnDirtPaintPiece(Vector3 worldPos)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00c5: 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)
			GameObject val = FindPrefabByName("cultivate");
			if ((Object)(object)val == (Object)null)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: 'cultivate' prefab not found via FindPrefabByName.");
				return false;
			}
			Piece component = val.GetComponent<Piece>();
			if ((Object)(object)component == (Object)null)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: 'cultivate' prefab has no Piece component.");
				return false;
			}
			if (PlayerPlacePieceMethod == null)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: Player.PlacePiece(Piece,Vector3,Quaternion,bool) reflection lookup returned null — likely a parameter-type mismatch.");
				return false;
			}
			object? obj = LocalPlayerField?.GetValue(null);
			Player val2 = (Player)((obj is Player) ? obj : null);
			if ((Object)(object)val2 == (Object)null)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: no local player.");
				return false;
			}
			object value = PiecePlaceEffectField?.GetValue(component);
			if (PiecePlaceEffectField != null)
			{
				PiecePlaceEffectField.SetValue(component, (object?)new EffectList());
			}
			object obj2;
			try
			{
				obj2 = PlayerPlacePieceMethod.Invoke(val2, new object[5]
				{
					component,
					worldPos,
					Quaternion.identity,
					false,
					false
				});
			}
			catch (Exception ex)
			{
				bool shouldAppend;
				FireLogger.DebugMessage message = new FireLogger.DebugMessage(42, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("TrySpawnDirtPaintPiece: PlacePiece threw: ");
					message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
				}
				FireLogger.Debug(ref message);
				shouldAppend = false;
				return shouldAppend;
			}
			finally
			{
				if (PiecePlaceEffectField != null)
				{
					PiecePlaceEffectField.SetValue(component, value);
				}
			}
			bool flag = default(bool);
			int num;
			if (obj2 is bool)
			{
				flag = (bool)obj2;
				num = ((1 == 0) ? 1 : 0);
			}
			else
			{
				num = 1;
			}
			int num2 = num | (flag ? 1 : 0);
			if (num2 == 0)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: PlacePiece returned false (placement rejected).");
			}
			return (byte)num2 != 0;
		}

		[Obsolete("Superseded by TrySpawnDirtPaintPiece via Player.PlacePiece — kept only for reference.")]
		private static bool TrySpawnDirtPaintPieceViaSpawnObject(Vector3 worldPos)
		{
			//IL_0076: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindPrefabByName("cultivate");
			if ((Object)(object)val == (Object)null)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: 'cultivate' prefab not found via FindPrefabByName.");
				return false;
			}
			if (ZNetSceneSpawnObjectMethod == null)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: ZNetScene.SpawnObject(Vector3,Quaternion,GameObject) reflection lookup returned null — likely a parameter-type or overload mismatch.");
				return false;
			}
			object obj = ZNetSceneInstanceField?.GetValue(null);
			if (obj == null)
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: ZNetScene.instance is null.");
				return false;
			}
			if (ZNetSceneIsAreaReadyMethod != null && !(bool)ZNetSceneIsAreaReadyMethod.Invoke(obj, new object[1] { worldPos }))
			{
				FireLogger.Debug("TrySpawnDirtPaintPiece: IsAreaReady(worldPos) is false — this is likely why SpawnObject returns null.");
			}
			object obj2;
			FireLogger.DebugMessage message;
			try
			{
				obj2 = ZNetSceneSpawnObjectMethod.Invoke(obj, new object[3]
				{
					worldPos,
					Quaternion.identity,
					val
				});
			}
			catch (Exception ex)
			{
				message = new FireLogger.DebugMessage(43, 1, out var shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("TrySpawnDirtPaintPiece: SpawnObject threw: ");
					message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
				}
				FireLogger.Debug(ref message);
				shouldAppend = false;
				return shouldAppend;
			}
			GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null);
			if (val2 == null)
			{
				message = new FireLogger.DebugMessage(64, 1, out var shouldAppend2);
				if (shouldAppend2)
				{
					message.AppendLiteral("TrySpawnDirtPaintPiece: SpawnObject returned ");
					message.AppendFormatted((obj2 == null) ? "null" : obj2.GetType().Name);
					message.AppendLiteral(", not a GameObject.");
				}
				FireLogger.Debug(ref message);
				return false;
			}
			val2.AddComponent<TerrainPaintCleanup>();
			return true;
		}

		public static bool TrySpawnTree(string prefabName, Vector3 worldPos)
		{
			//IL_0083: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (!IsServer())
			{
				FireLogger.Debug("TrySpawnTree: not the server - regrowth is server authority only.");
				return false;
			}
			GameObject val = FindPrefabByName(prefabName);
			FireLogger.DebugMessage message;
			bool shouldAppend;
			if ((Object)(object)val == (Object)null)
			{
				message = new FireLogger.DebugMessage(55, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("TrySpawnTree: prefab '");
					message.AppendFormatted(prefabName);
					message.AppendLiteral("' not found via FindPrefabByName.");
				}
				FireLogger.Debug(ref message);
				return false;
			}
			if (ZDOMan.instance == null || ZNetSceneInstanceField?.GetValue(null) == null)
			{
				FireLogger.Debug("TrySpawnTree: ZDOMan/ZNetScene not up yet.");
				return false;
			}
			float num = Mathf.Repeat(worldPos.x * 37.1f + worldPos.z * 91.7f, 360f);
			GameObject val2;
			try
			{
				val2 = Object.Instantiate<GameObject>(val, worldPos, Quaternion.Euler(0f, num, 0f));
			}
			catch (Exception ex)
			{
				message = new FireLogger.DebugMessage(33, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("TrySpawnTree: Instantiate threw: ");
					message.AppendFormatted(ex.Message);
				}
				FireLogger.Debug(ref message);
				shouldAppend = false;
				return shouldAppend;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			ZNetView component = val2.GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				message = new FireLogger.DebugMessage(66, 1, out var shouldAppend2);
				if (shouldAppend2)
				{
					message.AppendLiteral("TrySpawnTree: '");
					message.AppendFormatted(prefabName);
					message.AppendLiteral("' came up without a valid ZNetView/ZDO - destroyed.");
				}
				FireLogger.Debug(ref message);
				Object.Destroy((Object)(object)val2);
				return false;
			}
			return true;
		}

		public static int PrefabHashOf(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return 0;
			}
			int num = name.IndexOfAny(PrefabNameTerminators);
			return StringExtensionMethods.GetStableHashCode((num >= 0) ? name.Remove(num) : name);
		}

		public static bool CollectAllZdosNear(Vector3 center, List<ZdoBurnable> into)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			into.Clear();
			ZDOMan instance = ZDOMan.instance;
			if (instance == null || ZdoManFindSectorObjectsMethod == null)
			{
				return false;
			}
			_zdoScanScratch.Clear();
			try
			{
				ZdoManFindSectorObjectsMethod.Invoke(instance, new object[4]
				{
					ZoneSystem.GetZone(center),
					(object)new SimulationDistance(1, 0, true),
					_zdoScanScratch,
					null
				});
			}
			catch (Exception ex)
			{
				bool shouldAppend;
				FireLogger.DebugMessage message = new FireLogger.DebugMessage(45, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("CollectAllZdosNear: FindSectorObjects threw: ");
					message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
				}
				FireLogger.Debug(ref message);
				shouldAppend = false;
				return shouldAppend;
			}
			for (int i = 0; i < _zdoScanScratch.Count; i++)
			{
				ZDO val = _zdoScanScratch[i];
				if (val != null)
				{
					into.Add(new ZdoBurnable
					{
						Id = val.m_uid,
						Position = val.GetPosition(),
						PrefabHash = val.GetPrefab()
					});
				}
			}
			return true;
		}

		public static bool TryGetZdoPosition(ZDOID id, out Vector3 position)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			ZDOMan instance = ZDOMan.instance;
			ZDO val = ((instance != null) ? instance.GetZDO(id) : null);
			if (val == null)
			{
				return false;
			}
			position = val.GetPosition();
			return true;
		}

		public static bool CollectPlayerBuiltPositionsNear(Vector3 center, List<Vector3> into)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			into.Clear();
			ZDOMan instance = ZDOMan.instance;
			if (instance == null || ZdoManFindSectorObjectsMethod == null)
			{
				FireLogger.Debug("CollectPlayerBuiltPositionsNear: ZDOMan null or the FindSectorObjects lookup failed - the build-over check cannot answer, so the caller must skip.");
				return false;
			}
			_zdoScanScratch.Clear();
			try
			{
				ZdoManFindSectorObjectsMethod.Invoke(instance, new object[4]
				{
					ZoneSystem.GetZone(center),
					(object)new SimulationDistance(1, 0, true),
					_zdoScanScratch,
					null
				});
			}
			catch (Exception ex)
			{
				bool shouldAppend;
				FireLogger.DebugMessage message = new FireLogger.DebugMessage(58, 1, out shouldAppend);
				if (shouldAppend)
				{
					message.AppendLiteral("CollectPlayerBuiltPositionsNear: FindSectorObjects threw: ");
					message.AppendFormatted(ex.InnerException?.Message ?? ex.Message);
				}
				FireLogger.Debug(ref message);
				shouldAppend = false;
				return shouldAppend;
			}
			for (int i = 0; i < _zdoScanScratch.Count; i++)
			{
				ZDO val = _zdoScanScratch[i];
				if (val != null && val.GetLong(CreatorZdoHash, 0L) != 0L)
				{
					into.Add(val.GetPosition());
				}
			}
			return true;
		}

		public static void ForceCleanupTerrainPaintPiece(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			ZNetView component = go.GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
				}
				component.Destroy();
			}
		}

		public static int TryPaintScorchedDirtBatch(List<PaintJob> jobs, float radius)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_032d: 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_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Expected O, but got Unknown
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: 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_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			if (jobs == null || jobs.Count == 0)
			{
				return 0;
			}
			if (TerrainCompPaintClearedMethod == null || TerrainCompNviewField == null || TerrainCompHmapField == null || TerrainCompSaveMethod == null || TerrainCompOperationsField == null || TerrainCompLastOpPointField == null || TerrainCompLastOpRadiusField == null)
			{
				if (!_paintReflectionFailureLogged)
				{
					_paintReflectionFailureLogged = true;
					FireLogger.Warn("UseVanillaDirtPaint is on, but a TerrainComp member this build reflects (PaintCleared / Save / m_nview / m_hmap / m_operations / m_lastOpPoint / m_lastOpRadius) is missing from this game version. No dirt will be painted; the scorch decal still draws.");
				}
				return 0;
			}
			Dictionary<TerrainComp, ZoneBatch> dictionary = new Dictionary<TerrainComp, ZoneBatch>();
			int num = 0;
			int num2 = 0;
			ZNetScene instance = ZNetScene.instance;
			FireLogger.DebugMessage message;
			bool shouldAppend;
			foreach (PaintJob job in jobs)
			{
				Vector3 position = job.Position;
				Heightmap val = Heightmap.FindHeightmap(position);
				if ((Object)(object)val == (Object)null)
				{
					num++;
					continue;
				}
				TerrainComp val2 = TerrainComp.FindTerrainCompiler(((Component)val).transform.position);
				if ((Object)(object)val2 == (Object)null && job.MayCreate && (Object)(object)instance != (Object)null && instance.IsAreaReady(position))
				{
					try
					{
						val2 = val.GetAndCreateTerrainCompiler();
					}
					catch (Exception ex)
					{
						message = new FireLogger.DebugMessage(66, 2, out shouldAppend);
						if (shouldAppend)
						{
							message.AppendLiteral("TryPaintScorchedDirtBatch: GetAndCreateTerrainCompiler threw at ");
							message.AppendFormatted<Vector3>(position, "F0");
							message.AppendLiteral(": ");
							message.AppendFormatted(ex.Message);
						}
						FireLogger.Debug(ref message);
						continue;
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					num2++;
					continue;
				}
				AddPaintPosition(dictionary, val2, position, assigned: true);
				_paintHeightmapScratch.Clear();
				Heightmap.FindHeightmap(position, radius, _paintHeightmapScratch);
				for (int i = 0; i < _paintHeightmapScratch.Count; i++)
				{
					Heightmap val3 = _paintHeightmapScratch[i];
					if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)val))
					{
						TerrainComp val4 = TerrainComp.FindTerrainCompiler(((Component)val3).transform.position);
						if ((Object)(object)val4 != (Object)null && (Object)(object)val4 != (Object)(object)val2)
						{
							AddPaintPosition(dictionary, val4, position, assigned: false);
						}
					}
				}
			}
			int num3 = 0;
			int num4 = 0;
			foreach (KeyValuePair<TerrainComp, ZoneBatch> item in dictionary)
			{
				TerrainComp key = item.Key;
				ZoneBatch value = item.Value;
				object? value2 = T