Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Timbersaw v0.3.0
plugins/Timbersaw.dll
Decompiled an hour ago
The result has been truncated due to the large size, download it to view full contents!
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: