using 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;
}
}