Decompiled source of Timbersaw v0.3.0

plugins/Timbersaw.dll

Decompiled 27 minutes ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DotaItemDisplays;
using EntityStates;
using IL.RoR2;
using KinematicCharacterController;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.ConVar;
using RoR2.ContentManagement;
using RoR2.Items;
using RoR2.Skills;
using TimberMod.Modules;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Timbersaw")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: AssemblyInformationalVersion("0.3.0+10c4231efb8e86318977ec4205abbfdd64741fe1")]
[assembly: AssemblyProduct("Timbersaw")]
[assembly: AssemblyTitle("Timbersaw")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.0.0")]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
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 DotaItemDisplays
{
	internal static class ItemDisplayAssets
	{
		internal static IEnumerator Load(SkinDefParams skin, Dictionary<SkinnedMeshRenderer, Mesh> meshes)
		{
			if (!Object.op_Implicit((Object)(object)skin))
			{
				throw new InvalidOperationException("Native item display calibration skin missing");
			}
			MeshReplacement[] meshReplacements = skin.meshReplacements;
			foreach (MeshReplacement val in meshReplacements)
			{
				Renderer renderer = val.renderer;
				SkinnedMeshRenderer renderer2 = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
				if (renderer2 != null)
				{
					Mesh val2 = val.mesh;
					if (!Object.op_Implicit((Object)(object)val2))
					{
						AsyncOperationHandle<Mesh> handle = Addressables.LoadAssetAsync<Mesh>((object)val.meshAddress);
						yield return handle;
						val2 = handle.Result;
					}
					if (!Object.op_Implicit((Object)(object)val2))
					{
						throw new InvalidOperationException("Native item display bind mesh missing: " + ((Object)renderer2).name);
					}
					meshes[renderer2] = val2;
				}
			}
		}
	}
}
namespace TimberMod
{
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void ErrorAssetBundle(string assetName, string bundleName)
		{
			Error("failed to load asset, " + assetName + ", because it does not exist in asset bundle, " + bundleName);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInPlugin("DDL.Timbersaw", "Timbersaw", "0.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class TimbersawPlugin : BaseUnityPlugin
	{
		public const string MODUID = "DDL.Timbersaw";

		public const string MODVERSION = "0.3.0";

		internal static TimbersawPlugin instance;

		internal static AssetBundle bundle;

		public static ConfigEntry<float> SoundVolume;

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			SoundVolume = new ConfigFile(Path.Combine(Paths.ConfigPath, "Timbersaw.cfg"), true, ((BaseUnityPlugin)this).Info.Metadata).Bind<float>("Audio", "Volume", 0.75f, new ConfigDescription("Timbersaw skill sound volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			bundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "AssetBundles", "timbersaw"));
			if (!Object.op_Implicit((Object)(object)bundle))
			{
				Log.Error("Timbersaw asset bundle missing. Reinstall the complete package.");
				return;
			}
			TimberTokens.Init();
			TimberHooks.Init();
			TimberNetwork.Init();
			TimberAudio.Init();
			new ContentPacks().Initialize();
			Log.Info("Timbersaw 0.3.0 initialized.");
		}

		private void OnDestroy()
		{
			TimberHooks.Shutdown();
			TimberLookingGlass.Shutdown();
			TimberAudio.Shutdown();
		}
	}
	internal static class TimberAssets
	{
		internal static T Load<T>(string name) where T : Object
		{
			if (!Object.op_Implicit((Object)(object)TimbersawPlugin.bundle))
			{
				return default(T);
			}
			return TimbersawPlugin.bundle.LoadAsset<T>(name);
		}

		internal static Sprite Icon(string name)
		{
			return TimberAssets.Load<Sprite>(name);
		}
	}
	internal sealed class TimberAimTargets : IDisposable
	{
		private readonly CharacterBody owner;

		private readonly Renderer[] volumeRenderers;

		internal readonly HashSet<HealthComponent> Targets = new HashSet<HealthComponent>();

		private Collider[] overlaps = (Collider[])(object)new Collider[64];

		private readonly List<Renderer> fallbackRenderers = new List<Renderer>();

		private Color color;

		private bool disposed;

		internal TimberAimTargets(CharacterBody owner, Renderer[] volumeRenderers)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			this.owner = owner;
			this.volumeRenderers = volumeRenderers;
			SceneCamera.onSceneCameraPreRender += new SceneCameraDelegate(OnSceneCamera);
			OutlineHighlight.onPreRenderOutlineHighlight = (Action<OutlineHighlight>)Delegate.Combine(OutlineHighlight.onPreRenderOutlineHighlight, new Action<OutlineHighlight>(OnOutline));
		}

		internal void Refresh(Vector3 center, Quaternion frame, float radius, float halfHeight, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			this.color = new Color(color.r, color.g, color.b, 1f);
			Targets.Clear();
			if (disposed || !Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)owner.healthComponent) || !owner.healthComponent.alive)
			{
				return;
			}
			int num;
			while ((num = Physics.OverlapSphereNonAlloc(center, Mathf.Sqrt(radius * radius + halfHeight * halfHeight), overlaps, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.entityPrecise)).mask), (QueryTriggerInteraction)2)) == overlaps.Length)
			{
				Array.Resize(ref overlaps, overlaps.Length * 2);
			}
			for (int i = 0; i < num; i++)
			{
				Collider val = overlaps[i];
				overlaps[i] = null;
				HealthComponent val2 = ((!Object.op_Implicit((Object)(object)val)) ? null : ((Component)val).GetComponent<HurtBox>()?.healthComponent);
				if (TimberCombat.Enemy(owner, val2) && !Targets.Contains(val2) && TimberGeometry.DiscVisibleContact(val, center, frame, radius, halfHeight, throughWalls: false, out var _))
				{
					Targets.Add(val2);
				}
			}
		}

		internal void ClearTargets()
		{
			Targets.Clear();
		}

		private bool OwnCamera(SceneCamera camera)
		{
			if (!disposed && Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)owner.healthComponent) && owner.healthComponent.alive && Object.op_Implicit((Object)(object)camera) && Object.op_Implicit((Object)(object)camera.cameraRigController))
			{
				return (Object)(object)camera.cameraRigController.target == (Object)(object)((Component)owner).gameObject;
			}
			return false;
		}

		private void OnSceneCamera(SceneCamera camera)
		{
			int layer = (OwnCamera(camera) ? LayerIndex.defaultLayer.intVal : LayerIndex.noDraw.intVal);
			Renderer[] array = volumeRenderers;
			foreach (Renderer val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					((Component)val).gameObject.layer = layer;
				}
			}
		}

		private void OnOutline(OutlineHighlight outline)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)outline) || !OwnCamera(outline.sceneCamera))
			{
				return;
			}
			foreach (HealthComponent target in Targets)
			{
				if (!TimberCombat.Enemy(owner, target))
				{
					continue;
				}
				ModelLocator modelLocator = target.body.modelLocator;
				CharacterModel val = ((Object.op_Implicit((Object)(object)modelLocator) && Object.op_Implicit((Object)(object)modelLocator.modelTransform)) ? ((Component)modelLocator.modelTransform).GetComponent<CharacterModel>() : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					if (val.invisibilityCount <= 0)
					{
						RendererInfo[] baseRendererInfos = val.baseRendererInfos;
						foreach (RendererInfo val2 in baseRendererInfos)
						{
							Add(outline, val2.renderer);
						}
					}
					continue;
				}
				fallbackRenderers.Clear();
				((Component)target.body).GetComponentsInChildren<Renderer>(false, fallbackRenderers);
				foreach (Renderer fallbackRenderer in fallbackRenderers)
				{
					if (fallbackRenderer is MeshRenderer || fallbackRenderer is SkinnedMeshRenderer)
					{
						Add(outline, fallbackRenderer);
					}
				}
			}
		}

		private void Add(OutlineHighlight outline, Renderer renderer)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)renderer) && renderer.enabled && ((Component)renderer).gameObject.activeInHierarchy)
			{
				outline.AddHighlight(renderer, color);
			}
		}

		public void Dispose()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (!disposed)
			{
				disposed = true;
				SceneCamera.onSceneCameraPreRender -= new SceneCameraDelegate(OnSceneCamera);
				OutlineHighlight.onPreRenderOutlineHighlight = (Action<OutlineHighlight>)Delegate.Remove(OutlineHighlight.onPreRenderOutlineHighlight, new Action<OutlineHighlight>(OnOutline));
				Targets.Clear();
				fallbackRenderers.Clear();
			}
		}
	}
	public sealed class TimberDisplayMarker : MonoBehaviour
	{
	}
	public sealed class TimberAnimator : MonoBehaviour
	{
		private Animator animator;

		private CharacterBody body;

		private string state;

		private float actionUntil;

		private float introUntil;

		private bool display;

		private readonly Dictionary<string, float> lengths = new Dictionary<string, float>();

		private void OnEnable()
		{
			animator = ((Component)this).GetComponent<Animator>();
			if (Object.op_Implicit((Object)(object)animator) && Object.op_Implicit((Object)(object)animator.runtimeAnimatorController))
			{
				display = Object.op_Implicit((Object)(object)((Component)this).GetComponent<TimberDisplayMarker>());
				animator.applyRootMotion = false;
				animator.cullingMode = (AnimatorCullingMode)0;
				lengths.Clear();
				AnimationClip[] animationClips = animator.runtimeAnimatorController.animationClips;
				foreach (AnimationClip val in animationClips)
				{
					lengths[((Object)val).name] = val.length;
				}
				Play(display ? "DisplayIntro" : "Idle", 1f);
				introUntil = Time.time + Length("DisplayIntro");
			}
		}

		private float Length(string name)
		{
			foreach (KeyValuePair<string, float> length in lengths)
			{
				if (length.Key.EndsWith("_" + name, StringComparison.Ordinal))
				{
					return length.Value;
				}
			}
			return 1f;
		}

		private void Play(string next, float speed)
		{
			if (Object.op_Implicit((Object)(object)animator))
			{
				int num = Animator.StringToHash("Base Layer." + next);
				if (animator.HasState(0, num))
				{
					animator.SetFloat("PlaybackRate", speed);
					animator.CrossFadeInFixedTime(num, 0.1f, 0, 0f);
					state = next;
				}
			}
		}

		internal void Action(string next, float duration)
		{
			Play(next, Length(next) / Mathf.Max(0.1f, duration));
			actionUntil = Time.time + duration;
		}

		private void Update()
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)animator))
			{
				return;
			}
			if (display)
			{
				if (Time.time >= introUntil && state != "DisplayIdle")
				{
					Play("DisplayIdle", 1f);
				}
				return;
			}
			if (!Object.op_Implicit((Object)(object)body))
			{
				body = ((Component)this).GetComponentInParent<CharacterModel>()?.body;
			}
			if (!Object.op_Implicit((Object)(object)body))
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)body.healthComponent) && !body.healthComponent.alive)
			{
				if (state != "Death")
				{
					Play("Death", 1f);
				}
			}
			else if (!(Time.time < actionUntil))
			{
				TimberController component = ((Component)body).GetComponent<TimberController>();
				CharacterMotor characterMotor = body.characterMotor;
				float num;
				if (!Object.op_Implicit((Object)(object)characterMotor))
				{
					num = 0f;
				}
				else
				{
					Vector3 val = Vector3.ProjectOnPlane(characterMotor.velocity, Vector3.up);
					num = ((Vector3)(ref val)).magnitude;
				}
				float num2 = num;
				string text = ((Object.op_Implicit((Object)(object)component) && component.flightActive) ? "Flight" : ((Object.op_Implicit((Object)(object)component) && component.chainActive) ? "Chain" : ((Object.op_Implicit((Object)(object)characterMotor) && !characterMotor.isGrounded) ? ((characterMotor.velocity.y > 1f) ? "Jump" : "Fall") : ((num2 > 0.2f) ? "Run" : "Idle"))));
				if (text != state)
				{
					Play(text, (text == "Run") ? Mathf.Clamp(num2 / 7f, 0.65f, 2f) : 1f);
				}
			}
		}
	}
	internal static class TimberAudio
	{
		private sealed class PositionedVoice
		{
			internal TimberPcmOutput.Voice voice;

			internal Vector3 position;

			internal Transform parent;

			internal float gain;
		}

		private static readonly Dictionary<string, float[]> clips = new Dictionary<string, float[]>();

		private static readonly List<PositionedVoice> voices = new List<PositionedVoice>();

		private static TimberPcmOutput output;

		private static float nextVolumeUpdate;

		private static float gameVolume = 1f;

		private static float Volume
		{
			get
			{
				if (Time.unscaledTime >= nextVolumeUpdate)
				{
					nextVolumeUpdate = Time.unscaledTime + 0.25f;
					gameVolume = ReadVolume("volume_master") * ReadVolume("volume_sfx");
					BaseConVar val = (Object.op_Implicit((Object)(object)Console.instance) ? Console.instance.FindConVar("audio_focused_only") : null);
					if (!Application.isFocused && val != null && val.GetString() != "0")
					{
						gameVolume = 0f;
					}
				}
				return gameVolume * TimbersawPlugin.SoundVolume.Value;
			}
		}

		public static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if (Application.isBatchMode || (int)Application.platform != 2)
			{
				return;
			}
			try
			{
				Assembly assembly = typeof(TimberAudio).Assembly;
				foreach (string item in from n in assembly.GetManifestResourceNames()
					where n.StartsWith("TimbersawAudio.")
					select n)
				{
					clips[item.Substring(15, item.Length - 19)] = TimberPcmOutput.ReadWave(assembly.GetManifestResourceStream(item));
				}
				output = new TimberPcmOutput();
				((Component)TimbersawPlugin.instance).gameObject.AddComponent<TimberAudioDriver>();
				Log.Info($"Dota audio: {clips.Count} original WAV samples; Windows PCM output ready.");
			}
			catch (Exception arg)
			{
				Shutdown();
				Log.Error($"Dota audio unavailable: {arg}");
			}
		}

		public static TimberPcmOutput.Voice Play(string sound, Vector3 position, float volume = 1f, Transform parent = null)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Transform val = Listener();
			if (output == null || !Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			string key = sound switch
			{
				"impact" => "arrow_impact_" + Random.Range(1, 4), 
				"frost" => "frost_arrow" + Random.Range(1, 5), 
				"arrow" => "arrow_" + Random.Range(1, 5), 
				_ => sound, 
			};
			if (!clips.TryGetValue(key, out var value))
			{
				return null;
			}
			PositionedVoice positionedVoice = new PositionedVoice
			{
				position = position,
				parent = parent,
				gain = volume
			};
			Gains(positionedVoice, val, out var left, out var right);
			positionedVoice.voice = output.Play(value, left, right);
			voices.Add(positionedVoice);
			return positionedVoice.voice;
		}

		public static TimberPcmOutput.Voice PlayVariant(string prefix, Vector3 position, float volume, Transform parent)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			string[] array = clips.Keys.Where((string k) => k.StartsWith(prefix, StringComparison.Ordinal)).ToArray();
			if (array.Length != 0)
			{
				return Play(array[Random.Range(0, array.Length)], position, volume, parent);
			}
			return null;
		}

		internal static void Tick()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (output == null)
			{
				return;
			}
			if (output.Error != null)
			{
				Log.Error(output.Error);
				Shutdown();
				return;
			}
			Transform listener = Listener();
			voices.RemoveAll((PositionedVoice v) => !v.voice.IsPlaying);
			foreach (PositionedVoice voice in voices)
			{
				if (Object.op_Implicit((Object)(object)voice.parent))
				{
					voice.position = voice.parent.position;
				}
				Gains(voice, listener, out var left, out var right);
				output.SetGain(voice.voice, left, right);
			}
		}

		private static Transform Listener()
		{
			foreach (CameraRigController readOnlyInstances in CameraRigController.readOnlyInstancesList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyInstances.sceneCam) && ((Behaviour)readOnlyInstances.sceneCam).isActiveAndEnabled)
				{
					return ((Component)readOnlyInstances.sceneCam).transform;
				}
			}
			return null;
		}

		private static void Gains(PositionedVoice voice, Transform listener, out float left, out float right)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			left = (right = 0f);
			if (Object.op_Implicit((Object)(object)listener))
			{
				Vector3 val = voice.position - listener.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				float num = voice.gain * Volume * Mathf.Clamp01(1f - magnitude / 70f) * Mathf.Min(1f, 8f / Mathf.Max(1f, magnitude));
				float num2 = Mathf.Clamp(Vector3.Dot(listener.right, ((Vector3)(ref val)).normalized), -1f, 1f);
				left = num * Mathf.Sqrt((1f - num2) * 0.5f);
				right = num * Mathf.Sqrt((1f + num2) * 0.5f);
			}
		}

		private static float ReadVolume(string name)
		{
			BaseConVar val = (Object.op_Implicit((Object)(object)Console.instance) ? Console.instance.FindConVar(name) : null);
			if (val == null || !float.TryParse(val.GetString(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return 1f;
			}
			return Mathf.Clamp01(result / 100f);
		}

		internal static void Shutdown()
		{
			foreach (PositionedVoice voice in voices)
			{
				voice.voice.Stop();
			}
			voices.Clear();
			output?.Dispose();
			output = null;
		}
	}
	public sealed class TimberAudioDriver : MonoBehaviour
	{
		private void Update()
		{
			TimberAudio.Tick();
		}

		private void OnDestroy()
		{
			TimberAudio.Shutdown();
		}

		private void OnApplicationQuit()
		{
			TimberAudio.Shutdown();
		}
	}
	public class TimberEffectSound : MonoBehaviour
	{
		public string sound;

		public float volume = 1f;

		private void OnEnable()
		{
			((MonoBehaviour)this).StartCoroutine(PlayNextFrame());
		}

		private IEnumerator PlayNextFrame()
		{
			yield return null;
			TimberAudio.Play(sound, ((Component)this).transform.position, volume);
		}
	}
	internal static class TimberBalance
	{
		internal const float PrimaryRadius = 10f;

		internal const float DiscRadius = 6f;

		internal const float DiscHalfHeight = 3f;

		internal const float DiscSpeed = 30f;

		internal const float DiscRange = 60f;

		internal const float FlightDuration = 10f;

		internal const float FlightCooldown = 18f;

		internal const float TwistedDuration = 2.4f;

		internal const float TwistedLength = 50f;

		internal const float TwistedWidth = 12.5f;

		internal const float ChainRange = 45f;

		internal const float ChainSpeed = 30f;

		internal const float ChainEnemyRadius = 0.25f;

		internal const float FlameDuration = 8f;

		internal const float FlameInterval = 0.2f;

		internal const float FlameRange = 14f;

		internal const float FlameHalfAngle = 35f;

		internal const float SlowDuration = 2f;

		internal static float FlightMultiplier(float age)
		{
			return 1f + 2f * Math.Min(1f, Math.Max(0f, Finite(age) ? (age / 10f) : 0f));
		}

		internal static int FlightVerticalInput(bool jump, bool rawSprint)
		{
			return (jump ? 1 : 0) - (rawSprint ? 1 : 0);
		}

		internal static DiscPhase RecallPhase(DiscPhase phase)
		{
			if (phase != DiscPhase.Outgoing && phase != DiscPhase.Stationary)
			{
				return phase;
			}
			return DiscPhase.Returning;
		}

		internal static float ChainRangeFor(float statSpeed, float baseSpeed)
		{
			return ChainScaledFor(45f, statSpeed, baseSpeed);
		}

		internal static float ChainSpeedFor(float statSpeed, float baseSpeed)
		{
			return ChainScaledFor(30f, statSpeed, baseSpeed, halfBonus: true);
		}

		private static float ChainScaledFor(float baseline, float statSpeed, float baseSpeed, bool halfBonus = false)
		{
			if (!Finite(statSpeed) || !Finite(baseSpeed) || baseSpeed <= 0f)
			{
				return baseline;
			}
			double num = (double)Math.Max(0f, statSpeed) / (double)baseSpeed;
			if (num * 45.0 > 3.4028234663852886E+38)
			{
				return baseline;
			}
			if (halfBonus && num > 1.0)
			{
				num = 1.0 + (num - 1.0) * 0.5;
			}
			return (float)((double)baseline * num);
		}

		internal static float SanitizeChainSpeed(float speed)
		{
			if (!Finite(speed) || !(speed > 0f))
			{
				return 0f;
			}
			return speed;
		}

		internal static float Momentum(float speed)
		{
			return 3.4f + 0.3f * Math.Max(0f, Finite(speed) ? (speed - 7f) : 0f);
		}

		internal static float Exposure(int count)
		{
			return 3.4f + (float)((count > 1) ? (count - 1) : 0);
		}

		internal static float ArmorDamage(float fraction)
		{
			return Math.Min(20f, Math.Max(2f, 20f * (Finite(fraction) ? fraction : 0f)));
		}

		internal static float Slow(float healthFraction)
		{
			return Math.Min(1f, Math.Max(0.05f, 0.05f * (1f + (float)Math.Floor(Math.Max(0f, 1f - healthFraction) * 20f + 1E-05f))));
		}

		internal static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		internal static float ActualDamage(float reported, float before, float after, float alreadyRecorded)
		{
			return Math.Max(0f, Math.Min(reported, Math.Max(0f, before - Math.Max(0f, after) - alreadyRecorded)));
		}
	}
	internal enum DiscPhase : byte
	{
		None,
		Outgoing,
		Stationary,
		Returning,
		TwistedOut,
		TwistedBack,
		Catching
	}
	internal sealed class DiscHitLedger<T>
	{
		private readonly HashSet<T> outgoing = new HashSet<T>();

		private readonly HashSet<T> returning = new HashSet<T>();

		internal bool Add(T target, bool back)
		{
			return (back ? returning : outgoing).Add(target);
		}
	}
	internal sealed class TimberPeriodicClock
	{
		private readonly double interval;

		private readonly int limit;

		private double elapsed;

		private int emitted;

		internal bool Complete => emitted >= limit;

		internal TimberPeriodicClock(double interval, int limit)
		{
			this.interval = interval;
			this.limit = limit;
		}

		internal void Reset()
		{
			elapsed = 0.0;
			emitted = 0;
		}

		internal int Advance(float delta)
		{
			if (!TimberBalance.Finite(delta) || delta <= 0f)
			{
				return 0;
			}
			elapsed += delta;
			int num = (int)Math.Min(limit, Math.Floor((elapsed + 1E-06) / interval));
			int result = num - emitted;
			emitted = num;
			return result;
		}
	}
	internal static class TimberBuffs
	{
		internal static BuffDef Armor;

		internal static BuffDef ArmorActive;

		internal static BuffDef Flame;

		internal static BuffDef Flight;

		internal static BuffDef ShivaSlow;

		internal static BuffDef FlameSlow;

		internal static BuffDef DiscSlow;

		internal static void Init(Sprite nativeSlowIcon)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			Armor = New("Armor", "buffTimberArmor", debuff: false, stack: true);
			ArmorActive = New("ArmorActive", "buffTimberArmor");
			Flame = New("Flame", "buffTimberFlame");
			Flight = New("Flight", "buffTimberFlight");
			ShivaSlow = Content.CreateAndAddBuff("TimbersawShivaSlow", nativeSlowIcon, new Color(0.45f, 0.85f, 1f), canStack: false, isDebuff: true);
			DiscSlow = Content.CreateAndAddBuff("TimbersawChakramSlow", nativeSlowIcon, new Color(1f, 0.67f, 0.2f), canStack: false, isDebuff: true);
			FlameSlow = New("FlameSlow", "buffTimberFlame", debuff: true);
		}

		private static BuffDef New(string name, string icon, bool debuff = false, bool stack = false)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return Content.CreateAndAddBuff("Timbersaw" + name, TimberAssets.Icon(icon), Color.white, stack, debuff);
		}

		internal static void Refresh(CharacterBody body, BuffDef buff, float time)
		{
			body.ClearTimedBuffs(buff);
			body.AddTimedBuff(buff, time);
		}

		internal static bool CanSlow(CharacterBody body, BuffDef buff)
		{
			if (Object.op_Implicit((Object)(object)body) && (!body.isBoss || (Object)(object)buff != (Object)(object)ShivaSlow))
			{
				return !ImmuneToDebuffBehavior.OverrideDebuff(buff, body);
			}
			return false;
		}

		internal static void ApplySlow(CharacterBody body, BuffDef buff)
		{
			if (CanSlow(body, buff))
			{
				Refresh(body, buff, 2f);
			}
		}

		internal static void ApplyDiscSlow(HealthComponent health)
		{
			if (NetworkServer.active && Object.op_Implicit((Object)(object)health) && CanSlow(health.body, DiscSlow))
			{
				int strength = Mathf.Clamp(Mathf.RoundToInt(TimberBalance.Slow(health.health / Mathf.Max(1f, health.fullHealth)) * 20f), 1, 20);
				TimberDiscSlow.Apply(health.body, strength);
			}
		}
	}
	internal static class TimberChainCollision
	{
		internal static bool Resolve(Ray ray, float range, float enemyRadius, int worldMask, int enemyMask, Func<Collider, bool> enemy, out Vector3 target)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			Vector3 direction = ((Ray)(ref ray)).direction;
			((Ray)(ref ray)).direction = ((Vector3)(ref direction)).normalized;
			target = ((Ray)(ref ray)).GetPoint(range);
			if (!(range <= 0f))
			{
				direction = ((Ray)(ref ray)).direction;
				if (!(((Vector3)(ref direction)).sqrMagnitude < 0.5f))
				{
					RaycastHit val = default(RaycastHit);
					bool flag = Physics.Raycast(ray, ref val, range, worldMask, (QueryTriggerInteraction)1);
					float num = (flag ? ((RaycastHit)(ref val)).distance : range);
					if (flag)
					{
						target = ((RaycastHit)(ref val)).point;
					}
					float num2 = num;
					float num3 = float.PositiveInfinity;
					Collider[] array = Physics.OverlapSphere(((Ray)(ref ray)).origin, enemyRadius, enemyMask, (QueryTriggerInteraction)2);
					foreach (Collider val2 in array)
					{
						if (!enemy(val2))
						{
							continue;
						}
						Vector3 val3 = val2.ClosestPoint(((Ray)(ref ray)).origin);
						if (VisibleContact(ray, val3, range, num, worldMask))
						{
							float num4 = Vector3.Distance(((Ray)(ref ray)).origin, val3);
							if (!(num4 >= num3))
							{
								num3 = num4;
								num2 = 0f;
								target = val3;
								flag = true;
							}
						}
					}
					RaycastHit[] array2 = Physics.SphereCastAll(ray, enemyRadius, num, enemyMask, (QueryTriggerInteraction)2);
					Array.Sort(array2, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
					RaycastHit[] array3 = array2;
					for (int i = 0; i < array3.Length; i++)
					{
						RaycastHit val4 = array3[i];
						if (!(((RaycastHit)(ref val4)).distance >= num2) && enemy(((RaycastHit)(ref val4)).collider) && !(((RaycastHit)(ref val4)).distance <= 0f) && VisibleContact(ray, ((RaycastHit)(ref val4)).point, range, num, worldMask))
						{
							num2 = ((RaycastHit)(ref val4)).distance;
							target = ((RaycastHit)(ref val4)).point;
							flag = true;
						}
					}
					return flag;
				}
			}
			return false;
		}

		private static bool VisibleContact(Ray ray, Vector3 point, float range, float limit, int worldMask)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = point - ((Ray)(ref ray)).origin;
			float num = Vector3.Dot(val, ((Ray)(ref ray)).direction);
			if (num >= 0f && num <= limit && ((Vector3)(ref val)).sqrMagnitude <= range * range)
			{
				return !Physics.Linecast(((Ray)(ref ray)).origin, point, worldMask, (QueryTriggerInteraction)1);
			}
			return false;
		}
	}
	internal sealed class TimberChakram
	{
		internal DiscPhase phase;

		internal Vector3 position;

		internal readonly Quaternion frame;

		internal readonly float area;

		private readonly TimberController owner;

		private readonly Vector3 origin;

		private readonly Vector3 direction;

		private readonly bool twisted;

		private readonly bool crit;

		private readonly DiscHitLedger<HealthComponent> ledger = new DiscHitLedger<HealthComponent>();

		private float age;

		private float distance;

		private float tick;

		private readonly float stopDistance;

		internal TimberChakram(TimberController owner, Vector3 forward, Vector3 destination, bool twisted)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			this.owner = owner;
			this.twisted = twisted;
			area = owner.Area;
			origin = (position = owner.body.aimOrigin);
			TimberGeometry.ResolveDiscLaunch(origin, forward, destination, twisted, out frame, out stopDistance);
			direction = frame * Vector3.forward;
			crit = owner.body.RollCrit();
			phase = ((!twisted) ? DiscPhase.Outgoing : DiscPhase.TwistedOut);
			TimberNetwork.Burst(owner.body, TimberEffect.DiscCast, position, direction, (!twisted) ? 1 : 2);
		}

		internal void Command()
		{
			//IL_0029: 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)
			DiscPhase discPhase = TimberBalance.RecallPhase(phase);
			if (discPhase != phase)
			{
				phase = discPhase;
				TimberNetwork.Burst(owner.body, TimberEffect.DiscRecall, position, direction, 1f);
			}
		}

		internal bool Tick(float dt)
		{
			//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)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: 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_009f: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_02ed: 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_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)owner.body) || !owner.body.healthComponent.alive)
			{
				return false;
			}
			Vector3 val = position;
			age += dt;
			Vector3 val4;
			if (twisted && phase != DiscPhase.Catching)
			{
				float num = Mathf.Clamp01((age - dt) / 2.4f);
				float num2 = Mathf.Clamp01(age / 2.4f);
				if (num < 0.5f && num2 >= 0.5f)
				{
					Vector3 val2 = origin + frame * TimberGeometry.Twisted(0.5f);
					Sweep(val, val2, back: false, stationary: false);
					val = val2;
				}
				phase = ((num2 < 0.5f) ? DiscPhase.TwistedOut : DiscPhase.TwistedBack);
				position = origin + frame * TimberGeometry.Twisted(num2);
				Sweep(val, position, num2 >= 0.5f, stationary: false);
				if (num2 >= 1f)
				{
					phase = DiscPhase.Catching;
				}
			}
			else if (phase == DiscPhase.Outgoing)
			{
				float num3 = Mathf.Min(30f * dt, stopDistance - distance);
				RaycastHit val3 = default(RaycastHit);
				if (Physics.SphereCast(position, 0.25f, direction, ref val3, num3, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
				{
					num3 = Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.02f);
					phase = DiscPhase.Stationary;
				}
				position += direction * num3;
				distance += num3;
				Sweep(val, position, back: false, stationary: false);
				if (distance >= stopDistance - 0.001f)
				{
					phase = DiscPhase.Stationary;
				}
			}
			else if (phase == DiscPhase.Stationary)
			{
				tick += dt;
				if (tick >= 0.5f)
				{
					tick -= 0.5f;
					Sweep(position, position, back: false, stationary: true);
				}
				val4 = owner.body.corePosition - position;
				if (((Vector3)(ref val4)).sqrMagnitude > 14400f)
				{
					phase = DiscPhase.Returning;
				}
			}
			else if (phase == DiscPhase.Returning || phase == DiscPhase.Catching)
			{
				Vector3 aimOrigin = owner.body.aimOrigin;
				float num4 = Mathf.Max(30f, Object.op_Implicit((Object)(object)owner.body.characterMotor) ? (((Vector3)(ref owner.body.characterMotor.velocity)).magnitude + 10f) : 30f);
				position = Vector3.MoveTowards(position, aimOrigin, num4 * dt);
				Sweep(val, position, back: true, stationary: false);
				val4 = position - aimOrigin;
				if (((Vector3)(ref val4)).sqrMagnitude < 0.16f)
				{
					return false;
				}
			}
			return true;
		}

		private void Sweep(Vector3 from, Vector3 to, bool back, bool stationary)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			float num = 6f * area;
			float num2 = 3f * area;
			float num3 = Vector3.Distance(from, to);
			int num4 = Mathf.Max(1, Mathf.CeilToInt(num3 / 0.5f));
			HashSet<HealthComponent> hashSet = (stationary ? new HashSet<HealthComponent>() : null);
			Collider[] array = Physics.OverlapCapsule(from, to, Mathf.Sqrt(num * num + num2 * num2), LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.entityPrecise)).mask), (QueryTriggerInteraction)2);
			foreach (Collider val in array)
			{
				HealthComponent val2 = ((Component)val).GetComponent<HurtBox>()?.healthComponent;
				if (!TimberCombat.Enemy(owner.body, val2))
				{
					continue;
				}
				for (int j = 0; j <= num4; j++)
				{
					Vector3 center = Vector3.Lerp(from, to, (float)j / (float)num4);
					if (!TimberGeometry.DiscVisibleContact(val, center, frame, num, num2, back, out var point))
					{
						continue;
					}
					if (stationary ? hashSet.Add(val2) : ledger.Add(val2, back))
					{
						float num5 = (stationary ? 1.5f : ((float)(twisted ? 10 : 6)));
						float proc = (stationary ? 0.25f : (twisted ? 0.8f : 1f));
						if (TimberCombat.Hit(owner.body, val2, point, owner.body.damage * num5, proc, (DamageSource)8, percent: false, ignite: false, crit) > 0f)
						{
							TimberBuffs.ApplyDiscSlow(val2);
						}
					}
					break;
				}
			}
		}
	}
	internal sealed class TimberDamageRecord
	{
		internal float raw;

		internal float actual;

		internal float available;

		internal bool percent;
	}
	internal static class TimberCombat
	{
		internal static readonly Dictionary<DamageInfo, TimberDamageRecord> Pending = new Dictionary<DamageInfo, TimberDamageRecord>();

		internal static bool Enemy(CharacterBody owner, HealthComponent health)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)owner.teamComponent) && Object.op_Implicit((Object)(object)health) && health.alive && Object.op_Implicit((Object)(object)health.body) && Object.op_Implicit((Object)(object)health.body.teamComponent) && (Object)(object)health.body != (Object)(object)owner && (int)health.body.teamComponent.teamIndex != 0)
			{
				return health.body.teamComponent.teamIndex != owner.teamComponent.teamIndex;
			}
			return false;
		}

		internal static bool Eligible(CharacterBody owner, HealthComponent health)
		{
			if (Enemy(owner, health) && !health.godMode && !health.body.HasBuff(Buffs.Immune) && !health.body.HasBuff(Buffs.HiddenInvincibility) && !health.body.HasBuff(Buffs.Intangible) && !health.body.HasBuff(Buffs.HiddenRejectAllDamage) && !health.body.HasBuff(Buffs.BrotherThroneShield))
			{
				return !health.body.HasBuff(Buffs.SojournVehicle);
			}
			return false;
		}

		internal static Dictionary<HealthComponent, Vector3> Sphere(CharacterBody owner, Vector3 center, float radius, bool walls = true)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<HealthComponent, Vector3> dictionary = new Dictionary<HealthComponent, Vector3>();
			Collider[] array = Physics.OverlapSphere(center, radius, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.entityPrecise)).mask), (QueryTriggerInteraction)2);
			foreach (Collider val in array)
			{
				HealthComponent val2 = ((Component)val).GetComponent<HurtBox>()?.healthComponent;
				if (Enemy(owner, val2) && !dictionary.ContainsKey(val2))
				{
					Vector3 val3 = val.ClosestPoint(center);
					if (!walls || !Physics.Linecast(center, val3, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
					{
						dictionary.Add(val2, val3);
					}
				}
			}
			return dictionary;
		}

		internal static float Hit(CharacterBody owner, HealthComponent target, Vector3 point, float amount, float proc, DamageSource source, bool percent = false, bool ignite = false, bool? crit = null)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			if (!NetworkServer.active || !Enemy(owner, target) || amount <= 0f)
			{
				return 0f;
			}
			DamageInfo val = new DamageInfo
			{
				attacker = ((Component)owner).gameObject,
				inflictor = ((Component)owner).gameObject,
				damage = amount,
				position = point,
				crit = (!percent && (crit ?? owner.RollCrit())),
				procCoefficient = (percent ? 0f : proc),
				damageType = new DamageTypeCombo(DamageTypeCombo.op_Implicit((DamageType)(ignite ? 128 : 0)), (DamageTypeExtended)0, (DamageSource)((!percent) ? ((int)source) : 0))
			};
			TimberDamageRecord timberDamageRecord = new TimberDamageRecord
			{
				raw = amount,
				percent = percent,
				available = target.combinedHealth
			};
			Pending.Add(val, timberDamageRecord);
			try
			{
				target.TakeDamage(val);
			}
			finally
			{
				Pending.Remove(val);
			}
			if (!val.rejected && !percent && Object.op_Implicit((Object)(object)GlobalEventManager.instance))
			{
				GlobalEventManager.instance.OnHitEnemy(val, ((Component)target).gameObject);
				GlobalEventManager.instance.OnHitAll(val, ((Component)target).gameObject);
			}
			if (!val.rejected)
			{
				return timberDamageRecord.actual;
			}
			return 0f;
		}

		internal static void Whirl(TimberController c, bool exposure, float speed)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				return;
			}
			CharacterBody body = c.body;
			Dictionary<HealthComponent, Vector3> dictionary = Sphere(body, body.corePosition, 10f * c.Area);
			List<KeyValuePair<HealthComponent, Vector3>> list = new List<KeyValuePair<HealthComponent, Vector3>>();
			foreach (KeyValuePair<HealthComponent, Vector3> item in dictionary)
			{
				if (Eligible(body, item.Key))
				{
					list.Add(item);
				}
			}
			float num = (exposure ? TimberBalance.Exposure(list.Count) : TimberBalance.Momentum(speed));
			int num2 = 0;
			bool value = body.RollCrit();
			foreach (KeyValuePair<HealthComponent, Vector3> item2 in list)
			{
				float amount = item2.Key.fullHealth * (item2.Key.body.isBoss ? 0.05f : 0.13f);
				float num3 = Hit(body, item2.Key, item2.Value, body.damage * num, 1f, (DamageSource)1, percent: false, ignite: false, value);
				if (Object.op_Implicit((Object)(object)item2.Key) && item2.Key.alive)
				{
					num3 += Hit(body, item2.Key, item2.Value, amount, 0f, (DamageSource)1, percent: true);
				}
				if (num3 > 0f)
				{
					num2++;
				}
			}
			if (exposure && num2 > 0)
			{
				body.healthComponent.Heal(body.maxHealth * 0.025f * (float)num2, default(ProcChainMask), true);
			}
			TimberNetwork.Burst(body, TimberEffect.Whirl, body.corePosition, c.Aim, c.Area);
		}

		internal static void Flame(TimberController c)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			Vector3 aimOrigin = c.body.aimOrigin;
			Vector3 aim = c.Aim;
			float num = 14f * c.Area;
			HashSet<HealthComponent> hashSet = new HashSet<HealthComponent>();
			Collider[] array = Physics.OverlapSphere(aimOrigin, num * 1.25f, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.entityPrecise)).mask), (QueryTriggerInteraction)2);
			foreach (Collider val in array)
			{
				HealthComponent val2 = ((Component)val).GetComponent<HurtBox>()?.healthComponent;
				if (Enemy(c.body, val2) && !hashSet.Contains(val2) && TimberGeometry.ConeContact(val, aimOrigin, aim, num, out var point) && !Physics.Linecast(aimOrigin, point, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
				{
					hashSet.Add(val2);
					if (Hit(c.body, val2, point, c.body.damage * 0.48f, 0.2f, (DamageSource)2, percent: false, ignite: true) > 0f)
					{
						TimberBuffs.ApplySlow(val2.body, TimberBuffs.FlameSlow);
					}
				}
			}
		}

		internal static void Chain(TimberController c, Vector3 from, Vector3 to, HashSet<HealthComponent> hits)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapCapsule(from, to, 2.5f * c.Area, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.entityPrecise)).mask), (QueryTriggerInteraction)2);
			foreach (Collider val in array)
			{
				HealthComponent val2 = ((Component)val).GetComponent<HurtBox>()?.healthComponent;
				if (Enemy(c.body, val2) && !hits.Contains(val2))
				{
					Vector3 val3 = val.ClosestPoint(to);
					if (!Physics.Linecast(to, val3, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
					{
						hits.Add(val2);
						Hit(c.body, val2, val3, c.body.damage * 4f, 0.7f, (DamageSource)4);
					}
				}
			}
		}
	}
	public sealed class TimberController : MonoBehaviour, ITeleportHandler, IEventSystemHandler
	{
		public GenericSkill relic;

		internal CharacterBody body;

		internal TimberChakram disc;

		internal DiscPhase discPhase;

		internal Vector3 discPosition;

		internal Vector3 chainEnd;

		internal Quaternion discFrame;

		internal float discArea = 1f;

		internal bool chainActive;

		internal bool flightActive;

		internal bool localDiscBusy;

		internal bool discAiming;

		internal bool flightDrive;

		internal Vector3 flightVelocity;

		private float armorUntil;

		private float armorActiveUntil;

		private float shivaTick;

		private float networkTick;

		private float lastAttackSpeed = -1f;

		private bool armorActive;

		private bool flameActive;

		private readonly TimberPeriodicClock flameClock = new TimberPeriodicClock(0.2, 40);

		private uint sequence;

		private uint lastSequence;

		private uint nextCommand;

		private uint acceptedCommand;

		private uint pendingCommand;

		internal float Area
		{
			get
			{
				if (!HasRelic(TimberSkills.Shiva))
				{
					return 1f;
				}
				return 1.2f;
			}
		}

		internal Vector3 Aim
		{
			get
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inputBank))
				{
					Vector3 aimDirection = body.inputBank.aimDirection;
					if (((Vector3)(ref aimDirection)).sqrMagnitude > 0.01f)
					{
						aimDirection = body.inputBank.aimDirection;
						return ((Vector3)(ref aimDirection)).normalized;
					}
				}
				return ((Component)this).transform.forward;
			}
		}

		internal bool DiscBusy
		{
			get
			{
				if (discPhase == DiscPhase.None)
				{
					return localDiscBusy;
				}
				return true;
			}
		}

		internal bool CanControlDisc
		{
			get
			{
				if (!localDiscBusy)
				{
					if (discPhase != DiscPhase.Outgoing)
					{
						return discPhase == DiscPhase.Stationary;
					}
					return true;
				}
				return false;
			}
		}

		internal bool ArmorEquipped
		{
			get
			{
				if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.skillLocator))
				{
					return (Object)(object)body.skillLocator.secondary.skillDef == (Object)(object)TimberSkills.Reactive;
				}
				return false;
			}
		}

		internal uint BeginDiscRequest()
		{
			pendingCommand = ++nextCommand;
			localDiscBusy = true;
			return pendingCommand;
		}

		private void Awake()
		{
			body = ((Component)this).GetComponent<CharacterBody>();
		}

		internal bool HasRelic(SkillDef skill)
		{
			if (Object.op_Implicit((Object)(object)relic) && Object.op_Implicit((Object)(object)skill))
			{
				return (Object)(object)relic.skillDef == (Object)(object)skill;
			}
			return false;
		}

		internal void Play(string state, float duration)
		{
			Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				TimberAnimator[] componentsInChildren = ((Component)val).GetComponentsInChildren<TimberAnimator>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].Action(state, duration);
				}
			}
		}

		internal void AddArmor(int count)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && ArmorEquipped && body.healthComponent.alive)
			{
				body.SetBuffCount(TimberBuffs.Armor.buffIndex, Mathf.Min(40, body.GetBuffCount(TimberBuffs.Armor) + count));
				armorUntil = Time.fixedTime + 12f;
			}
		}

		internal void ActivateArmor()
		{
			//IL_00aa: 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)
			if (NetworkServer.active)
			{
				armorActive = true;
				armorActiveUntil = Time.fixedTime + 6f;
				AddArmor(40);
				HealthComponent healthComponent = body.healthComponent;
				healthComponent.Networkbarrier = Mathf.Min(healthComponent.barrier, body.maxHealth);
				healthComponent.AddBarrier(Mathf.Max(0f, Mathf.Min(body.maxHealth - healthComponent.barrier, body.maxHealth * 0.25f)));
				TimberBuffs.Refresh(body, TimberBuffs.ArmorActive, 6f);
				TimberNetwork.Burst(body, TimberEffect.ArmorCast, body.corePosition, Aim, Area);
			}
		}

		internal void ActivateFlame()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				flameActive = true;
				flameClock.Reset();
				TimberBuffs.Refresh(body, TimberBuffs.Flame, 8f);
				TimberNetwork.Burst(body, TimberEffect.FlameCast, body.aimOrigin, Aim, Area);
			}
		}

		internal void DiscCommand(Vector3 direction, Vector3 destination, bool twisted, uint command, bool control)
		{
			//IL_0029: 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)
			if (NetworkServer.active && command > acceptedCommand)
			{
				acceptedCommand = command;
				if (disc == null && !control)
				{
					disc = new TimberChakram(this, direction, destination, twisted);
				}
				else if (disc != null && control && !twisted)
				{
					disc.Command();
				}
				Snapshot();
			}
		}

		internal void AcceptSnapshot(uint serial, uint acknowledged, DiscPhase phase, Vector3 position, Quaternion frame, float area)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (serial > lastSequence)
			{
				lastSequence = serial;
				discPhase = phase;
				discPosition = position;
				discFrame = frame;
				discArea = area;
				if (acknowledged >= pendingCommand)
				{
					localDiscBusy = false;
				}
			}
		}

		private void Snapshot()
		{
			//IL_007e: 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_0027: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			discPhase = disc?.phase ?? DiscPhase.None;
			if (disc != null)
			{
				discPosition = disc.position;
				discFrame = disc.frame;
				discArea = disc.area;
			}
			localDiscBusy = false;
			TimberNetwork.Snapshot(body, ++sequence, acceptedCommand, discPhase, discPosition, discFrame, discArea);
		}

		private void FixedUpdate()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.healthComponent))
			{
				return;
			}
			if (!body.healthComponent.alive)
			{
				Clear();
				return;
			}
			if (body.attackSpeed != lastAttackSpeed && Object.op_Implicit((Object)(object)body.skillLocator) && Object.op_Implicit((Object)(object)body.skillLocator.primary))
			{
				lastAttackSpeed = body.attackSpeed;
				body.skillLocator.primary.RecalculateFinalRechargeInterval();
			}
			if (!NetworkServer.active)
			{
				return;
			}
			float fixedTime = Time.fixedTime;
			if (!ArmorEquipped)
			{
				armorActive = false;
				body.SetBuffCount(TimberBuffs.Armor.buffIndex, 0);
				body.ClearTimedBuffs(TimberBuffs.ArmorActive);
			}
			if (armorActive)
			{
				if (body.healthComponent.barrier <= 0f || fixedTime >= armorActiveUntil)
				{
					ExplodeArmor();
				}
				else
				{
					AddArmor(40);
					body.healthComponent.Networkbarrier = Mathf.Min(body.maxHealth, body.healthComponent.barrier);
					int count = TimberCombat.Sphere(body, body.corePosition, 30f, walls: false).Count;
					float num = Mathf.Min(body.maxHealth - body.healthComponent.barrier, body.maxHealth * 0.025f * (float)count * Time.fixedDeltaTime);
					if (num > 0f)
					{
						body.healthComponent.AddBarrier(num);
					}
				}
			}
			else if (fixedTime >= armorUntil && body.GetBuffCount(TimberBuffs.Armor) > 0)
			{
				body.SetBuffCount(TimberBuffs.Armor.buffIndex, 0);
			}
			if (flameActive)
			{
				int num2 = flameClock.Advance(Time.fixedDeltaTime);
				for (int i = 0; i < num2; i++)
				{
					TimberCombat.Flame(this);
				}
				if (flameClock.Complete)
				{
					flameActive = false;
				}
			}
			if (HasRelic(TimberSkills.Shiva) && fixedTime >= shivaTick)
			{
				shivaTick = fixedTime + 0.25f;
				foreach (KeyValuePair<HealthComponent, Vector3> item in TimberCombat.Sphere(body, body.corePosition, 50f, walls: false))
				{
					if (TimberBuffs.CanSlow(item.Key.body, TimberBuffs.ShivaSlow))
					{
						TimberBuffs.Refresh(item.Key.body, TimberBuffs.ShivaSlow, 0.35f);
					}
				}
			}
			if (disc != null && !disc.Tick(Time.fixedDeltaTime))
			{
				disc = null;
				Snapshot();
			}
			if (fixedTime >= networkTick)
			{
				networkTick = fixedTime + 0.05f;
				Snapshot();
			}
		}

		private void ExplodeArmor()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			armorActive = false;
			HealthComponent healthComponent = body.healthComponent;
			float num = TimberBalance.ArmorDamage(healthComponent.barrier / Mathf.Max(1f, body.maxHealth));
			healthComponent.Networkbarrier = 0f;
			body.ClearTimedBuffs(TimberBuffs.ArmorActive);
			AddArmor(40);
			bool value = body.RollCrit();
			foreach (KeyValuePair<HealthComponent, Vector3> item in TimberCombat.Sphere(body, body.corePosition, 30f * Area))
			{
				TimberCombat.Hit(body, item.Key, item.Value, body.damage * num, 1f, (DamageSource)2, percent: false, ignite: false, value);
			}
			TimberNetwork.Burst(body, TimberEffect.ArmorBurst, body.corePosition, Aim, Area);
		}

		internal void Clear()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			chainActive = false;
			flightActive = false;
			flightDrive = false;
			discAiming = false;
			localDiscBusy = false;
			if (NetworkServer.active)
			{
				bool num = disc != null;
				disc = null;
				discPhase = DiscPhase.None;
				armorActive = false;
				flameActive = false;
				if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)TimberBuffs.Armor))
				{
					body.SetBuffCount(TimberBuffs.Armor.buffIndex, 0);
					body.ClearTimedBuffs(TimberBuffs.ArmorActive);
					body.ClearTimedBuffs(TimberBuffs.Flame);
					body.ClearTimedBuffs(TimberBuffs.Flight);
				}
				if (num)
				{
					Snapshot();
				}
			}
		}

		public void OnTeleport(Vector3 oldPosition, Vector3 newPosition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = oldPosition - newPosition;
			if (((Vector3)(ref val)).sqrMagnitude > 400f)
			{
				Clear();
			}
		}

		private void OnDisable()
		{
			Clear();
		}
	}
	internal static class TimberDamagePatch
	{
		private static bool Field(Instruction i, OpCode code, string type, string name)
		{
			//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)
			if (i.OpCode == code)
			{
				object operand = i.Operand;
				FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null);
				if (val != null && ((MemberReference)((MemberReference)val).DeclaringType).FullName == type)
				{
					return ((MemberReference)val).Name == name;
				}
			}
			return false;
		}

		internal static void Rewrite(ILContext il, Action<ILCursor, int> inject)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			int damage = -1;
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction i) => Field(i, OpCodes.Ldfld, "RoR2.DamageInfo", "damage"),
				(Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref damage)
			}))
			{
				throw new InvalidOperationException("Timbersaw: native damage local missing");
			}
			if (!val.TryGotoNext((MoveType)1, new Func<Instruction, bool>[3]
			{
				(Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0),
				(Instruction i) => Field(i, OpCodes.Ldfld, "RoR2.HealthComponent", "body"),
				(Instruction i) => Field(i, OpCodes.Ldsfld, "RoR2.DLC4Content/Buffs", "DamageReduction")
			}))
			{
				throw new InvalidOperationException("Timbersaw: native defensive boundary missing");
			}
			inject(val, damage);
		}
	}
	internal sealed class TimberDiscSlowState : MonoBehaviour
	{
		internal readonly TimberDiscSlowTimers timers = new TimberDiscSlowTimers();

		internal byte strength;

		private AlterBuffDuration[] durationControllers;

		private void Awake()
		{
			durationControllers = ((Component)this).GetComponents<AlterBuffDuration>();
		}

		internal float HitDuration()
		{
			float num = 2f;
			AlterBuffDuration[] array = durationControllers;
			foreach (AlterBuffDuration val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && val.IsBuffAffected(TimberBuffs.DiscSlow))
				{
					num *= val.durationScalar;
				}
			}
			return num;
		}
	}
	internal static class TimberDiscSlow
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__EnsureProtocol;

			public static hook_UpdateBuffs <1>__UpdateBuffs;

			public static hook_SetBuffCount <2>__SetBuffCount;

			public static hook_WriteBuffs <3>__WriteBuffs;

			public static hook_ReadBuffs <4>__ReadBuffs;
		}

		internal const string ProtocolToken = "DDL.Timbersaw.BuffProtocol;1";

		private static void EnsureProtocol()
		{
			IEnumerable<string> networkModList = NetworkModCompatibilityHelper.networkModList;
			if (!networkModList.Contains("DDL.Timbersaw.BuffProtocol;1"))
			{
				NetworkModCompatibilityHelper.networkModList = networkModList.Append("DDL.Timbersaw.BuffProtocol;1").OrderBy<string, string>((string value) => value, StringComparer.Ordinal).ToArray();
			}
		}

		internal static void Init()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			NetworkModCompatibilityHelper.onUpdated += EnsureProtocol;
			EnsureProtocol();
			object obj = <>O.<1>__UpdateBuffs;
			if (obj == null)
			{
				hook_UpdateBuffs val = UpdateBuffs;
				<>O.<1>__UpdateBuffs = val;
				obj = (object)val;
			}
			CharacterBody.UpdateBuffs += (hook_UpdateBuffs)obj;
			object obj2 = <>O.<2>__SetBuffCount;
			if (obj2 == null)
			{
				hook_SetBuffCount val2 = SetBuffCount;
				<>O.<2>__SetBuffCount = val2;
				obj2 = (object)val2;
			}
			CharacterBody.SetBuffCount += (hook_SetBuffCount)obj2;
			object obj3 = <>O.<3>__WriteBuffs;
			if (obj3 == null)
			{
				hook_WriteBuffs val3 = WriteBuffs;
				<>O.<3>__WriteBuffs = val3;
				obj3 = (object)val3;
			}
			CharacterBody.WriteBuffs += (hook_WriteBuffs)obj3;
			object obj4 = <>O.<4>__ReadBuffs;
			if (obj4 == null)
			{
				hook_ReadBuffs val4 = ReadBuffs;
				<>O.<4>__ReadBuffs = val4;
				obj4 = (object)val4;
			}
			CharacterBody.ReadBuffs += (hook_ReadBuffs)obj4;
		}

		internal static void Shutdown()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			NetworkModCompatibilityHelper.onUpdated -= EnsureProtocol;
			NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Where((string value) => value != "DDL.Timbersaw.BuffProtocol;1").ToArray();
			object obj = <>O.<1>__UpdateBuffs;
			if (obj == null)
			{
				hook_UpdateBuffs val = UpdateBuffs;
				<>O.<1>__UpdateBuffs = val;
				obj = (object)val;
			}
			CharacterBody.UpdateBuffs -= (hook_UpdateBuffs)obj;
			object obj2 = <>O.<2>__SetBuffCount;
			if (obj2 == null)
			{
				hook_SetBuffCount val2 = SetBuffCount;
				<>O.<2>__SetBuffCount = val2;
				obj2 = (object)val2;
			}
			CharacterBody.SetBuffCount -= (hook_SetBuffCount)obj2;
			object obj3 = <>O.<3>__WriteBuffs;
			if (obj3 == null)
			{
				hook_WriteBuffs val3 = WriteBuffs;
				<>O.<3>__WriteBuffs = val3;
				obj3 = (object)val3;
			}
			CharacterBody.WriteBuffs -= (hook_WriteBuffs)obj3;
			object obj4 = <>O.<4>__ReadBuffs;
			if (obj4 == null)
			{
				hook_ReadBuffs val4 = ReadBuffs;
				<>O.<4>__ReadBuffs = val4;
				obj4 = (object)val4;
			}
			CharacterBody.ReadBuffs -= (hook_ReadBuffs)obj4;
		}

		internal static int Strength(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)TimberBuffs.DiscSlow) || !body.HasBuff(TimberBuffs.DiscSlow))
			{
				return 0;
			}
			TimberDiscSlowState component = ((Component)body).GetComponent<TimberDiscSlowState>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return 0;
			}
			return component.strength;
		}

		internal static void Apply(CharacterBody body, int strength)
		{
			TimberDiscSlowState timberDiscSlowState = ((Component)body).GetComponent<TimberDiscSlowState>() ?? ((Component)body).gameObject.AddComponent<TimberDiscSlowState>();
			float num = timberDiscSlowState.HitDuration();
			if (!(num <= 0f) && !float.IsNaN(num))
			{
				if (!body.HasBuff(TimberBuffs.DiscSlow))
				{
					timberDiscSlowState.timers.Clear();
				}
				body.AddTimedBuff(TimberBuffs.DiscSlow, 2f);
				if (body.HasBuff(TimberBuffs.DiscSlow))
				{
					timberDiscSlowState.timers.Add(strength, num);
					SetStrength(body, timberDiscSlowState, (byte)timberDiscSlowState.timers.Strength);
				}
			}
		}

		private static void SetStrength(CharacterBody body, TimberDiscSlowState state, byte strength)
		{
			if (state.strength != strength)
			{
				state.strength = strength;
				body.statsDirty = true;
				if (NetworkServer.active)
				{
					((NetworkBehaviour)body).SetDirtyBit(2u);
				}
			}
		}

		private static void UpdateBuffs(orig_UpdateBuffs orig, CharacterBody body, float deltaTime)
		{
			orig.Invoke(body, deltaTime);
			if (NetworkServer.active)
			{
				TimberDiscSlowState component = ((Component)body).GetComponent<TimberDiscSlowState>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.timers.Advance(deltaTime);
					SetStrength(body, component, (byte)component.timers.Strength);
				}
			}
		}

		private static void SetBuffCount(orig_SetBuffCount orig, CharacterBody body, BuffIndex index, int count)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(body, index, count);
			if (Object.op_Implicit((Object)(object)TimberBuffs.DiscSlow) && index == TimberBuffs.DiscSlow.buffIndex && !body.HasBuff(index))
			{
				TimberDiscSlowState component = ((Component)body).GetComponent<TimberDiscSlowState>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.timers.Clear();
					SetStrength(body, component, 0);
				}
			}
		}

		private static void WriteBuffs(orig_WriteBuffs orig, CharacterBody body, NetworkWriter writer)
		{
			orig.Invoke(body, writer);
			writer.Write((byte)Strength(body));
		}

		private static void ReadBuffs(orig_ReadBuffs orig, CharacterBody body, NetworkReader reader)
		{
			orig.Invoke(body, reader);
			byte b = reader.ReadByte();
			if (NetworkServer.active)
			{
				return;
			}
			b = (byte)Mathf.Clamp((int)b, 0, 20);
			if (!Object.op_Implicit((Object)(object)TimberBuffs.DiscSlow) || !body.HasBuff(TimberBuffs.DiscSlow))
			{
				b = 0;
			}
			TimberDiscSlowState timberDiscSlowState = ((Component)body).GetComponent<TimberDiscSlowState>();
			if (Object.op_Implicit((Object)(object)timberDiscSlowState) || b != 0)
			{
				if (!Object.op_Implicit((Object)(object)timberDiscSlowState))
				{
					timberDiscSlowState = ((Component)body).gameObject.AddComponent<TimberDiscSlowState>();
				}
				SetStrength(body, timberDiscSlowState, b);
			}
		}
	}
	internal sealed class TimberDiscSlowTimers
	{
		private readonly float[] remaining = new float[20];

		internal int Strength
		{
			get
			{
				for (int num = remaining.Length - 1; num >= 0; num--)
				{
					if (remaining[num] > 0f)
					{
						return num + 1;
					}
				}
				return 0;
			}
		}

		internal void Add(int strength, float duration)
		{
			if (strength >= 1 && strength <= remaining.Length && !(duration <= 0f) && !float.IsNaN(duration))
			{
				remaining[strength - 1] = Math.Max(remaining[strength - 1], duration);
			}
		}

		internal void Advance(float deltaTime)
		{
			if (!(deltaTime <= 0f) && !float.IsNaN(deltaTime))
			{
				for (int i = 0; i < remaining.Length; i++)
				{
					remaining[i] = Math.Max(0f, remaining[i] - deltaTime);
				}
			}
		}

		internal void Clear()
		{
			Array.Clear(remaining, 0, remaining.Length);
		}
	}
	internal enum TimberEffect : byte
	{
		Whirl,
		ArmorCast,
		ArmorBurst,
		FlameCast,
		DiscCast,
		DiscRecall,
		ChainCast,
		JetStart,
		JetEnd
	}
	internal static class TimberEffects
	{
		internal static void Burst(TimberEffect kind, CharacterBody body, Vector3 position, Vector3 direction, float scale)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			string text = null;
			switch (kind)
			{
			case TimberEffect.Whirl:
				text = "whirling_death";
				break;
			case TimberEffect.ArmorCast:
				text = "armor_cast";
				break;
			case TimberEffect.ArmorBurst:
				text = "armor_explode";
				break;
			case TimberEffect.FlameCast:
				text = "flamethrower_cast";
				break;
			case TimberEffect.DiscCast:
				text = "chakra_cast";
				break;
			case TimberEffect.DiscRecall:
				text = "chakra_return";
				break;
			case TimberEffect.ChainCast:
				text = "timberchain";
				break;
			case TimberEffect.JetStart:
				text = "jetpack_cast";
				break;
			case TimberEffect.JetEnd:
				text = "jetpack_end";
				break;
			}
			if (text != null)
			{
				TimberAudio.Play(text, position, 0.8f);
			}
			if (kind == TimberEffect.ChainCast)
			{
				if (Object.op_Implicit((Object)(object)body))
				{
					TimberPresentation component = ((Component)body).GetComponent<TimberPresentation>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.BeginChain(position, direction);
					}
				}
			}
			else
			{
				GameObject val = new GameObject("Timbersaw " + kind);
				val.transform.position = position;
				val.transform.rotation = TimberGeometry.Frame(direction);
				val.AddComponent<TimberBurstVisual>().Initialize(kind, scale);
			}
		}
	}
	public sealed class TimberBurstVisual : MonoBehaviour
	{
		private TimberEffect kind;

		private float age;

		private float scale;

		private TimberSpatialVisual ring;

		private TimberSpatialVisual fire;

		private TimberSpatialVisual smoke;

		private TimberSpatialVisual sparks;

		private TimberSpatialVisual flash;

		private TimberSpatialVisual blades;

		private TimberSpatialVisual sweep;

		internal void Initialize(TimberEffect effect, float area)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			kind = effect;
			if (effect == TimberEffect.Whirl)
			{
				((Component)this).transform.rotation = Quaternion.identity;
			}
			scale = Mathf.Clamp(area, 0.1f, 4f);
			ring = new TimberSpatialVisual(((Component)this).transform, "radial saw arcs", "beam_hotwhite", 1600);
			fire = new TimberSpatialVisual(((Component)this).transform, "volumetric flash", "flame_puff_seq0_12", 300);
			smoke = new TimberSpatialVisual(((Component)this).transform, "expanding source smoke", "smoke1_seq0", 150, smoke: true);
			sparks = new TimberSpatialVisual(((Component)this).transform, "radial white streaks", "beam_hotwhite", 500);
			if (effect == TimberEffect.ArmorBurst)
			{
				flash = new TimberSpatialVisual(((Component)this).transform, "expanding spherical flash", "solid", 5120);
			}
			if (effect == TimberEffect.Whirl)
			{
				blades = new TimberSpatialVisual(((Component)this).transform, "source white rotating blades", "shredder_center_blade", 384);
				sweep = new TimberSpatialVisual(((Component)this).transform, "source broad whirling sweep", "juggernaut_blade_fury_seq0", 576);
				ring.Dispose();
				ring = new TimberSpatialVisual(((Component)this).transform, "source gold curled edge", "beam_blue_energy_01", 512);
				sparks.Dispose();
				sparks = new TimberSpatialVisual(((Component)this).transform, "tapered radial white streaks", "solid", 64);
			}
			Evaluate(0f);
		}

		private void Update()
		{
			age += Time.deltaTime;
			Evaluate(age);
			if (age > 0.9f)
			{
				TimberSpatialVisual.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		internal void Evaluate(float time)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_0616: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0642: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_0655: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: 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_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0560: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			if (ring == null)
			{
				return;
			}
			ring.Begin();
			fire.Begin();
			smoke.Begin();
			sparks.Begin();
			flash?.Begin();
			blades?.Begin();
			sweep?.Begin();
			float num = Mathf.Clamp01(time / 0.85f);
			float num2 = 1f - num;
			Color gold = TimberSpatialVisual.Gold;
			bool num3 = kind == TimberEffect.Whirl;
			bool flag = kind == TimberEffect.ArmorBurst;
			float num4 = (num3 ? 10f : (flag ? 30f : ((kind == TimberEffect.JetStart) ? 4f : 2.5f))) * scale;
			float num5 = Mathf.Clamp01(time / (flag ? 0.2f : 0.18f));
			if (num3)
			{
				float num6 = num4 * Mathf.Lerp(0.35f, 1f, Mathf.Clamp01(time / 0.18f));
				float num7 = Mathf.Clamp01(1f - time / 0.52f);
				sweep.SourceDisc(num6 * 0.94f, num6 * 0.25f, -0.08f, new Color(1f, 0.88f, 0.54f, num7 * 0.5f), time * 8f, 0.32f * scale);
				sweep.SourceDisc(num6 * 0.87f, num6 * 0.33f, 0.1f, new Color(1f, 0.96f, 0.8f, num7 * 0.3f), (0f - time) * 5f, -0.28f * scale);
				blades.SourceDisc(num6 * 0.76f, num6 * 0.2f, 0.2f, new Color(1f, 1f, 0.94f, num7 * 0.92f), time * 10f, 0.15f * scale);
				blades.SourceDisc(num6 * 0.65f, num6 * 0.2f, -0.18f, new Color(1f, 1f, 0.9f, num7 * 0.48f), (0f - time) * 8f, -0.12f * scale);
				for (int i = 0; i < 3; i++)
				{
					ring.Annulus(num6 * (1f - (float)i * 0.035f), num6 * (0.9f - (float)i * 0.04f), (float)(i - 1) * 0.16f * scale, new Color(2f, 1.18f, 0.24f, num2 * 0.7f), time * (float)(3 + i), 0.22f * scale);
				}
				Vector3 val = default(Vector3);
				for (int j = 0; j < 48; j++)
				{
					float num8 = (float)j * 2.39996f + time * 0.8f;
					((Vector3)(ref val))..ctor(Mathf.Cos(num8), 0f, Mathf.Sin(num8));
					float num9 = num6 * (0.7f + 0.31f * TimberSpatialVisual.Hash(j + 17));
					Vector3 val2 = val * num9;
					Vector3 val3 = new Vector3(0f - val.z, 0f, val.x) * (0.035f + 0.065f * TimberSpatialVisual.Hash(j)) * scale;
					Vector3 val4 = val2 - val * (1.5f + 2.4f * TimberSpatialVisual.Hash(j + 3)) * num7 * scale;
					sparks.Quad(val4 - val3, val4 + val3, val2, val2, new Color(1.5f, 1.45f, 1.3f, num7 * 0.95f));
					if (j < 12)
					{
						smoke.Puff(val2, 0.35f * num2, new Color(0.3f, 0.23f, 0.16f, num2 * 0.18f), (float)j + num);
					}
				}
			}
			else if (flag)
			{
				float num10 = Mathf.Clamp01(1f - time / 0.32f);
				for (int k = 0; k < 10; k++)
				{
					flash.SphereShell(num4 * num5 * (1f - (float)k * 0.09f), new Color(4f, 3f, 0.5f, num10 * ((k == 0) ? 0.014f : 0.055f)));
				}
				for (int l = 0; l < 96; l++)
				{
					Vector3 val5 = TimberSpatialVisual.Sphere(l);
					float num11 = num4 * num5 * (0.25f + 0.7f * TimberSpatialVisual.Hash(l + 39));
					Vector3 val6 = val5 * num11;
					sparks.Tube(val6 - val5 * (2f + 5f * num2), val6, 0.16f * num2, new Color(4f, 3.5f, 1.8f, num2));
					if (l < 48)
					{
						fire.Puff(val6, Mathf.Min(4f, num4 * 0.15f) * (1f - num), new Color(2f, 0.9f, 0.09f, num2 * 0.5f), (float)l + num);
					}
					if (l < 40)
					{
						smoke.Puff(val5 * num4 * num5 * 0.75f, 2f + num * 2f, new Color(0.3f, 0.26f, 0.21f, Mathf.Sin(num * MathF.PI) * 0.25f), (float)l + num);
					}
				}
			}
			else
			{
				ring.Ring(num4 * num5, 0.1f * num2, 0f, new Color(gold.r, gold.g, gold.b, num2 * 0.5f));
				for (int m = 0; m < 24; m++)
				{
					Vector3 p = TimberSpatialVisual.Sphere(m) * num4 * num5;
					fire.Puff(p, 0.35f * num2, new Color(1f, 0.65f, 0.2f, num2 * 0.4f), (float)m + num);
				}
			}
			ring.Upload();
			fire.Upload();
			smoke.Upload();
			sparks.Upload();
			flash?.Upload();
			blades?.Upload();
			sweep?.Upload();
		}

		internal void Release()
		{
			ring?.Dispose();
			fire?.Dispose();
			smoke?.Dispose();
			sparks?.Dispose();
			flash?.Dispose();
			blades?.Dispose();
			sweep?.Dispose();
		}

		private void OnDestroy()
		{
			Release();
		}
	}
	internal static class TimberGeometry
	{
		internal static Vector3 DiscDestination(Vector3 origin, Vector3 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			direction = Frame(direction) * Vector3.forward;
			float num = 60f;
			RaycastHit val = default(RaycastHit);
			if (Physics.SphereCast(origin, 0.25f, direction, ref val, num, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
			{
				num = Mathf.Max(0f, ((RaycastHit)(ref val)).distance - 0.02f);
			}
			return origin + direction * num;
		}

		internal static void ResolveDiscLaunch(Vector3 origin, Vector3 forward, Vector3 destination, bool twisted, out Quaternion frame, out float distance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = destination - origin;
			if (!TimberBalance.Finite(((Vector3)(ref val)).sqrMagnitude))
			{
				val = Frame(forward) * Vector3.forward * 60f;
			}
			frame = Frame(twisted ? forward : val);
			distance = Mathf.Clamp(((Vector3)(ref val)).magnitude, 0f, 60f);
		}

		internal static Quaternion Frame(Vector3 direction)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0051: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!TimberBalance.Finite(((Vector3)(ref direction)).sqrMagnitude) || ((Vector3)(ref direction)).sqrMagnitude < 0.0001f)
			{
				direction = Vector3.forward;
			}
			((Vector3)(ref direction)).Normalize();
			Vector3 val = Vector3.Cross(Vector3.up, direction);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.right;
			}
			((Vector3)(ref val)).Normalize();
			return Quaternion.LookRotation(direction, Vector3.Cross(direction, val));
		}

		internal static Vector3 Twisted(float phase)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			phase = Mathf.Clamp01(phase);
			float num = ((phase <= 0.5f) ? (phase * 2f) : (2f - phase * 2f));
			float num2 = 12.5f * Mathf.Sin(num * MathF.PI * 2f) * (float)((phase <= 0.5f) ? 1 : (-1));
			float num3 = 1.25f * Mathf.Sin(num * MathF.PI * 2f) * (float)((phase <= 0.5f) ? 1 : (-1));
			return new Vector3(num2, num3, 50f * num);
		}

		internal static bool InDisc(Vector3 local, float radius, float halfHeight)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (local.x * local.x + local.z * local.z <= radius * radius)
			{
				return Mathf.Abs(local.y) <= halfHeight;
			}
			return false;
		}

		internal static bool DiscVisibleContact(Collider collider, Vector3 center, Quaternion frame, float radius, float halfHeight, bool throughWalls, out Vector3 point)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: