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 HammerThrow v1.11.0
HammerThrow.dll
Decompiled 15 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("HammerThrow")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HammerThrow")] [assembly: AssemblyTitle("HammerThrow")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HammerThrow { public enum SpinAxisMode { Tumble, Roll, Yaw } [BepInPlugin("snowfarm.valheim.hammerthrow", "HammerThrow", "1.11.0")] public class HammerThrowPlugin : BaseUnityPlugin { private sealed class ThrowState { public Player Owner; public ItemData Weapon; public GameObject Visual; public GameObject HiddenOriginal; public Vector3 Direction; public Vector3 Position; public float Travelled; public bool Returning; public float Damage; public readonly HashSet<ZDOID> HitOut = new HashSet<ZDOID>(); public readonly HashSet<ZDOID> HitBack = new HashSet<ZDOID>(); public readonly HashSet<int> BirdHitsOut = new HashSet<int>(); public readonly HashSet<int> BirdHitsBack = new HashSet<int>(); } private sealed class PendingThrow { public Player Owner; public ItemData Weapon; public float StartTime; public float LaunchTime; public float PeakY; public bool PeakHandled; } [HarmonyPatch(typeof(Player), "PlayerAttackInput")] private static class AttackBlockPatch { private static bool Prefix() { if (IsFlying && _blockAttack != null) { return !_blockAttack.Value; } return true; } } [HarmonyPatch(typeof(Humanoid), "OnAttackTrigger")] private static class AttackEventPatch { private static bool Prefix(Humanoid __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { return !(Time.time < _suppressAttackUntil); } return true; } } public const string Guid = "snowfarm.valheim.hammerthrow"; public const string Name = "HammerThrow"; public const string Version = "1.11.0"; private static ManualLogSource _log; private static ConfigEntry<bool> _enabled; private static ConfigEntry<KeyCode> _reloadKey; private static ConfigEntry<float> _maxRange; private static ConfigEntry<float> _outSpeed; private static ConfigEntry<float> _returnSpeed; private static ConfigEntry<float> _damageMultiplier; private static ConfigEntry<float> _hitRadius; private static ConfigEntry<float> _cooldown; private static ConfigEntry<bool> _blockAttack; private static ConfigEntry<string> _overrideAnimation; private static ConfigEntry<KeyCode> _extraKey; private static ConfigEntry<float> _spinSpeed; private static ConfigEntry<float> _spinDirection; private static ConfigEntry<float> _launchFraction; private static ConfigEntry<bool> _launchAtPeak; private static ConfigEntry<float> _launchExtra; private static ConfigEntry<SpinAxisMode> _spinAxis; private static ConfigEntry<float> _modelRoll; private static ConfigEntry<bool> _verbose; private static ConfigEntry<float> _launchDelay; private static ConfigEntry<float> _modelYaw; private static ConfigEntry<float> _staminaMultiplier; private static readonly FieldRef<Humanoid, ItemData> RightItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem"); private static readonly FieldRef<Humanoid, VisEquipment> Vis = AccessTools.FieldRefAccess<Humanoid, VisEquipment>("m_visEquipment"); private static readonly FieldRef<VisEquipment, GameObject> RightInstance = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance"); private static readonly FieldRef<Character, ZSyncAnimation> Zanim = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim"); private static readonly FieldRef<ObjectDB, List<GameObject>> ItemsRef = AccessTools.FieldRefAccess<ObjectDB, List<GameObject>>("m_items"); private static readonly FieldRef<ItemDrop, ItemData> ItemDataRef = AccessTools.FieldRefAccess<ItemDrop, ItemData>("m_itemData"); private static readonly FieldRef<Character, Animator> AnimatorRef = AccessTools.FieldRefAccess<Character, Animator>("m_animator"); private static readonly FieldRef<Player, Skills> PlayerSkills = AccessTools.FieldRefAccess<Player, Skills>("m_skills"); private static HammerThrowPlugin _instance; private static Harmony _harmony; private static ThrowState _throw; private static PendingThrow _pending; private static float _lastThrowTime = -999f; private static float _suppressAttackUntil; private static bool _animsLogged; private static string _oneHandedAnim; private static bool _attacksDumped; private const string MaceHeavyAnimation = "mace_secondary"; private static readonly HashSet<string> ClipNames = new HashSet<string>(); internal static bool IsFlying { get { if (_throw == null) { return _pending != null; } return true; } } private void Awake() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Expected O, but got Unknown //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Expected O, but got Unknown //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Expected O, but got Unknown //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Expected O, but got Unknown //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Expected O, but got Unknown //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Expected O, but got Unknown //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Expected O, but got Unknown //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Expected O, but got Unknown //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Expected O, but got Unknown _log = ((BaseUnityPlugin)this).Logger; _instance = this; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Enable the throwing heavy attack."); _reloadKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("1 - General", "ReloadConfigKey", (KeyCode)291, "Press to reload this file without restarting the game."); _maxRange = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "MaxRange", 25f, new ConfigDescription("How far the hammer flies before turning back (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 60f), Array.Empty<object>())); _outSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "OutSpeed", 26f, new ConfigDescription("Outbound speed (m/s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 80f), Array.Empty<object>())); _returnSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "ReturnSpeed", 34f, new ConfigDescription("Return speed (m/s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 80f), Array.Empty<object>())); _damageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Combat", "DamageMultiplier", 0.75f, new ConfigDescription("Fraction of the weapon's blunt damage dealt on each pass.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>())); _hitRadius = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Combat", "HitRadius", 1.2f, new ConfigDescription("Radius used to hit characters along the flight path.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 4f), Array.Empty<object>())); _cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Combat", "Cooldown", 0.6f, new ConfigDescription("Seconds after catching before it can be thrown again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); _blockAttack = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Combat", "BlockAttackWhileFlying", true, "Prevent attacking until the hammer is back in hand."); _overrideAnimation = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Animation", "ThrowAnimation", "", "Animator trigger for the throw. Empty = use the weapon's own secondary attack."); _launchAtPeak = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "LaunchAtPeak", false, "Throw when the hand reaches the top of the motion (off = use LaunchDelaySeconds)."); _launchExtra = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "LaunchDelaySeconds", 1.3f, new ConfigDescription("Seconds after the throw animation starts before the hammer leaves the hand.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 4f), Array.Empty<object>())); _spinAxis = ((BaseUnityPlugin)this).Config.Bind<SpinAxisMode>("1 - General", "SpinAxis", SpinAxisMode.Tumble, "Which axis the thrown hammer spins around."); _modelRoll = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "ModelRoll", 90f, new ConfigDescription("Extra roll around the flight direction, use 0/90/180/270 to fix the facing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>())); _spinDirection = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "SpinDirection", -1f, new ConfigDescription("1 or -1: which way the hammer tumbles.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), Array.Empty<object>())); _launchFraction = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "LaunchAtAnimationFraction", 1f, new ConfigDescription("How much of the throw animation plays before the hammer leaves the hand (1 = whole animation).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); _launchDelay = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "LaunchDelay", 0.45f, new ConfigDescription("Seconds into the throw animation before the hammer leaves the hand.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); _modelYaw = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "ModelYaw", 0f, new ConfigDescription("Yaw applied to the thrown model so the head faces along the flight path.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>())); _spinSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "SpinSpeed", 720f, new ConfigDescription("Degrees per second the thrown hammer spins.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2160f), Array.Empty<object>())); _verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Debug", "Verbose", false, "Log animation and item dumps (diagnostics)."); _staminaMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Combat", "StaminaMultiplier", 1f, new ConfigDescription("Multiplier for the normal-swing stamina cost of the throw.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); _extraKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("3 - Animation", "ExtraKey", (KeyCode)0, "Optional keyboard key that also triggers the throw (middle mouse always works)."); _harmony = new Harmony("snowfarm.valheim.hammerthrow"); _harmony.PatchAll(typeof(AttackBlockPatch)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"HammerThrow 1.11.0 loaded."); } private void OnDestroy() { Abort("plugin destroyed"); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!_enabled.Value) { if (_throw != null) { Abort("disabled"); } return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { _pending = null; if (_throw != null) { Abort("player gone"); } return; } if (Input.GetKeyDown(_reloadKey.Value)) { ((BaseUnityPlugin)this).Config.Reload(); _log.LogInfo((object)$"[HammerThrow] config reloaded: SpinAxis={_spinAxis.Value} SpinDirection={_spinDirection.Value} ModelRoll={_modelRoll.Value} ModelYaw={_modelYaw.Value} LaunchAtPeak={_launchAtPeak.Value}"); } if (_verbose.Value) { LogAnimationsOnce(localPlayer); } if (_verbose.Value) { DumpClubAttacks(localPlayer); } if (_pending != null) { if (_launchAtPeak.Value && !_pending.PeakHandled && HandReachedPeak(_pending, localPlayer)) { _pending.PeakHandled = true; _pending.LaunchTime = Time.time + Mathf.Max(0f, _launchExtra.Value); } if (Time.time >= _pending.LaunchTime) { PendingThrow pending = _pending; _pending = null; if ((Object)(object)pending.Owner != (Object)null && pending.Weapon != null) { StartFlight(pending.Owner, pending.Weapon); } } } else if (_throw == null) { if (ThrowPressed()) { TryStartThrow(localPlayer); } } else { Advance(localPlayer, Time.deltaTime); } } private static void LogAnimationsOnce(Player player) { if (_animsLogged) { return; } _animsLogged = true; try { Animator val = AnimatorRef.Invoke((Character)(object)player); RuntimeAnimatorController val2 = (((Object)(object)val != (Object)null) ? val.runtimeAnimatorController : null); AnimationClip[] array = (((Object)(object)val2 != (Object)null) ? val2.animationClips : null); if (array == null) { _log.LogInfo((object)"[HammerThrow] animator clips unavailable."); return; } List<string> list = new List<string>(); AnimationClip[] array2 = array; foreach (AnimationClip val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { string text = ((Object)val3).name ?? string.Empty; if (text.IndexOf("throw", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("swing", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("cast", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("sledge", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("hammer", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("attack", StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(text); } } } _log.LogInfo((object)string.Format("[HammerThrow] animation clips ({0}): {1}", list.Count, string.Join(", ", list))); } catch (Exception ex) { _log.LogDebug((object)("[HammerThrow] clip dump failed: " + ex.Message)); } } private bool ThrowPressed() { //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) if (Input.GetMouseButtonDown(2)) { return true; } if ((int)_extraKey.Value != 0) { return Input.GetKeyDown(_extraKey.Value); } return false; } private static bool IsGreatHammer(ItemData item) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if (item == null) { return false; } SharedData shared = item.m_shared; if (shared == null) { return false; } if ((int)shared.m_itemType == 14) { return (int)shared.m_skillType == 3; } return false; } private void TryStartThrow(Player player) { if (Time.time - _lastThrowTime < _cooldown.Value || ((Character)player).InAttack() || _pending != null) { return; } ItemData val = RightItem.Invoke((Humanoid)(object)player); if (!IsGreatHammer(val)) { return; } VisEquipment val2 = Vis.Invoke((Humanoid)(object)player); if ((Object)(object)val2 == (Object)null || (Object)(object)RightInstance.Invoke(val2) == (Object)null) { return; } float throwStaminaCost = GetThrowStaminaCost(player, val); if (!(throwStaminaCost > 0f) || ((Character)player).HaveStamina(throwStaminaCost)) { PlayThrowAnimation(player, val); if (throwStaminaCost > 0f) { ((Character)player).UseStamina(throwStaminaCost); } _lastThrowTime = Time.time; _pending = new PendingThrow { Owner = player, Weapon = val, StartTime = Time.time, LaunchTime = Time.time + (_launchAtPeak.Value ? ComputeLaunchDelay(player, val) : Mathf.Max(0f, _launchExtra.Value)), PeakY = float.MinValue }; } } private static bool HandReachedPeak(PendingThrow pending, Player player) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) VisEquipment val = Vis.Invoke((Humanoid)(object)player); Transform val2 = (((Object)(object)val != (Object)null) ? val.m_rightHand : null); if ((Object)(object)val2 == (Object)null) { return false; } float y = val2.position.y; if (y > pending.PeakY) { pending.PeakY = y; return false; } if (pending.PeakY - y > 0.08f) { return Time.time - pending.StartTime > 0.15f; } return false; } private void StartFlight(Player player, ItemData weapon) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) VisEquipment val = Vis.Invoke((Humanoid)(object)player); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = RightInstance.Invoke(val); if (!((Object)(object)val2 == (Object)null)) { Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 val3 = ((Humanoid)player).GetAimDir(eyePoint); if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = ((Component)player).transform.forward; } ((Vector3)(ref val3)).Normalize(); GameObject val4; try { val4 = Object.Instantiate<GameObject>(val2); } catch (Exception ex) { _log.LogWarning((object)("[HammerThrow] could not clone the weapon visual: " + ex.Message)); return; } ((Object)val4).name = "HammerThrow_Projectile"; val4.transform.SetParent((Transform)null, true); val4.transform.position = val2.transform.position; val4.transform.rotation = Quaternion.AngleAxis(_modelRoll.Value, val3) * (AlignHeadWithFlight(val4, val2, val3) * Quaternion.Euler(0f, _modelYaw.Value, 0f)); if (_verbose.Value) { LogLaunchGeometry(val4, val2, val3); } float num = weapon.GetDamage().m_blunt * _damageMultiplier.Value; if (num <= 0f) { DamageTypes damage = weapon.GetDamage(); num = ((DamageTypes)(ref damage)).GetTotalDamage() * _damageMultiplier.Value; } val2.SetActive(false); NotifyRainbowGear(val4); _throw = new ThrowState { Owner = player, Weapon = weapon, Visual = val4, HiddenOriginal = val2, Direction = val3, Position = val4.transform.position, Damage = num }; _log.LogDebug((object)$"[HammerThrow] launched, damage {num:F1}"); } } private static void LogLaunchGeometry(GameObject clone, GameObject original, Vector3 dir) { //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_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_003e: 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_0045: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00b1: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0146: 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_0170: Unknown result type (might be due to invalid IL or missing references) try { Renderer val = LargestRenderer(clone); if ((Object)(object)val == (Object)null) { _log.LogInfo((object)"[HammerThrow] geometry: no renderer found"); return; } Transform transform = clone.transform; Bounds bounds = val.bounds; Vector3 val2 = transform.InverseTransformPoint(((Bounds)(ref bounds)).center); bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; Quaternion rotation = clone.transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; _log.LogInfo((object)($"[HammerThrow] geometry: renderer='{((Object)val).name}' size=({size.x:F2},{size.y:F2},{size.z:F2}) " + $"headLocal=({val2.x:F2},{val2.y:F2},{val2.z:F2}) " + $"dir=({dir.x:F2},{dir.y:F2},{dir.z:F2}) resultEuler=({eulerAngles.x:F1},{eulerAngles.y:F1},{eulerAngles.z:F1}) " + $"localEuler=({((Component)val).transform.localEulerAngles.x:F1},{((Component)val).transform.localEulerAngles.y:F1},{((Component)val).transform.localEulerAngles.z:F1})")); } catch (Exception ex) { _log.LogInfo((object)("[HammerThrow] geometry log failed: " + ex.Message)); } } private static Quaternion AlignHeadWithFlight(GameObject clone, GameObject original, Vector3 dir) { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0082: 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) try { Renderer val = LargestRenderer(clone); if ((Object)(object)val != (Object)null) { Transform transform = clone.transform; Bounds bounds = val.bounds; Vector3 val2 = transform.InverseTransformPoint(((Bounds)(ref bounds)).center); if (((Vector3)(ref val2)).sqrMagnitude > 0.0004f) { Vector3 normalized = ((Vector3)(ref val2)).normalized; Vector3 val3 = ((Mathf.Abs(Vector3.Dot(normalized, Vector3.up)) > 0.9f) ? Vector3.forward : Vector3.up); Quaternion val4 = Quaternion.LookRotation(normalized, val3); return Quaternion.LookRotation(dir, Vector3.up) * Quaternion.Inverse(val4); } } } catch (Exception ex) { _log.LogDebug((object)("[HammerThrow] head alignment failed: " + ex.Message)); } return Quaternion.LookRotation(dir); } private static Renderer LargestRenderer(GameObject item) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0045: 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_004e: 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) Renderer result = null; float num = 0f; Renderer[] componentsInChildren = item.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(val is ParticleSystemRenderer) && !(val is TrailRenderer)) { Bounds bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float num2 = size.x * size.y * size.z; if (num2 > num) { num = num2; result = val; } } } return result; } private static float ComputeLaunchDelay(Player player, ItemData weapon) { float num = Mathf.Max(0f, _launchFraction.Value); float clipLength = GetClipLength(player, "MaceAltAttack"); if (clipLength <= 0.05f) { return Mathf.Max(0f, _launchDelay.Value); } return clipLength * num; } private static float GetClipLength(Player player, string clipName) { try { Animator val = AnimatorRef.Invoke((Character)(object)player); RuntimeAnimatorController val2 = (((Object)(object)val != (Object)null) ? val.runtimeAnimatorController : null); AnimationClip[] array = (((Object)(object)val2 != (Object)null) ? val2.animationClips : null); if (array == null) { return -1f; } AnimationClip[] array2 = array; foreach (AnimationClip val3 in array2) { if (!((Object)(object)val3 == (Object)null) && ((Object)val3).name == clipName) { return val3.length; } } } catch (Exception ex) { _log.LogDebug((object)("[HammerThrow] clip length lookup failed: " + ex.Message)); } return -1f; } private static float GetThrowStaminaCost(Player player, ItemData weapon) { float num = ((weapon != null && weapon.m_shared != null) ? weapon.m_shared.m_attack : null)?.m_attackStamina ?? 0f; if (num <= 0f) { return 0f; } float equipmentAttackStaminaModifier = ((Character)player).GetEquipmentAttackStaminaModifier(); if (equipmentAttackStaminaModifier > 0f) { num *= equipmentAttackStaminaModifier; } return num * _staminaMultiplier.Value; } private static string OneHandedClubThrowAnimation() { if (_oneHandedAnim != null) { return _oneHandedAnim; } string[] array = new string[5] { "Club", "IronMace", "BronzeMace", "Frostner", "Porcupine" }; foreach (string text in array) { try { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(text) : null); if ((Object)(object)val == (Object)null) { continue; } ItemDrop component = val.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { ItemData val2 = ItemDataRef.Invoke(component); string text2 = ((val2 != null && val2.m_shared != null) ? val2.m_shared.m_secondaryAttack : null)?.m_attackAnimation; if (!string.IsNullOrEmpty(text2)) { _oneHandedAnim = text2; _log.LogInfo((object)("[HammerThrow] throw animation from '" + text + "': " + text2)); return _oneHandedAnim; } } } catch (Exception ex) { _log.LogDebug((object)("[HammerThrow] prefab lookup failed for '" + text + "': " + ex.Message)); } } _oneHandedAnim = string.Empty; return _oneHandedAnim; } private static void DumpClubAttacks(Player player) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Invalid comparison between Unknown and I4 //IL_01a6: Unknown result type (might be due to invalid IL or missing references) if (_attacksDumped) { return; } _attacksDumped = true; try { Animator val = AnimatorRef.Invoke((Character)(object)player); if ((Object)(object)val != (Object)null) { List<string> list = new List<string>(); AnimatorControllerParameter[] parameters = val.parameters; foreach (AnimatorControllerParameter val2 in parameters) { list.Add($"{val2.name}:{val2.type}"); } _log.LogInfo((object)string.Format("[HammerThrow] animator parameters ({0}): {1}", list.Count, string.Join(", ", list))); } ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { _log.LogInfo((object)"[HammerThrow] ObjectDB.instance is null."); return; } List<GameObject> list2 = ItemsRef.Invoke(instance); if (list2 == null) { _log.LogInfo((object)"[HammerThrow] ObjectDB item list unavailable."); return; } List<string> list3 = new List<string>(); foreach (GameObject item in list2) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { SharedData val3 = ItemDataRef.Invoke(component)?.m_shared; if (val3 != null && (int)val3.m_skillType == 3) { string text = ((val3.m_attack != null) ? val3.m_attack.m_attackAnimation : ""); string text2 = ((val3.m_secondaryAttack != null) ? val3.m_secondaryAttack.m_attackAnimation : ""); list3.Add($"{((Object)item).name}[{val3.m_itemType}] primary='{text}' secondary='{text2}'"); } } } _log.LogInfo((object)string.Format("[HammerThrow] club items ({0}): {1}", list3.Count, string.Join(" | ", list3))); } catch (Exception ex) { _log.LogInfo((object)("[HammerThrow] club dump failed: " + ex.Message)); } } private static bool HasClip(Player player, string clipName) { if (ClipNames.Contains(clipName)) { return true; } try { Animator val = AnimatorRef.Invoke((Character)(object)player); RuntimeAnimatorController val2 = (((Object)(object)val != (Object)null) ? val.runtimeAnimatorController : null); AnimationClip[] array = (((Object)(object)val2 != (Object)null) ? val2.animationClips : null); if (array == null) { return false; } AnimationClip[] array2 = array; foreach (AnimationClip val3 in array2) { if ((Object)(object)val3 != (Object)null && ((Object)val3).name == clipName) { ClipNames.Add(clipName); return true; } } } catch (Exception ex) { _log.LogDebug((object)("[HammerThrow] clip check failed: " + ex.Message)); } return false; } private static void PlayThrowAnimation(Player player, ItemData weapon) { string text = _overrideAnimation.Value; if (string.IsNullOrEmpty(text)) { text = "mace_secondary"; } if (string.IsNullOrEmpty(text)) { text = OneHandedClubThrowAnimation(); } if (string.IsNullOrEmpty(text)) { Attack val = weapon?.m_shared?.m_secondaryAttack; if (val != null) { text = val.m_attackAnimation; } if (string.IsNullOrEmpty(text)) { Attack val2 = weapon?.m_shared?.m_attack; if (val2 != null) { text = val2.m_attackAnimation; } } } if (!string.IsNullOrEmpty(text)) { ZSyncAnimation val3 = Zanim.Invoke((Character)(object)player); if ((Object)(object)val3 != (Object)null) { val3.SetTrigger(text); } _suppressAttackUntil = Time.time + 3f; } } private static void NotifyRainbowGear(GameObject visual) { try { (Type.GetType("RainbowGear.RainbowGearPlugin, RainbowGear")?.GetMethod("RegisterExtra", BindingFlags.Static | BindingFlags.Public))?.Invoke(null, new object[1] { visual }); } catch (Exception ex) { _log.LogDebug((object)("[HammerThrow] RainbowGear not notified: " + ex.Message)); } } private void Advance(Player player, float dt) { //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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) ThrowState throwState = _throw; if (throwState == null) { return; } if ((Object)(object)throwState.Visual == (Object)null || (Object)(object)throwState.Owner == (Object)null) { Abort("visual lost"); return; } VisEquipment val = Vis.Invoke((Humanoid)(object)player); Transform val2 = (((Object)(object)val != (Object)null && (Object)(object)val.m_rightHand != (Object)null) ? val.m_rightHand : ((Component)player).transform); if (throwState.Returning) { Vector3 val3 = val2.position - throwState.Position; float num = _returnSpeed.Value * dt; if (((Vector3)(ref val3)).magnitude <= Mathf.Max(num, 1.1f)) { Catch("returned"); return; } throwState.Position += ((Vector3)(ref val3)).normalized * num; } else { float num2 = _outSpeed.Value * dt; if (HitObstacle(throwState.Position, throwState.Direction, num2 + 0.4f)) { throwState.Returning = true; } else { throwState.Position += throwState.Direction * num2; throwState.Travelled += num2; if (throwState.Travelled >= _maxRange.Value) { throwState.Returning = true; } } } throwState.Visual.transform.position = throwState.Position; Vector3 val4 = (Vector3)(_spinAxis.Value switch { SpinAxisMode.Roll => throwState.Direction, SpinAxisMode.Yaw => Vector3.up, _ => Vector3.Cross(Vector3.up, throwState.Direction), }); if (((Vector3)(ref val4)).sqrMagnitude < 0.001f) { val4 = Vector3.right; } ((Vector3)(ref val4)).Normalize(); throwState.Visual.transform.Rotate(val4, _spinDirection.Value * _spinSpeed.Value * dt, (Space)0); DamageAlong(throwState); } private static bool HitObstacle(Vector3 from, Vector3 dir, float distance) { //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) int num = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "piece_nonsolid" }); if (num == 0) { num = -5; } return Physics.Raycast(from, dir, distance, num, (QueryTriggerInteraction)1); } private static void DamageAlong(ThrowState state) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_00b9: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) Player owner = state.Owner; if ((Object)(object)owner == (Object)null) { return; } Collider[] array = Physics.OverlapSphere(state.Position, _hitRadius.Value, -1, (QueryTriggerInteraction)1); HashSet<ZDOID> hashSet = (state.Returning ? state.HitBack : state.HitOut); HashSet<int> hashSet2 = (state.Returning ? state.BirdHitsBack : state.BirdHitsOut); Collider[] array2 = array; foreach (Collider val in array2) { if ((Object)(object)val == (Object)null) { continue; } Character componentInParent = ((Component)val).GetComponentInParent<Character>(); if ((Object)(object)componentInParent != (Object)null) { if (!((Object)(object)componentInParent == (Object)(object)owner) && !componentInParent.IsDead() && (!componentInParent.IsPlayer() || ((Character)owner).IsPVPEnabled())) { ZDOID zDOID = componentInParent.GetZDOID(); if (hashSet.Add(zDOID)) { componentInParent.Damage(BuildHit(owner, state, componentInParent.GetCenterPoint())); SpawnHitEffect(state, componentInParent.GetCenterPoint()); } } continue; } RandomFlyingBird componentInParent2 = ((Component)val).GetComponentInParent<RandomFlyingBird>(); if ((Object)(object)componentInParent2 == (Object)null) { continue; } IDestructible componentInParent3 = ((Component)val).GetComponentInParent<IDestructible>(); if (componentInParent3 != null) { int instanceID = ((Object)((Component)componentInParent2).transform.root).GetInstanceID(); if (hashSet2.Add(instanceID)) { Vector3 position = ((Component)componentInParent2).transform.position; componentInParent3.Damage(BuildHit(owner, state, position)); SpawnHitEffect(state, position); } } } } private static void SpawnHitEffect(ThrowState state, Vector3 point) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) SharedData val = ((state.Weapon != null) ? state.Weapon.m_shared : null); if (val == null) { return; } Attack val2 = val.m_secondaryAttack ?? val.m_attack; if (val2 != null) { EffectList val3 = val2.m_hitTerrainEffect; if (val3 == null || !val3.HasEffects()) { val3 = val2.m_hitEffect; } if (val3 != null && val3.HasEffects()) { val3.Create(point, Quaternion.LookRotation(state.Direction), (Transform)null, 1f, -1, default(ZDOID)); } } } private static HitData BuildHit(Player player, ThrowState state, Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_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_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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) //IL_0040: 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_0047: 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_0064: 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) //IL_0081: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown HitData val = new HitData { m_damage = new DamageTypes { m_blunt = state.Damage }, m_attacker = ((Character)player).GetZDOID(), m_point = point, m_dir = state.Direction, m_skill = (SkillType)3, m_skillRaiseAmount = 1f, m_itemLevel = (short)state.Weapon.m_quality, m_pushForce = 0f, m_backstabBonus = 1f, m_blockable = true, m_dodgeable = true, m_ranged = true, m_hitType = (HitType)2, m_staggerMultiplier = 1f }; Skills val2 = PlayerSkills.Invoke(player); if ((Object)(object)val2 != (Object)null) { val.m_skillLevel = val2.GetSkillLevel((SkillType)3); } return val; } private void Catch(string reason) { ThrowState throwState = _throw; _throw = null; if (throwState != null) { if ((Object)(object)throwState.Visual != (Object)null) { Object.Destroy((Object)(object)throwState.Visual); } if ((Object)(object)throwState.HiddenOriginal != (Object)null) { throwState.HiddenOriginal.SetActive(true); } _lastThrowTime = Time.time; _log.LogDebug((object)("[HammerThrow] caught (" + reason + ")")); } } private void Abort(string reason) { ThrowState throwState = _throw; _throw = null; if (throwState != null) { if ((Object)(object)throwState.Visual != (Object)null) { Object.Destroy((Object)(object)throwState.Visual); } if ((Object)(object)throwState.HiddenOriginal != (Object)null) { throwState.HiddenOriginal.SetActive(true); } _log.LogDebug((object)("[HammerThrow] aborted (" + reason + ")")); } } } }