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 ShieldBash v1.5.2
BepInEx/plugins/ShieldBash/ShieldBash.dll
Decompiled 3 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Managers; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Playables; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ShieldBash")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ShieldBash")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("be1580d5-2dda-4cf4-b5c8-d4f902314e67")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace ShieldBashMod; [BepInPlugin("alexbez.valheim.shieldbash", "ShieldBash", "2.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ShieldBashPlugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <AntiSlideRoutine>d__76 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Player player; public float duration; public ShieldBashPlugin <>4__this; private Rigidbody <body>5__1; private float <t>5__2; private Vector3 <v>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AntiSlideRoutine>d__76(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <body>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!Object.op_Implicit((Object)(object)player)) { return false; } <body>5__1 = null; try { <body>5__1 = CharacterBody.Invoke((Character)(object)player); } catch { } if (!Object.op_Implicit((Object)(object)<body>5__1)) { return false; } <t>5__2 = 0f; try { CharacterMoveDir.Invoke((Character)(object)player) = Vector3.zero; } catch { } <body>5__1.linearVelocity = Vector3.zero; break; case 1: <>1__state = -1; break; } if (<t>5__2 < duration && Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)<body>5__1)) { <v>5__3 = <body>5__1.linearVelocity; <v>5__3.x = 0f; <v>5__3.z = 0f; <body>5__1.linearVelocity = <v>5__3; try { CharacterMoveDir.Invoke((Character)(object)player) = Vector3.zero; } catch { } <t>5__2 += Time.deltaTime; <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <DoBash>d__75 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Player player; public Animator animator; public AnimationClip clip; public ShieldBashPlugin <>4__this; private bool <prevRootMotion>5__1; private PlayableGraph <graph>5__2; private AnimatorControllerPlayable <controllerPlayable>5__3; private AnimationClipPlayable <clipPlayable>5__4; private AnimationLayerMixerPlayable <mixer>5__5; private AnimationPlayableOutput <output>5__6; private float <hitAt>5__7; private float <remain>5__8; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DoBash>d__75(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } <>1__state = -2; } private bool MoveNext() { //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //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_010f: 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_0122: 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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (<>4__this.AntiSlideTime.Value > 0.0001f) { ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.AntiSlideRoutine(player, <>4__this.AntiSlideTime.Value)); } <prevRootMotion>5__1 = animator.applyRootMotion; animator.applyRootMotion = false; <graph>5__2 = PlayableGraph.Create("ShieldBashGraph"); <>1__state = -3; <controllerPlayable>5__3 = AnimatorControllerPlayable.Create(<graph>5__2, animator.runtimeAnimatorController); <clipPlayable>5__4 = AnimationClipPlayable.Create(<graph>5__2, clip); ((AnimationClipPlayable)(ref <clipPlayable>5__4)).SetApplyFootIK(false); ((AnimationClipPlayable)(ref <clipPlayable>5__4)).SetApplyPlayableIK(false); <mixer>5__5 = AnimationLayerMixerPlayable.Create(<graph>5__2, 2); ((PlayableGraph)(ref <graph>5__2)).Connect<AnimatorControllerPlayable, AnimationLayerMixerPlayable>(<controllerPlayable>5__3, 0, <mixer>5__5, 0); ((PlayableGraph)(ref <graph>5__2)).Connect<AnimationClipPlayable, AnimationLayerMixerPlayable>(<clipPlayable>5__4, 0, <mixer>5__5, 1); PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(<mixer>5__5, 0, 1f); PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(<mixer>5__5, 1, 1f); <output>5__6 = AnimationPlayableOutput.Create(<graph>5__2, "ShieldBashOutput", animator); PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationLayerMixerPlayable>(<output>5__6, <mixer>5__5); ((PlayableGraph)(ref <graph>5__2)).Play(); <hitAt>5__7 = Mathf.Clamp(<>4__this.HitDelay.Value, 0.01f, Mathf.Max(0.01f, clip.length)); <>2__current = (object)new WaitForSeconds(<hitAt>5__7); <>1__state = 1; return true; case 1: <>1__state = -3; <>4__this.ApplyBashDamageAndSfx(player); <remain>5__8 = Mathf.Max(0.01f, clip.length - <hitAt>5__7); <>2__current = (object)new WaitForSeconds(<remain>5__8); <>1__state = 2; return true; case 2: <>1__state = -3; <>m__Finally1(); return false; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (((PlayableGraph)(ref <graph>5__2)).IsValid()) { ((PlayableGraph)(ref <graph>5__2)).Destroy(); } animator.applyRootMotion = <prevRootMotion>5__1; } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGUID = "alexbez.valheim.shieldbash"; public const string PluginName = "ShieldBash"; public const string PluginVersion = "2.2.0"; private const string ButtonName = "ShieldBash"; internal static ShieldBashPlugin Instance; internal ConfigEntry<KeyCode> BashKey; internal ConfigEntry<float> Cooldown; internal ConfigEntry<bool> RequireShield; internal ConfigEntry<float> StaminaCost; internal ConfigEntry<float> AntiSlideTime; internal ConfigEntry<float> BaseDamage; internal ConfigEntry<float> BlockPowerScale; internal ConfigEntry<float> QualityBonusPerLevel; internal ConfigEntry<float> MinDamage; internal ConfigEntry<float> MaxDamage; internal ConfigEntry<float> BlockingSkillMultiplier; internal ConfigEntry<float> DamageRandomMin; internal ConfigEntry<float> DamageRandomMax; internal ConfigEntry<float> CenterHitBonusMax; internal ConfigEntry<float> HitDelay; internal ConfigEntry<float> Range; internal ConfigEntry<float> Radius; internal ConfigEntry<float> PushForce; internal ConfigEntry<float> Angle; internal ConfigEntry<bool> LineOfSightCheck; internal ConfigEntry<int> MaxLoSRaycastsPerBash; internal ConfigEntry<bool> HitTamed; internal ConfigEntry<bool> HitPlayers; internal ConfigEntry<int> OverlapBufferSize; internal ConfigEntry<bool> ShowShieldBashInTooltip; internal ConfigEntry<bool> DebugLog; internal ConfigEntry<bool> DebugLogDamageAfterArmor; internal ConfigEntry<bool> DamageWorldObjects; internal ConfigEntry<float> WorldDamageScale; internal ConfigEntry<bool> WorldDamageUseRandom; internal ConfigEntry<string> HitClipName; internal ConfigEntry<string> MissClipName; internal ConfigEntry<bool> PlayHitSfxPerTarget; internal ConfigEntry<float> HitSfxVolumeMin; internal ConfigEntry<float> HitSfxVolumeMax; internal ConfigEntry<float> MissSfxVolume; internal ConfigEntry<float> RandomVolJitterMin; internal ConfigEntry<float> RandomVolJitterMax; internal ConfigEntry<float> RandomPitchJitterMin; internal ConfigEntry<float> RandomPitchJitterMax; internal ConfigEntry<float> MetalVolumeMul; internal ConfigEntry<float> WoodVolumeMul; internal ConfigEntry<float> MetalPitchMul; internal ConfigEntry<float> WoodPitchMul; internal ConfigEntry<float> MultiHitBonusMin; internal ConfigEntry<float> MultiHitBonusMax; internal ConfigEntry<float> LocalClipVolumeMul; private ButtonConfig _bashButton; private Harmony _harmony; private AnimationClip _bashClip; private AudioClip _hitClip; private AudioClip _missClip; private float _nextUseTime; private Collider[] _overlapCols; private int[] _hitOnceIds; private int _hitOnceCount; private int _overlapMask = -1; private int _losWorldMask = -1; private int _losCharMask = -1; private float _cachedAngle = -999f; private float _cachedCosHalf = -2f; private AudioSource _localSfxSource; private static readonly FieldRef<Character, Animator> CharacterAnimator = AccessTools.FieldRefAccess<Character, Animator>("m_animator"); private static readonly FieldRef<Character, Rigidbody> CharacterBody = AccessTools.FieldRefAccess<Character, Rigidbody>("m_body"); private static readonly FieldRef<Character, Vector3> CharacterMoveDir = AccessTools.FieldRefAccess<Character, Vector3>("m_moveDir"); private static readonly FieldRef<Humanoid, ItemData> HumanoidLeftItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_leftItem"); private void Awake() { //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06a6: Unknown result type (might be due to invalid IL or missing references) //IL_06b2: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06c4: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Expected O, but got Unknown //IL_06f8: Unknown result type (might be due to invalid IL or missing references) //IL_0702: Expected O, but got Unknown Instance = this; BashKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Input", "BashKey", (KeyCode)102, "Key for Shield Bash"); Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "Cooldown", 0.9f, "Cooldown seconds"); RequireShield = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "RequireShield", true, "Require shield in left hand"); StaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "StaminaCost", 18f, "Stamina cost per bash (no message if insufficient)"); AntiSlideTime = ((BaseUnityPlugin)this).Config.Bind<float>("Feel", "AntiSlideTime", 0.2f, "Anti-slide duration seconds (0 = off)"); BaseDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BaseDamage", 10f, "Flat blunt damage added to bash"); BlockPowerScale = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BlockPowerScale", 0.6f, "Damage per 1 shield block power"); QualityBonusPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "QualityBonusPerLevel", 0.8f, "Soft bonus damage per shield upgrade level (quality-1)"); MinDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "MinDamage", 6f, "Minimum final damage (after multipliers)"); MaxDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "MaxDamage", 45f, "Maximum final damage cap (after multipliers)"); BlockingSkillMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BlockingSkillMultiplier", 0.35f, "Damage multiplier from Blocking skill: damage *= 1 + skillFactor(0..1) * value"); DamageRandomMin = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "DamageRandomMin", 0.92f, "Per-bash random damage multiplier min (vanilla-like variability)."); DamageRandomMax = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "DamageRandomMax", 1.08f, "Per-bash random damage multiplier max (vanilla-like variability)."); CenterHitBonusMax = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "CenterHitBonusMax", 0.12f, "Up to +X% damage when target is centered in cone."); HitDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "HitDelay", 0.12f, "Seconds after animation start when damage is applied"); DamageWorldObjects = ((BaseUnityPlugin)this).Config.Bind<bool>("WorldDamage", "DamageWorldObjects", true, "Allow Shield Bash to damage trees/rocks/buildings like vanilla weapons"); WorldDamageScale = ((BaseUnityPlugin)this).Config.Bind<float>("WorldDamage", "WorldDamageScale", 0.85f, "Multiplier for world-object damage (trees/rocks/buildings)."); WorldDamageUseRandom = ((BaseUnityPlugin)this).Config.Bind<bool>("WorldDamage", "WorldDamageUseRandom", false, "If true: world damage also uses per-bash random multiplier (default false)."); Range = ((BaseUnityPlugin)this).Config.Bind<float>("Hitbox", "Range", 1.6f, "Forward distance of hit center"); Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Hitbox", "Radius", 0.9f, "Hit radius (capsule radius)"); PushForce = ((BaseUnityPlugin)this).Config.Bind<float>("Hitbox", "PushForce", 20f, "Push force applied to Characters"); Angle = ((BaseUnityPlugin)this).Config.Bind<float>("Hitbox", "AngleDegrees", 110f, "Cone angle filter (degrees). 180 = no cone."); LineOfSightCheck = ((BaseUnityPlugin)this).Config.Bind<bool>("Hitbox", "LineOfSightCheck", true, "Raycast visibility check (avoid hitting through walls)"); MaxLoSRaycastsPerBash = ((BaseUnityPlugin)this).Config.Bind<int>("Hitbox", "MaxLoSRaycastsPerBash", 6, "Max LoS raycasts per bash (CPU saver in crowds)."); HitTamed = ((BaseUnityPlugin)this).Config.Bind<bool>("Targets", "HitTamed", false, "Hit tamed creatures"); HitPlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("Targets", "HitPlayers", false, "Hit other players (PvP)"); OverlapBufferSize = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "OverlapBufferSize", 64, "NonAlloc overlap collider buffer size (64/96/128)"); ShowShieldBashInTooltip = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowShieldBashInTooltip", true, "Add Shield Bash damage lines near block power in shield tooltip"); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Log", false, "General debug logging"); DebugLogDamageAfterArmor = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogDamageAfterArmor", false, "Log actual dealt damage (HP delta) per hit target"); HitClipName = ((BaseUnityPlugin)this).Config.Bind<string>("SFX", "HitClipName", "shield_bash_hit", "AudioClip.name inside AssetBundle for HIT sound."); MissClipName = ((BaseUnityPlugin)this).Config.Bind<string>("SFX", "MissClipName", "shield_bash_miss", "AudioClip.name inside AssetBundle for MISS sound."); PlayHitSfxPerTarget = ((BaseUnityPlugin)this).Config.Bind<bool>("SFX", "PlayHitSfxPerTarget", false, "If true: play hit sound for each target (heavier)."); HitSfxVolumeMin = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "HitSfxVolumeMin", 0.6f, "Min hit volume at MinDamage."); HitSfxVolumeMax = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "HitSfxVolumeMax", 1.1f, "Max hit volume at MaxDamage."); MissSfxVolume = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "MissSfxVolume", 0.7f, "Base miss whoosh volume."); RandomVolJitterMin = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "RandomVolJitterMin", 0.95f, "Random volume multiplier min."); RandomVolJitterMax = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "RandomVolJitterMax", 1.05f, "Random volume multiplier max."); RandomPitchJitterMin = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "RandomPitchJitterMin", 0.97f, "Random pitch multiplier min."); RandomPitchJitterMax = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "RandomPitchJitterMax", 1.03f, "Random pitch multiplier max."); MetalVolumeMul = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "MetalVolumeMul", 1.07f, "Volume multiplier for metal shields."); WoodVolumeMul = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "WoodVolumeMul", 0.92f, "Volume multiplier for wood shields."); MetalPitchMul = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "MetalPitchMul", 1.02f, "Pitch multiplier for metal shields."); WoodPitchMul = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "WoodPitchMul", 0.96f, "Pitch multiplier for wood shields."); MultiHitBonusMin = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "MultiHitBonusMin", 0.05f, "Bonus volume add when hits>1, min."); MultiHitBonusMax = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "MultiHitBonusMax", 0.1f, "Bonus volume add when hits>1, max."); LocalClipVolumeMul = ((BaseUnityPlugin)this).Config.Bind<float>("SFX", "LocalClipVolumeMul", 1f, "Multiplier for local AudioClips."); _bashButton = new ButtonConfig { Name = "ShieldBash", Key = BashKey.Value, HintToken = "Shield Bash" }; InputManager.Instance.AddButton("alexbez.valheim.shieldbash", _bashButton); EnsureBuffers(); _harmony = new Harmony("alexbez.valheim.shieldbash"); _harmony.PatchAll(); bool flag = LoadAssetsFromBundle(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Assets loaded: {1} (anim={2}, hit={3}, miss={4})", "ShieldBash", flag, Object.op_Implicit((Object)(object)_bashClip) ? ((Object)_bashClip).name : "null", Object.op_Implicit((Object)(object)_hitClip) ? ((Object)_hitClip).name : "null", Object.op_Implicit((Object)(object)_missClip) ? ((Object)_missClip).name : "null")); } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } try { if (Object.op_Implicit((Object)(object)_localSfxSource) && Object.op_Implicit((Object)(object)((Component)_localSfxSource).gameObject)) { Object.Destroy((Object)(object)((Component)_localSfxSource).gameObject); } } catch { } } private void EnsureBuffers() { int num = Mathf.Clamp(OverlapBufferSize.Value, 16, 256); if (_overlapCols == null || _overlapCols.Length != num) { _overlapCols = (Collider[])(object)new Collider[num]; } int num2 = Mathf.Clamp(num * 2, 32, 1024); if (_hitOnceIds == null || _hitOnceIds.Length != num2) { _hitOnceIds = new int[num2]; } _hitOnceCount = 0; } private void Update() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) EnsureBuffers(); if (!Input.GetKeyDown(BashKey.Value)) { return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || Time.time < _nextUseTime) { return; } if ((Object)(object)_bashClip == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ShieldBash] Bash clip is null. Bundle/clip not loaded."); } else if ((!RequireShield.Value || HasShieldInLeftHand(localPlayer)) && TryUseStaminaNoMessage(localPlayer, StaminaCost.Value)) { Animator animator = GetAnimator((Character)(object)localPlayer); if (Object.op_Implicit((Object)(object)animator)) { _nextUseTime = Time.time + Cooldown.Value; ((MonoBehaviour)this).StartCoroutine(DoBash(localPlayer, animator, _bashClip)); } } } [IteratorStateMachine(typeof(<DoBash>d__75))] private IEnumerator DoBash(Player player, Animator animator, AnimationClip clip) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DoBash>d__75(0) { <>4__this = this, player = player, animator = animator, clip = clip }; } [IteratorStateMachine(typeof(<AntiSlideRoutine>d__76))] private IEnumerator AntiSlideRoutine(Player player, float duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AntiSlideRoutine>d__76(0) { <>4__this = this, player = player, duration = duration }; } private bool TryUseStaminaNoMessage(Player player, float cost) { if (cost <= 0f) { return true; } if (player.GetStamina() + 0.001f < cost) { return false; } ((Character)player).UseStamina(cost); return true; } internal float ComputeShieldBaseDamage(ItemData shield) { int num = 1; float num2 = 0f; if (shield != null && shield.m_shared != null) { num = Mathf.Max(1, shield.m_quality); num2 = shield.m_shared.m_blockPower + shield.m_shared.m_blockPowerPerLevel * (float)(num - 1); } return BaseDamage.Value + num2 * BlockPowerScale.Value + (float)Mathf.Max(0, num - 1) * Mathf.Max(0f, QualityBonusPerLevel.Value); } private float GetBlockingSkillFactor(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return 0f; } try { return Mathf.Clamp01(((Character)player).GetSkillFactor((SkillType)6)); } catch { return 0f; } } private float ApplySkillAndRandom(float baseDamage, float skillFactor, float randMul) { float num = Mathf.Max(0f, BlockingSkillMultiplier.Value); float num2 = baseDamage * (1f + skillFactor * num); num2 *= randMul; return Mathf.Clamp(num2, MinDamage.Value, MaxDamage.Value); } private float GetCenterBonus01(float dotForward, float cosHalf) { if (dotForward <= cosHalf) { return 0f; } if (cosHalf >= 0.9999f) { return 1f; } return Mathf.Clamp01((dotForward - cosHalf) / (1f - cosHalf)); } private int GetOverlapMask() { if (_overlapMask != -1) { return _overlapMask; } _overlapMask = LayerMask.GetMask(new string[7] { "character", "character_net", "Default", "static_solid", "piece", "Hitbox", "hitbox" }); if (_overlapMask == 0) { _overlapMask = -1; } return _overlapMask; } private int GetWorldLosMask() { if (_losWorldMask != -1) { return _losWorldMask; } _losWorldMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "piece", "Hitbox", "hitbox", "character", "character_net" }); if (_losWorldMask == 0) { _losWorldMask = -1; } return _losWorldMask; } private int GetCharacterOnlyLosMask() { if (_losCharMask != -1) { return _losCharMask; } _losCharMask = LayerMask.GetMask(new string[4] { "character", "character_net", "Hitbox", "hitbox" }); if (_losCharMask == 0) { _losCharMask = -1; } return _losCharMask; } private float GetCosHalfAngle() { float num = Mathf.Clamp(Angle.Value, 1f, 180f); if (Mathf.Abs(num - _cachedAngle) < 0.001f && _cachedCosHalf > -1f) { return _cachedCosHalf; } _cachedAngle = num; _cachedCosHalf = Mathf.Cos(num * ((float)Math.PI / 180f) * 0.5f); return _cachedCosHalf; } private void HitOnceReset() { _hitOnceCount = 0; } private bool HitOnceTryAdd(int id) { for (int i = 0; i < _hitOnceCount; i++) { if (_hitOnceIds[i] == id) { return false; } } if (_hitOnceCount >= _hitOnceIds.Length) { return false; } _hitOnceIds[_hitOnceCount++] = id; return true; } private void ApplyBashDamageAndSfx(Player player) { //IL_0195: 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_01a2: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_07bb: Unknown result type (might be due to invalid IL or missing references) //IL_07c6: Unknown result type (might be due to invalid IL or missing references) //IL_07d0: Unknown result type (might be due to invalid IL or missing references) //IL_07d5: Unknown result type (might be due to invalid IL or missing references) //IL_07da: Unknown result type (might be due to invalid IL or missing references) //IL_07e4: Unknown result type (might be due to invalid IL or missing references) //IL_07e9: Unknown result type (might be due to invalid IL or missing references) //IL_07ee: Unknown result type (might be due to invalid IL or missing references) //IL_081d: Unknown result type (might be due to invalid IL or missing references) //IL_066c: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_07a5: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_069d: Unknown result type (might be due to invalid IL or missing references) //IL_06d8: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0353: 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_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0395: 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_039c: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: 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_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: 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_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04de: 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_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_0504: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_051f: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Expected O, but got Unknown //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: 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_0605: Unknown result type (might be due to invalid IL or missing references) //IL_0640: Unknown result type (might be due to invalid IL or missing references) HitOnceReset(); ItemData leftItem = GetLeftItem((Humanoid)(object)player); float num = ComputeShieldBaseDamage(leftItem); float num2 = Mathf.Min(DamageRandomMin.Value, DamageRandomMax.Value); float num3 = Mathf.Max(DamageRandomMin.Value, DamageRandomMax.Value); float num4 = Random.Range(num2, num3); float blockingSkillFactor = GetBlockingSkillFactor(player); float num5 = ApplySkillAndRandom(num, blockingSkillFactor, num4); float randMul = (WorldDamageUseRandom.Value ? num4 : 1f); float num6 = ApplySkillAndRandom(num, blockingSkillFactor, randMul) * Mathf.Clamp(WorldDamageScale.Value, 0f, 5f); float num7 = Mathf.Clamp01(Mathf.InverseLerp(MinDamage.Value, MaxDamage.Value, num5)); float num8 = Mathf.Lerp(HitSfxVolumeMin.Value, HitSfxVolumeMax.Value, num7); float num9 = Mathf.Max(0f, MissSfxVolume.Value); GetMaterialMix(leftItem, out var volMul, out var pitchMul); float num10 = Random.Range(Mathf.Min(RandomVolJitterMin.Value, RandomVolJitterMax.Value), Mathf.Max(RandomVolJitterMin.Value, RandomVolJitterMax.Value)); float num11 = Random.Range(Mathf.Min(RandomPitchJitterMin.Value, RandomPitchJitterMax.Value), Mathf.Max(RandomPitchJitterMin.Value, RandomPitchJitterMax.Value)); Vector3 forward = ((Component)player).transform.forward; Vector3 val = ((Component)player).transform.position + Vector3.up * 1.3f; Vector3 val2 = ((Component)player).transform.position + forward * Range.Value; Vector3 val3 = val2 + Vector3.up * 0.6f; Vector3 val4 = val2 + Vector3.up * 1.6f; int overlapMask = GetOverlapMask(); float cosHalfAngle = GetCosHalfAngle(); int num12 = Physics.OverlapCapsuleNonAlloc(val3, val4, Radius.Value, _overlapCols, overlapMask, (QueryTriggerInteraction)2); int num13 = 0; Vector3 pos = val; int losChecks = 0; int num14 = Mathf.Clamp(MaxLoSRaycastsPerBash.Value, 0, 64); float num15 = Mathf.Clamp(CenterHitBonusMax.Value, 0f, 1f); RaycastHit val9 = default(RaycastHit); for (int i = 0; i < num12; i++) { Collider val5 = _overlapCols[i]; if (!Object.op_Implicit((Object)(object)val5)) { continue; } Character componentInParent = ((Component)val5).GetComponentInParent<Character>(); Vector3 hitPoint; if ((Object)(object)componentInParent != (Object)null) { if ((Object)(object)componentInParent == (Object)(object)player || componentInParent.IsDead()) { continue; } if (!HitTamed.Value) { Tameable component = ((Component)componentInParent).GetComponent<Tameable>(); if ((Object)(object)component != (Object)null && component.IsTamed()) { continue; } } if (!HitPlayers.Value && componentInParent is Player) { continue; } Vector3 val6 = ((Component)componentInParent).transform.position + Vector3.up * 1.1f; Vector3 val7 = val6 - val; float magnitude = ((Vector3)(ref val7)).magnitude; if (magnitude < 0.001f) { continue; } Vector3 val8 = val7 / magnitude; float num16 = Vector3.Dot(forward, val8); if (num16 < cosHalfAngle) { continue; } if (LineOfSightCheck.Value && num14 > 0 && losChecks < num14) { losChecks++; int characterOnlyLosMask = GetCharacterOnlyLosMask(); if (Physics.Raycast(val, val8, ref val9, magnitude, characterOnlyLosMask, (QueryTriggerInteraction)1)) { Character val10 = (Object.op_Implicit((Object)(object)((RaycastHit)(ref val9)).collider) ? ((Component)((RaycastHit)(ref val9)).collider).GetComponentInParent<Character>() : null); if ((Object)(object)val10 != (Object)(object)componentInParent) { continue; } } } if (HitOnceTryAdd(((Object)((Component)componentInParent).gameObject).GetInstanceID())) { float centerBonus = GetCenterBonus01(num16, cosHalfAngle); float num17 = 1f + centerBonus * num15; float blunt = Mathf.Clamp(num5 * num17, MinDamage.Value, MaxDamage.Value); Vector3 val11 = val5.ClosestPoint(((Component)player).transform.position + forward * 0.5f); if (val11 == Vector3.zero) { val11 = val6; } HitData val12 = new HitData { m_attacker = ((Character)player).GetZDOID(), m_point = val11 }; Vector3 val13 = ((Component)componentInParent).transform.position - ((Component)player).transform.position; val12.m_dir = ((Vector3)(ref val13)).normalized; val12.m_pushForce = PushForce.Value; val12.m_backstabBonus = 1f; HitData val14 = val12; val14.m_damage.m_blunt = blunt; float num18 = 0f; if (DebugLogDamageAfterArmor.Value) { num18 = componentInParent.GetHealth(); } componentInParent.Damage(val14); if (DebugLogDamageAfterArmor.Value) { float health = componentInParent.GetHealth(); float num19 = Mathf.Max(0f, num18 - health); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] DEALT '{1}': {2:0.0} (base={3:0.0}, centerMul={4:0.00}) hp {5:0.0}->{6:0.0}", "ShieldBash", ((Object)componentInParent).name, num19, num5, num17, num18, health)); } num13++; if (num13 == 1) { pos = val11; } if (PlayHitSfxPerTarget.Value) { float volumeMul = Mathf.Max(0f, num8 * volMul * num10); float pitchMul2 = Mathf.Max(0.01f, pitchMul * num11); PlayLocalHitAt(player, val11, volumeMul, pitchMul2); } } } else if (DamageWorldObjects.Value && TryDamageWorldObject(val5, player, val, forward, cosHalfAngle, ref losChecks, num14, num6, out hitPoint)) { num13++; if (num13 == 1) { pos = hitPoint; } if (PlayHitSfxPerTarget.Value) { float volumeMul2 = Mathf.Max(0f, num8 * volMul * num10); float pitchMul3 = Mathf.Max(0.01f, pitchMul * num11); PlayLocalHitAt(player, hitPoint, volumeMul2, pitchMul3); } } } if (!PlayHitSfxPerTarget.Value) { if (num13 > 0) { float num20 = 0f; if (num13 > 1) { float num21 = Mathf.Min(MultiHitBonusMin.Value, MultiHitBonusMax.Value); float num22 = Mathf.Max(MultiHitBonusMin.Value, MultiHitBonusMax.Value); num20 = Random.Range(num21, num22); } float volumeMul3 = Mathf.Max(0f, (num8 + num20) * volMul * num10); float pitchMul4 = Mathf.Max(0.01f, pitchMul * num11); PlayLocalHitAt(player, pos, volumeMul3, pitchMul4); } else { Vector3 pos2 = ((Component)player).transform.position + ((Component)player).transform.forward * 0.6f + Vector3.up * 1f; float volumeMul4 = Mathf.Max(0f, num9 * volMul * num10); float pitchMul5 = Mathf.Max(0.01f, 1.02f * pitchMul * num11); PlayLocalMissAt(player, pos2, volumeMul4, pitchMul5); } } if (DebugLog.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Bash: shieldBase={1:0.0}, sf={2:0.00}, rand={3:0.00}, base={4:0.0}, world={5:0.0}, hits={6}, LoS={7}/{8}, overlap={9}", "ShieldBash", num, blockingSkillFactor, num4, num5, num6, num13, losChecks, num14, num12)); } } private bool TryDamageWorldObject(Collider col, Player player, Vector3 origin, Vector3 forward, float cosHalf, ref int losChecks, int maxLos, float worldDamage, out Vector3 hitPoint) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Expected O, but got Unknown hitPoint = origin; if (!Object.op_Implicit((Object)(object)col) || !Object.op_Implicit((Object)(object)player)) { return false; } TreeBase componentInParent = ((Component)col).GetComponentInParent<TreeBase>(); TreeLog componentInParent2 = ((Component)col).GetComponentInParent<TreeLog>(); MineRock componentInParent3 = ((Component)col).GetComponentInParent<MineRock>(); MineRock5 componentInParent4 = ((Component)col).GetComponentInParent<MineRock5>(); Destructible componentInParent5 = ((Component)col).GetComponentInParent<Destructible>(); WearNTear componentInParent6 = ((Component)col).GetComponentInParent<WearNTear>(); Component val = (Component)(componentInParent ?? componentInParent2 ?? componentInParent3 ?? componentInParent4 ?? ((object)componentInParent5) ?? ((object)componentInParent6)); if (!Object.op_Implicit((Object)(object)val)) { return false; } if (!HitOnceTryAdd(((Object)val.gameObject).GetInstanceID())) { return false; } Bounds bounds = col.bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 val2 = center - origin; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude < 0.001f) { return false; } Vector3 val3 = val2 / magnitude; float num = Vector3.Dot(forward, val3); if (num < cosHalf) { return false; } if (LineOfSightCheck.Value && maxLos > 0 && losChecks < maxLos) { losChecks++; int worldLosMask = GetWorldLosMask(); RaycastHit val4 = default(RaycastHit); if (Physics.Raycast(origin, val3, ref val4, magnitude, worldLosMask, (QueryTriggerInteraction)1)) { Collider collider = ((RaycastHit)(ref val4)).collider; object obj = ((collider != null) ? ((Component)collider).GetComponentInParent<TreeBase>() : null); if (obj == null) { Collider collider2 = ((RaycastHit)(ref val4)).collider; obj = ((collider2 != null) ? ((Component)collider2).GetComponentInParent<TreeLog>() : null); if (obj == null) { Collider collider3 = ((RaycastHit)(ref val4)).collider; obj = ((collider3 != null) ? ((Component)collider3).GetComponentInParent<MineRock>() : null); if (obj == null) { Collider collider4 = ((RaycastHit)(ref val4)).collider; obj = ((collider4 != null) ? ((Component)collider4).GetComponentInParent<MineRock5>() : null); if (obj == null) { Collider collider5 = ((RaycastHit)(ref val4)).collider; obj = ((collider5 != null) ? ((Component)collider5).GetComponentInParent<Destructible>() : null); if (obj == null) { Collider collider6 = ((RaycastHit)(ref val4)).collider; obj = ((collider6 != null) ? ((Component)collider6).GetComponentInParent<WearNTear>() : null); } } } } } Component val5 = (Component)obj; if ((Object)(object)val5 != (Object)(object)val) { return false; } } } hitPoint = col.ClosestPoint(((Component)player).transform.position + forward * 0.5f); if (hitPoint == Vector3.zero) { hitPoint = center; } bool flag = (Object)(object)componentInParent != (Object)null || (Object)(object)componentInParent2 != (Object)null; bool flag2 = (Object)(object)componentInParent3 != (Object)null || (Object)(object)componentInParent4 != (Object)null; HitData val6 = new HitData { m_attacker = ((Character)player).GetZDOID(), m_point = hitPoint, m_dir = val3, m_pushForce = 0f }; float num2 = Mathf.Max(0f, worldDamage); if (flag) { val6.m_damage.m_chop = num2; } else if (flag2) { val6.m_damage.m_pickaxe = num2; } else { val6.m_damage.m_blunt = num2; } if ((Object)(object)componentInParent != (Object)null) { componentInParent.Damage(val6); } else if ((Object)(object)componentInParent2 != (Object)null) { componentInParent2.Damage(val6); } else if ((Object)(object)componentInParent3 != (Object)null) { componentInParent3.Damage(val6); } else if ((Object)(object)componentInParent4 != (Object)null) { componentInParent4.Damage(val6); } else if ((Object)(object)componentInParent5 != (Object)null) { componentInParent5.Damage(val6); } else { if (!((Object)(object)componentInParent6 != (Object)null)) { return false; } componentInParent6.Damage(val6); } return true; } private void GetMaterialMix(ItemData shield, out float volMul, out float pitchMul) { volMul = 1f; pitchMul = 1f; string text = shield?.m_shared?.m_name ?? ""; string text2 = text.ToLowerInvariant(); bool flag = text2.Contains("iron") || text2.Contains("blackmetal") || text2.Contains("silver") || text2.Contains("bronze") || text2.Contains("metal"); bool flag2 = !flag && (text2.Contains("wood") || text2.Contains("tower")); if (flag) { volMul *= Mathf.Max(0.01f, MetalVolumeMul.Value); pitchMul *= Mathf.Max(0.01f, MetalPitchMul.Value); } else if (flag2) { volMul *= Mathf.Max(0.01f, WoodVolumeMul.Value); pitchMul *= Mathf.Max(0.01f, WoodPitchMul.Value); } } private AudioSource GetOrCreateLocalSfxSource(Player p) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)p)) { return null; } if (Object.op_Implicit((Object)(object)_localSfxSource) && Object.op_Implicit((Object)(object)((Component)_localSfxSource).gameObject) && ((Component)_localSfxSource).transform.IsChildOf(((Component)p).transform)) { return _localSfxSource; } try { if (Object.op_Implicit((Object)(object)_localSfxSource) && Object.op_Implicit((Object)(object)((Component)_localSfxSource).gameObject)) { Object.Destroy((Object)(object)((Component)_localSfxSource).gameObject); } } catch { } GameObject val = new GameObject("ShieldBash_LocalSFX_Source"); val.transform.SetParent(((Component)p).transform, false); AudioSource val2 = val.AddComponent<AudioSource>(); val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)0; val2.minDistance = 1f; val2.maxDistance = 35f; val2.playOnAwake = false; val2.loop = false; val2.dopplerLevel = 0f; _localSfxSource = val2; return _localSfxSource; } private void PlayLocalHitAt(Player player, Vector3 pos, float volumeMul, float pitchMul) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) PlayLocalAt(player, _hitClip, pos, volumeMul, pitchMul); } private void PlayLocalMissAt(Player player, Vector3 pos, float volumeMul, float pitchMul) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) PlayLocalAt(player, _missClip, pos, volumeMul, pitchMul); } private void PlayLocalAt(Player player, AudioClip clip, Vector3 pos, float volumeMul, float pitchMul) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)clip)) { AudioSource orCreateLocalSfxSource = GetOrCreateLocalSfxSource(player); if (Object.op_Implicit((Object)(object)orCreateLocalSfxSource)) { ((Component)orCreateLocalSfxSource).transform.position = pos; orCreateLocalSfxSource.pitch = Mathf.Clamp(pitchMul, 0.5f, 2f); float num = Mathf.Clamp01(volumeMul) * Mathf.Clamp(LocalClipVolumeMul.Value, 0f, 3f); orCreateLocalSfxSource.PlayOneShot(clip, num); } } } private bool LoadAssetsFromBundle() { string text = Path.Combine(Paths.PluginPath, "ShieldBash", "Assets", "shieldbashbundle"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ShieldBash] Bundle path: " + text)); if (!File.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ShieldBash] AssetBundle not found: " + text)); return false; } AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] Failed to load AssetBundle (null). Wrong Unity version or corrupted file."); return false; } try { _bashClip = val.LoadAsset<AnimationClip>("AttackShield01"); if ((Object)(object)_bashClip == (Object)null) { AnimationClip[] array = val.LoadAllAssets<AnimationClip>(); if (array != null && array.Length != 0) { foreach (AnimationClip val2 in array) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name == "AttackShield01") { _bashClip = val2; break; } } if ((Object)(object)_bashClip == (Object)null) { _bashClip = array[0]; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ShieldBash] Loaded embedded clip: " + ((Object)_bashClip).name)); } } if ((Object)(object)_bashClip == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] No AnimationClip found in bundle."); ((BaseUnityPlugin)this).Logger.LogError((object)("[ShieldBash] Assets inside bundle:\n - " + string.Join("\n - ", val.GetAllAssetNames()))); return false; } _hitClip = null; _missClip = null; string text2 = (HitClipName.Value ?? "").Trim(); string text3 = (MissClipName.Value ?? "").Trim(); AudioClip[] array2 = val.LoadAllAssets<AudioClip>(); if (array2 != null) { foreach (AudioClip val3 in array2) { if (Object.op_Implicit((Object)(object)val3)) { if ((Object)(object)_hitClip == (Object)null && ((Object)val3).name.Equals(text2, StringComparison.OrdinalIgnoreCase)) { _hitClip = val3; } else if ((Object)(object)_missClip == (Object)null && ((Object)val3).name.Equals(text3, StringComparison.OrdinalIgnoreCase)) { _missClip = val3; } } } } if (!Object.op_Implicit((Object)(object)_hitClip)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ShieldBash] HIT clip not found. Expected AudioClip name: '" + text2 + "'")); } if (!Object.op_Implicit((Object)(object)_missClip)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ShieldBash] MISS clip not found. Expected AudioClip name: '" + text3 + "'")); } return true; } finally { val.Unload(false); } } private Animator GetAnimator(Character character) { try { return CharacterAnimator.Invoke(character); } catch { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] Cannot access field 'm_animator' on Character."); return null; } } private ItemData GetLeftItem(Humanoid humanoid) { try { return HumanoidLeftItem.Invoke(humanoid); } catch { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] Cannot access field 'm_leftItem' on Humanoid."); return null; } } private bool HasShieldInLeftHand(Player player) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 ItemData leftItem = GetLeftItem((Humanoid)(object)player); return leftItem != null && leftItem.m_shared != null && (int)leftItem.m_shared.m_itemType == 5; } } [HarmonyPatch(typeof(ItemData))] public static class ShieldBashTooltipPatch { [CompilerGenerated] private sealed class <TargetMethods>d__1 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; private List<MethodInfo>.Enumerator <>s__1; private MethodInfo <m>5__2; MethodBase IEnumerator<MethodBase>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TargetMethods>d__1(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>s__1 = default(List<MethodInfo>.Enumerator); <m>5__2 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -3; goto IL_00b6; } <>1__state = -1; <>s__1 = AccessTools.GetDeclaredMethods(typeof(ItemData)).GetEnumerator(); <>1__state = -3; goto IL_00be; IL_00b6: <m>5__2 = null; goto IL_00be; IL_00be: if (<>s__1.MoveNext()) { <m>5__2 = <>s__1.Current; if (<m>5__2.Name == "GetTooltip" && <m>5__2.ReturnType == typeof(string)) { <>2__current = <m>5__2; <>1__state = 1; return true; } goto IL_00b6; } <>m__Finally1(); <>s__1 = default(List<MethodInfo>.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <TargetMethods>d__1(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<MethodBase>)this).GetEnumerator(); } } private static readonly string[] BlockLineHints = new string[6] { "$item_blockpower", "Block power", "Block Power", "Сопротивление урону", "Блокирование", "Блок" }; [IteratorStateMachine(typeof(<TargetMethods>d__1))] private static IEnumerable<MethodBase> TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TargetMethods>d__1(-2); } private static void Postfix(ItemData __instance, ref string __result) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 ShieldBashPlugin instance = ShieldBashPlugin.Instance; if ((Object)(object)instance == (Object)null || !instance.ShowShieldBashInTooltip.Value || __instance == null || __instance.m_shared == null || (int)__instance.m_shared.m_itemType != 5) { return; } float num = instance.ComputeShieldBaseDamage(__instance); Player localPlayer = Player.m_localPlayer; float num2 = 0f; try { if (Object.op_Implicit((Object)(object)localPlayer)) { num2 = Mathf.Clamp01(((Character)localPlayer).GetSkillFactor((SkillType)6)); } } catch { num2 = 0f; } float num3 = Mathf.Max(0f, instance.BlockingSkillMultiplier.Value); float num4 = num * (1f + num2 * num3); num4 = Mathf.Clamp(num4, instance.MinDamage.Value, instance.MaxDamage.Value); float num5 = Mathf.Clamp(num, instance.MinDamage.Value, instance.MaxDamage.Value); string text = $"\n<color=orange>Удар щитом</color>: {num5:0.0}"; string text2 = (((Object)(object)localPlayer != (Object)null) ? $"\n<color=orange>Удар щитом (твой блок)</color>: {num4:0.0}" : $"\n<color=orange>Удар щитом (твой блок)</color>: {num5:0.0}"); string text3 = text + text2; if (!TryInsertAfterBlockLine(ref __result, text3)) { __result += text3; } } private static bool TryInsertAfterBlockLine(ref string tooltip, string insert) { if (string.IsNullOrEmpty(tooltip)) { return false; } string[] blockLineHints = BlockLineHints; foreach (string value in blockLineHints) { int num = tooltip.IndexOf(value, StringComparison.OrdinalIgnoreCase); if (num >= 0) { int num2 = tooltip.IndexOf('\n', num); if (num2 < 0) { num2 = tooltip.Length; } tooltip = tooltip.Insert(num2, insert); return true; } } return false; } }