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.6.0
BepInEx/plugins/ShieldBash/ShieldBash.dll
Decompiled 3 days 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 Jotunn.Utils; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Playables; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [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.6.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace ShieldBashMod; [BepInPlugin("mexanik.shieldbash", "ShieldBash", "1.6.0")] [BepInDependency("com.jotunn.jotunn", "2.30.2")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class ShieldBashPlugin : BaseUnityPlugin { private sealed class BashVisual { internal Player Player; internal Animator Animator; internal bool RootMotion; internal bool Local; internal PlayableGraph Graph; } [HarmonyPatch(typeof(Player), "Awake")] private static class PlayerAwakePatch { private static void Postfix(Player __instance) { ShieldBashPlugin instance = Instance; if (!((Object)(object)instance == (Object)null)) { instance.RegisterPlayerRpc(__instance); } } } [HarmonyPatch] private static class ShieldTooltipPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] methods = typeof(ItemData).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo != null && methodInfo.Name == "GetTooltip" && methodInfo.ReturnType == typeof(string)) { yield return methodInfo; } } } private static void Postfix(ItemData __instance, ref string __result) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 try { ShieldBashPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.ShowShieldBashInTooltip.Value || __instance == null || __instance.m_shared == null || (int)__instance.m_shared.m_itemType != 5) { return; } string text = __result ?? string.Empty; if (text.IndexOf("Shield Bash:", StringComparison.Ordinal) < 0 && text.IndexOf("Удар щитом:", StringComparison.Ordinal) < 0) { string text2 = instance.BuildTooltipLineForShield(__instance); if (!string.IsNullOrEmpty(text2)) { __result = text + text2; } } } catch (Exception ex) { ShieldBashPlugin instance2 = Instance; if ((Object)(object)instance2 != (Object)null && instance2.DebugLog != null && instance2.DebugLog.Value) { ((BaseUnityPlugin)instance2).Logger.LogWarning((object)("[ShieldBash] Tooltip patch error: " + ex.Message)); } } } } private sealed class AttackPhase { internal bool Triggered; internal bool Interrupted; } [HarmonyPatch(typeof(Character), "Awake")] private static class InterruptCharacterAwakePatch { private static void Postfix(Character __instance) { if (Instance != null) { Instance.RegisterInterruptRpc(__instance); } } } [HarmonyPatch(typeof(Attack), "OnAttackTrigger")] private static class InterruptAttackTriggerPatch { private static bool Prefix(Attack __instance) { return ConsumeAttackTrigger(__instance); } } public const string PluginGUID = "mexanik.shieldbash"; public const string PluginName = "ShieldBash"; public const string PluginVersion = "1.6.0"; private const string InputName = "ShieldBash_Bash"; private const string RpcPlayBashVisual = "ShieldBash_PlayVisual"; internal static ShieldBashPlugin Instance; internal ConfigEntry<KeyCode> BashKey; internal ConfigEntry<float> Cooldown; internal ConfigEntry<bool> RequireShield; internal ConfigEntry<float> BaseStaminaCost; internal ConfigEntry<float> BlockPowerStaminaScale; internal ConfigEntry<float> SkillStaminaReduction; internal ConfigEntry<float> MinStaminaCost; internal ConfigEntry<float> MaxStaminaCost; 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> HitDelay; internal ConfigEntry<bool> DamageWorldObjects; internal ConfigEntry<float> WorldDamageScale; internal ConfigEntry<bool> WorldDamageUseRandom; 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> ShowCooldownHint; internal ConfigEntry<bool> ShowStaminaHint; internal ConfigEntry<bool> DebugLog; internal ConfigEntry<bool> DebugLogDamageAfterArmor; 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 bool _isBashing; private float _nextCooldownHintTime; private readonly HashSet<int> _remoteBashes = new HashSet<int>(); private readonly Dictionary<int, BashVisual> _visuals = new Dictionary<int, BashVisual>(); private readonly List<int> _expiredVisuals = new List<int>(); private float _nextStaminaHintTime; private Collider[] _overlapCols; private int[] _hitOnceIds; private int _hitOnceCount; private int _overlapMask = -1; private int _losWorldMask = -1; private float _cachedAngle = -999f; private float _cachedCosHalf = -2f; private AudioSource _localSfxSource; private static bool _locRefReady; private static Type _locType; private static PropertyInfo _locInstanceProp; private static MethodInfo _locGetSelectedLanguage; private static readonly FieldInfo CharacterAnimatorField = AccessTools.Field(typeof(Character), "m_animator"); private static readonly FieldInfo CharacterBodyField = AccessTools.Field(typeof(Character), "m_body"); private static readonly FieldInfo CharacterMoveDirField = AccessTools.Field(typeof(Character), "m_moveDir"); private static readonly FieldInfo HumanoidLeftItemField = AccessTools.Field(typeof(Humanoid), "m_leftItem"); private static readonly FieldInfo CharacterNViewField = AccessTools.Field(typeof(Character), "m_nview"); private const string InterruptRpc = "mexanik.shieldbash.InterruptV1"; private const string InterruptUntilKey = "mexanik.shieldbash.interruptUntilV1"; private const long InterruptProtectionTicks = 40000000L; private ConfigEntry<bool> InterruptEnabled; private static readonly ConditionalWeakTable<Attack, AttackPhase> AttackPhases = new ConditionalWeakTable<Attack, AttackPhase>(); private static readonly FieldInfo CurrentAttackField = AccessTools.Field(typeof(Humanoid), "m_currentAttack"); private static readonly FieldInfo AttackDoneField = AccessTools.Field(typeof(Attack), "m_attackDone"); private static readonly FieldInfo AttackAbortField = AccessTools.Field(typeof(Attack), "m_abortAttack"); private static readonly FieldInfo StaggerFactorField = AccessTools.Field(typeof(Character), "m_staggerDamageFactor"); private void Awake() { //IL_0757: Unknown result type (might be due to invalid IL or missing references) //IL_0761: Expected O, but got Unknown //IL_07cb: Unknown result type (might be due to invalid IL or missing references) //IL_07d5: Expected O, but got Unknown Instance = this; ConfigureInterrupt(); BashKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Input", "BashKey", (KeyCode)103, "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"); BaseStaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "BaseStaminaCost", 10f, "Base stamina cost of Shield Bash"); BlockPowerStaminaScale = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "BlockPowerStaminaScale", 0.08f, "Additional stamina cost per point of shield block power"); SkillStaminaReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "SkillStaminaReduction", 0.25f, "Maximum stamina cost reduction at Blocking skill 100"); MinStaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "MinStaminaCost", 8f, "Minimum stamina cost of Shield Bash"); MaxStaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "MaxStaminaCost", 18f, "Maximum stamina cost of Shield Bash"); AntiSlideTime = ((BaseUnityPlugin)this).Config.Bind<float>("Feel", "AntiSlideTime", 0.2f, "Anti-slide duration seconds (0 = off)"); BaseDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BaseDamage", 4f, "Flat blunt damage added to bash"); BlockPowerScale = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BlockPowerScale", 0.16f, "Damage per 1 shield block power"); QualityBonusPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "QualityBonusPerLevel", 0.4f, "Bonus damage per shield upgrade level (quality-1)"); MinDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "MinDamage", 3f, "Minimum final damage"); MaxDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "MaxDamage", 20f, "Maximum final damage cap"); BlockingSkillMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "BlockingSkillMultiplier", 0.3f, "At Blocking skill 100, damage is increased by 30 percent"); DamageRandomMin = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "DamageRandomMin", 0.92f, "Per-bash random damage multiplier min."); DamageRandomMax = ((BaseUnityPlugin)this).Config.Bind<float>("Damage", "DamageRandomMax", 1.05f, "Per-bash random damage multiplier max."); 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."); WorldDamageScale = ((BaseUnityPlugin)this).Config.Bind<float>("WorldDamage", "WorldDamageScale", 0.85f, "Multiplier for world-object damage."); WorldDamageUseRandom = ((BaseUnityPlugin)this).Config.Bind<bool>("WorldDamage", "WorldDamageUseRandom", false, "If true: world damage uses per-bash random multiplier."); 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"); 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. Unchecked targets are skipped; 0 blocks all hits while LineOfSightCheck is enabled."); 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 line to shield tooltip (RU/EN)"); ShowCooldownHint = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowCooldownHint", true, "Show remaining cooldown on an early key press (local only, RU/EN)"); ShowStaminaHint = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowStaminaHint", true, "Show insufficient stamina on key press (local only, RU/EN)"); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Log", false, "General debug logging"); DebugLogDamageAfterArmor = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogDamageAfterArmor", false, "Log dealt damage 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."); 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(); _bashButton.Name = "ShieldBash_Bash"; _bashButton.Config = BashKey; _bashButton.HintToken = "Shield Bash"; _bashButton.ActiveInGUI = false; _bashButton.ActiveInCustomGUI = false; InputManager.Instance.AddButton("mexanik.shieldbash", _bashButton); EnsureBuffers(); _harmony = new Harmony("mexanik.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)(object)_bashClip != (Object)null) ? ((Object)_bashClip).name : "null", ((Object)(object)_hitClip != (Object)null) ? ((Object)_hitClip).name : "null", ((Object)(object)_missClip != (Object)null) ? ((Object)_missClip).name : "null")); } private void OnDestroy() { OnDisable(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } try { if (_harmony != null) { _harmony.UnpatchSelf(); } } catch { } try { if ((Object)(object)_localSfxSource != (Object)null && (Object)(object)((Component)_localSfxSource).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)_localSfxSource).gameObject); } } catch { } } private void EnsureBuffers() { int num = Mathf.Clamp(OverlapBufferSize.Value, 16, 256); if (_overlapCols == null) { _overlapCols = (Collider[])(object)new Collider[num]; } else if (_overlapCols.Length != num) { _overlapCols = (Collider[])(object)new Collider[num]; } int num2 = Mathf.Clamp(num * 2, 32, 1024); if (_hitOnceIds == null) { _hitOnceIds = new int[num2]; } else if (_hitOnceIds.Length != num2) { _hitOnceIds = new int[num2]; } _hitOnceCount = 0; } private void Update() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Invalid comparison between Unknown and I4 CleanupExpiredVisuals(); if (ZInput.instance == null || !ZInput.GetButtonDown(_bashButton.Name)) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !CanBash(localPlayer)) { return; } if (_isBashing || Time.time < _nextUseTime) { if (ShowCooldownHint.Value && Time.time < _nextUseTime && Time.unscaledTime >= _nextCooldownHintTime) { float num = _nextUseTime - Time.time; ((Character)localPlayer).Message((MessageType)1, string.Format(IsRussianUi() ? "Удар щитом: ещё {0:0.0} с" : "Shield Bash: {0:0.0}s remaining", num), 0, (Sprite)null, false); _nextCooldownHintTime = Time.unscaledTime + 1f; } return; } if ((Object)(object)_bashClip == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[ShieldBash] Bash clip is null. Bundle/clip not loaded."); return; } ItemData leftItem = GetLeftItem((Humanoid)localPlayer); if (!RequireShield.Value || (leftItem != null && leftItem.m_shared != null && (int)leftItem.m_shared.m_itemType == 5)) { float cost = ComputeStaminaCost(localPlayer, leftItem); Animator animator = GetAnimator((Character)localPlayer); if (!((Object)(object)animator == (Object)null) && TryUseStaminaNoMessage(localPlayer, cost)) { EnsureBuffers(); _nextUseTime = Time.time + Cooldown.Value; ((MonoBehaviour)this).StartCoroutine(DoBash(localPlayer, animator, _bashClip, applyDamage: true, (leftItem != null) ? leftItem.Clone() : null, GetBlockingSkillFactor(localPlayer), ComputeShieldBaseDamage(leftItem))); BroadcastBashVisual(localPlayer); } } } private static bool CanBash(Player player) { if ((Object)(object)player != (Object)null && !((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Character)player).InDodge() && !((Character)player).IsStaggering() && !((Character)player).InAttack()) { return !((Character)player).InCutscene(); } return false; } private void ReleaseVisual(int id, BashVisual visual) { if (!_visuals.TryGetValue(id, out var value) || value != visual) { return; } _visuals.Remove(id); try { if (((PlayableGraph)(ref visual.Graph)).IsValid()) { ((PlayableGraph)(ref visual.Graph)).Destroy(); } } finally { _remoteBashes.Remove(id); if (visual.Local) { _isBashing = false; } if ((Object)(object)visual.Animator != (Object)null) { visual.Animator.applyRootMotion = visual.RootMotion; } } } private void CleanupExpiredVisuals() { _expiredVisuals.Clear(); foreach (KeyValuePair<int, BashVisual> visual in _visuals) { BashVisual value = visual.Value; if ((Object)(object)value.Player == (Object)null || (Object)(object)value.Animator == (Object)null || ((Character)value.Player).IsDead() || (value.Local && (Object)(object)value.Player != (Object)(object)Player.m_localPlayer)) { _expiredVisuals.Add(visual.Key); } } foreach (int expiredVisual in _expiredVisuals) { ReleaseVisual(expiredVisual, _visuals[expiredVisual]); } } private void OnDisable() { ((MonoBehaviour)this).StopAllCoroutines(); foreach (int item in new List<int>(_visuals.Keys)) { ReleaseVisual(item, _visuals[item]); } _remoteBashes.Clear(); _isBashing = false; _nextUseTime = 0f; } private IEnumerator DoBash(Player player, Animator animator, AnimationClip clip, bool applyDamage, ItemData attackShield = null, float attackSkill = 0f, float attackBaseDamage = 0f) { int playerId = ((Object)player).GetInstanceID(); if (!applyDamage && !_remoteBashes.Add(playerId)) { yield break; } if (applyDamage) { _isBashing = true; } bool applyRootMotion = animator.applyRootMotion; PlayableGraph val = default(PlayableGraph); BashVisual visual = new BashVisual { Player = player, Animator = animator, RootMotion = applyRootMotion, Local = applyDamage }; _visuals[playerId] = visual; try { if (applyDamage && AntiSlideTime.Value > 0.0001f) { ((MonoBehaviour)this).StartCoroutine(AntiSlideRoutine(player, AntiSlideTime.Value)); } animator.applyRootMotion = false; val = (visual.Graph = PlayableGraph.Create("ShieldBashGraph")); AnimatorControllerPlayable val2 = AnimatorControllerPlayable.Create(val, animator.runtimeAnimatorController); AnimationClipPlayable val3 = AnimationClipPlayable.Create(val, clip); ((AnimationClipPlayable)(ref val3)).SetApplyFootIK(false); ((AnimationClipPlayable)(ref val3)).SetApplyPlayableIK(false); AnimationLayerMixerPlayable val4 = AnimationLayerMixerPlayable.Create(val, 2); ((PlayableGraph)(ref val)).Connect<AnimatorControllerPlayable, AnimationLayerMixerPlayable>(val2, 0, val4, 0); ((PlayableGraph)(ref val)).Connect<AnimationClipPlayable, AnimationLayerMixerPlayable>(val3, 0, val4, 1); PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(val4, 0, 0f); PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(val4, 1, 1f); PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationLayerMixerPlayable>(AnimationPlayableOutput.Create(val, "ShieldBashOutput", animator), val4); ((PlayableGraph)(ref val)).Play(); float hitAt = Mathf.Clamp(HitDelay.Value, 0.01f, Mathf.Max(0.01f, clip.length)); yield return (object)new WaitForSeconds(hitAt); if (!_visuals.TryGetValue(playerId, out var value) || value != visual) { yield break; } if ((Object)(object)player != (Object)null && !((Character)player).IsDead()) { if (applyDamage) { ZNetView zNetView = GetZNetView((Character)(object)player); if (CanBash(player) && (Object)(object)zNetView != (Object)null && zNetView.IsValid() && zNetView.IsOwner()) { ApplyBashDamageAndSfx(player, attackShield, attackSkill, attackBaseDamage); } } else { PlayRemoteBashSfx(player); } } float num = Mathf.Max(0.01f, clip.length - hitAt); yield return (object)new WaitForSeconds(num); } finally { ReleaseVisual(playerId, visual); } } private void BroadcastBashVisual(Player player) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown ZNetView zNetView = GetZNetView((Character)player); if ((Object)(object)zNetView == (Object)null || !zNetView.IsValid() || !zNetView.IsOwner()) { return; } try { zNetView.InvokeRPC(ZNetView.Everybody, "ShieldBash_PlayVisual", Array.Empty<object>()); } catch (Exception ex) { if (DebugLog != null && DebugLog.Value) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ShieldBash] RPC send failed: " + ex.Message)); } } } internal void RegisterPlayerRpc(Player player) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if ((Object)(object)player == (Object)null) { return; } ZNetView zNetView = GetZNetView((Character)player); if ((Object)(object)zNetView == (Object)null || !zNetView.IsValid()) { return; } try { zNetView.Register("ShieldBash_PlayVisual", (Action<long>)delegate(long sender) { RpcPlayRemoteBashVisual(player, sender); }); } catch { } } private void RpcPlayRemoteBashVisual(Player player, long sender) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown if (!((Behaviour)this).isActiveAndEnabled || (Object)(object)player == (Object)null) { return; } ZNetView zNetView = GetZNetView((Character)player); if (!((Object)(object)zNetView == (Object)null) && zNetView.IsValid() && !zNetView.IsOwner() && zNetView.GetZDO() != null && sender == zNetView.GetZDO().GetOwner() && !((Object)(object)_bashClip == (Object)null)) { Animator animator = GetAnimator((Character)player); if (!((Object)(object)animator == (Object)null)) { ((MonoBehaviour)this).StartCoroutine(DoBash(player, animator, _bashClip, applyDamage: false)); } } } private void PlayRemoteBashSfx(Player player) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { Vector3 pos = ((Component)player).transform.position + ((Component)player).transform.forward * 0.6f + Vector3.up * 1f; PlayLocalMissAt(player, pos, Mathf.Max(0f, MissSfxVolume.Value), 1f); } } private IEnumerator AntiSlideRoutine(Player player, float duration) { if ((Object)(object)player == (Object)null) { yield break; } Rigidbody body; try { body = GetCharacterBody((Character)(object)player); } catch { body = null; } if (!((Object)(object)body == (Object)null) && !body.isKinematic) { float t = 0f; SetMoveDirZero(player); body.linearVelocity = Vector3.zero; while (t < duration && CanBash(player) && _isBashing && !((Object)(object)body == (Object)null)) { Vector3 linearVelocity = body.linearVelocity; linearVelocity.x = 0f; linearVelocity.z = 0f; body.linearVelocity = linearVelocity; SetMoveDirZero(player); t += Time.deltaTime; yield return null; } } } private static void SetMoveDirZero(Player player) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || CharacterMoveDirField == null) { return; } try { CharacterMoveDirField.SetValue(player, Vector3.zero); } catch { } } private float ComputeStaminaCost(Player player, ItemData shield) { float blockPower = 0f; if (shield != null && shield.m_shared != null) { int num = Mathf.Max(1, shield.m_quality); blockPower = shield.m_shared.m_blockPower + shield.m_shared.m_blockPowerPerLevel * (float)(num - 1); } float blockingSkillFactor = GetBlockingSkillFactor(player); return ComputeStaminaCostFromBlock(blockPower, blockingSkillFactor); } private float ComputeStaminaCostFromBlock(float blockPower, float skillFactor) { float num = Mathf.Max(0f, BaseStaminaCost.Value) + blockPower * Mathf.Max(0f, BlockPowerStaminaScale.Value); float num2 = skillFactor * Mathf.Clamp01(SkillStaminaReduction.Value); float num3 = num * (1f - num2); float num4 = Mathf.Max(0f, MinStaminaCost.Value); float num5 = Mathf.Max(num4, MaxStaminaCost.Value); return Mathf.Clamp(num3, num4, num5); } private bool TryUseStaminaNoMessage(Player player, float cost) { if (cost <= 0f) { return true; } if (player.GetStamina() + 0.001f < cost) { if (ShowStaminaHint.Value && Time.unscaledTime >= _nextStaminaHintTime) { ((Character)player).Message((MessageType)1, IsRussianUi() ? "Удар щитом: недостаточно выносливости" : "Shield Bash: not enough stamina", 0, (Sprite)null, false); _nextStaminaHintTime = Time.unscaledTime + 1f; } 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)(object)player == (Object)null) { 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); return Mathf.Clamp(baseDamage * (1f + skillFactor * num) * randMul, MinDamage.Value, MaxDamage.Value); } 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 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; _hitOnceCount++; return true; } private static Vector3 GetSafeHitPoint(Collider col, Vector3 nearPoint, Vector3 fallback) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)col == (Object)null) { return fallback; } Vector3 val = col.ClosestPointOnBounds(nearPoint); if (float.IsNaN(val.x)) { return fallback; } if (float.IsInfinity(val.x)) { return fallback; } return val; } private void ApplyBashDamageAndSfx(Player player, ItemData shield, float attackSkill, float attackBaseDamage) { //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: 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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0225: 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_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06d1: Unknown result type (might be due to invalid IL or missing references) //IL_06db: Unknown result type (might be due to invalid IL or missing references) //IL_06e0: Unknown result type (might be due to invalid IL or missing references) //IL_06e5: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_06f4: Unknown result type (might be due to invalid IL or missing references) //IL_06f9: Unknown result type (might be due to invalid IL or missing references) //IL_0728: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05bb: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05cd: Unknown result type (might be due to invalid IL or missing references) //IL_06b3: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05e5: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Expected O, but got Unknown //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_059f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } HitOnceReset(); float num = DamageRandomMin.Value; float num2 = DamageRandomMax.Value; if (num > num2) { float num3 = num; num = num2; num2 = num3; } float num4 = Random.Range(num, num2); float num5 = ApplySkillAndRandom(attackBaseDamage, attackSkill, num4); float randMul = ((!WorldDamageUseRandom.Value) ? 1f : num4); float num6 = ApplySkillAndRandom(attackBaseDamage, attackSkill, 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(shield, 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; Character val5 = null; float num14 = float.MaxValue; Vector3 pos = val; int losChecks = 0; int num15 = Mathf.Clamp(MaxLoSRaycastsPerBash.Value, 0, 64); Vector3 nearPoint = ((Component)player).transform.position + forward * 0.5f; for (int i = 0; i < num12; i++) { Collider val6 = _overlapCols[i]; if ((Object)(object)val6 == (Object)null) { continue; } Character componentInParent = ((Component)val6).GetComponentInParent<Character>(); if ((Object)(object)componentInParent != (Object)null) { if ((object)componentInParent == 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 && (Object)(object)((componentInParent is Player) ? componentInParent : null) != (Object)null) { continue; } Vector3 val7 = ((Component)componentInParent).transform.position + Vector3.up * 1.1f; Vector3 val8 = val7 - val; float magnitude = ((Vector3)(ref val8)).magnitude; if (magnitude < 0.001f) { continue; } Vector3 val9 = val8 / magnitude; if (Vector3.Dot(forward, val9) < cosHalfAngle) { continue; } if (LineOfSightCheck.Value) { if (losChecks >= num15) { continue; } if (num15 > 0 && losChecks < num15) { losChecks++; int worldLosMask = GetWorldLosMask(); RaycastHit val10 = default(RaycastHit); if (Physics.Raycast(val, val9, ref val10, magnitude, worldLosMask, (QueryTriggerInteraction)1)) { Character val11 = null; if ((Object)(object)((RaycastHit)(ref val10)).collider != (Object)null) { val11 = ((Component)((RaycastHit)(ref val10)).collider).GetComponentInParent<Character>(); } if (val11 != componentInParent) { continue; } } } } if (!HitOnceTryAdd(((Object)((Component)componentInParent).gameObject).GetInstanceID())) { continue; } float num16 = Mathf.Clamp(num5, MinDamage.Value, MaxDamage.Value); Vector3 safeHitPoint = GetSafeHitPoint(val6, nearPoint, val7); float num17 = 0f; if (DebugLogDamageAfterArmor.Value) { num17 = componentInParent.GetHealth(); } HitData val12 = new HitData(); val12.m_attacker = ((Character)player).GetZDOID(); val12.m_point = safeHitPoint; 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; val12.m_damage.m_blunt = num16; componentInParent.Damage(val12); if (IsInterruptCandidate(componentInParent)) { val13 = ((Component)componentInParent).transform.position - ((Component)player).transform.position; float sqrMagnitude = ((Vector3)(ref val13)).sqrMagnitude; if (sqrMagnitude < num14) { num14 = sqrMagnitude; val5 = componentInParent; } } if (DebugLogDamageAfterArmor.Value) { float health = componentInParent.GetHealth(); float num18 = Mathf.Max(0f, num17 - health); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] DEALT '{1}': {2:0.0} (damage={3:0.0}) hp {4:0.0}->{5:0.0}", "ShieldBash", ((Object)componentInParent).name, num18, num16, num17, health)); } num13++; if (num13 == 1) { pos = safeHitPoint; } if (PlayHitSfxPerTarget.Value) { float volumeMul = Mathf.Max(0f, num8 * volMul * num10); float pitchMul2 = Mathf.Max(0.01f, pitchMul * num11); PlayLocalHitAt(player, safeHitPoint, volumeMul, pitchMul2); } } else { if (!DamageWorldObjects.Value) { continue; } Vector3 hitPoint = val; if (TryDamageWorldObject(val6, player, val, forward, cosHalfAngle, ref losChecks, num15, num6, nearPoint, 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 num19 = 0f; if (num13 > 1) { float num20 = MultiHitBonusMin.Value; float num21 = MultiHitBonusMax.Value; if (num20 > num21) { float num22 = num20; num20 = num21; num21 = num22; } num19 = Random.Range(num20, num21); } float volumeMul3 = Mathf.Max(0f, (num8 + num19) * 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 ((Object)(object)val5 != (Object)null) { RequestInterrupt(player, val5); } if (DebugLog.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Bash: shieldBase={1:0.0}, sf={2:0.00}, rand={3:0.00}, char={4:0.0}, world={5:0.0}, hits={6}, LoS={7}/{8}, overlap={9}", "ShieldBash", attackBaseDamage, attackSkill, num4, num5, num6, num13, losChecks, num15, num12)); } } private bool TryDamageWorldObject(Collider col, Player player, Vector3 origin, Vector3 forward, float cosHalf, ref int losChecks, int maxLos, float worldDamage, Vector3 nearPoint, out Vector3 hitPoint) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_023e: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Expected O, but got Unknown //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: 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_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) hitPoint = origin; if ((Object)(object)col == (Object)null) { return false; } if ((Object)(object)player == (Object)null) { 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 = null; if ((Object)(object)componentInParent != (Object)null) { val = (Component)(object)componentInParent; } else if ((Object)(object)componentInParent2 != (Object)null) { val = (Component)(object)componentInParent2; } else if ((Object)(object)componentInParent3 != (Object)null) { val = (Component)(object)componentInParent3; } else if ((Object)(object)componentInParent4 != (Object)null) { val = (Component)(object)componentInParent4; } else if ((Object)(object)componentInParent5 != (Object)null) { val = (Component)(object)componentInParent5; } else if ((Object)(object)componentInParent6 != (Object)null) { val = (Component)(object)componentInParent6; } if ((Object)(object)val == (Object)null) { 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; if (Vector3.Dot(forward, val3) < cosHalf) { return false; } if (LineOfSightCheck.Value) { if (losChecks >= maxLos) { return false; } if (maxLos > 0 && losChecks < maxLos) { losChecks++; int worldLosMask = GetWorldLosMask(); RaycastHit val4 = default(RaycastHit); if (Physics.Raycast(origin, val3, ref val4, magnitude, worldLosMask, (QueryTriggerInteraction)1)) { Component val5 = null; if ((Object)(object)((RaycastHit)(ref val4)).collider != (Object)null) { TreeBase componentInParent7 = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<TreeBase>(); if ((Object)(object)componentInParent7 != (Object)null) { val5 = (Component)(object)componentInParent7; } else { TreeLog componentInParent8 = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<TreeLog>(); if ((Object)(object)componentInParent8 != (Object)null) { val5 = (Component)(object)componentInParent8; } else { MineRock componentInParent9 = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<MineRock>(); if ((Object)(object)componentInParent9 != (Object)null) { val5 = (Component)(object)componentInParent9; } else { MineRock5 componentInParent10 = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<MineRock5>(); if ((Object)(object)componentInParent10 != (Object)null) { val5 = (Component)(object)componentInParent10; } else { Destructible componentInParent11 = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<Destructible>(); if ((Object)(object)componentInParent11 != (Object)null) { val5 = (Component)(object)componentInParent11; } else { WearNTear componentInParent12 = ((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<WearNTear>(); if ((Object)(object)componentInParent12 != (Object)null) { val5 = (Component)(object)componentInParent12; } } } } } } } if (val5 != val) { return false; } } } } hitPoint = GetSafeHitPoint(col, nearPoint, center); bool flag = false; if ((Object)(object)componentInParent != (Object)null) { flag = true; } if ((Object)(object)componentInParent2 != (Object)null) { flag = true; } bool flag2 = false; if ((Object)(object)componentInParent3 != (Object)null) { flag2 = true; } if ((Object)(object)componentInParent4 != (Object)null) { flag2 = true; } HitData val6 = new HitData(); val6.m_attacker = ((Character)player).GetZDOID(); val6.m_point = hitPoint; val6.m_dir = val3; val6.m_pushForce = 0f; float num = Mathf.Max(0f, worldDamage); if (flag) { val6.m_damage.m_chop = num; } else if (flag2) { val6.m_damage.m_pickaxe = num; } else { val6.m_damage.m_blunt = num; } 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 = ""; text = ((shield == null) ? "" : ((shield.m_shared == null) ? "" : ((shield.m_shared.m_name != null) ? shield.m_shared.m_name : ""))); string text2 = text.ToLowerInvariant(); bool num = text2.Contains("iron") || text2.Contains("blackmetal") || text2.Contains("silver") || text2.Contains("bronze") || text2.Contains("metal"); bool flag = false; if (!num) { flag = text2.Contains("wood") || text2.Contains("tower"); } if (num) { volMul *= Mathf.Max(0.01f, MetalVolumeMul.Value); pitchMul *= Mathf.Max(0.01f, MetalPitchMul.Value); } else if (flag) { volMul *= Mathf.Max(0.01f, WoodVolumeMul.Value); pitchMul *= Mathf.Max(0.01f, WoodPitchMul.Value); } } private AudioSource GetOrCreateLocalSfxSource(Player player) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return null; } if ((Object)(object)_localSfxSource != (Object)null && (Object)(object)((Component)_localSfxSource).gameObject != (Object)null) { Transform transform = ((Component)_localSfxSource).transform; if ((Object)(object)transform != (Object)null && transform.IsChildOf(((Component)player).transform)) { return _localSfxSource; } } try { if ((Object)(object)_localSfxSource != (Object)null && (Object)(object)((Component)_localSfxSource).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)_localSfxSource).gameObject); } } catch { } GameObject val = new GameObject("ShieldBash_LocalSFX_Source"); val.transform.SetParent(((Component)player).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_002c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !((Object)(object)clip == (Object)null)) { AudioSource orCreateLocalSfxSource = GetOrCreateLocalSfxSource(player); if (!((Object)(object)orCreateLocalSfxSource == (Object)null)) { ((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 = null; string text2 = null; try { text = Assembly.GetExecutingAssembly().Location; text2 = Path.GetDirectoryName(text); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ShieldBash] Could not resolve DLL location: " + ex.Message)); } List<string> list = new List<string>(); AddBundleCandidates(list, text2); AddBundleCandidates(list, Path.Combine(text2 ?? string.Empty, "Assets")); AddBundleCandidates(list, Path.Combine(Paths.PluginPath, "ShieldBash")); AddBundleCandidates(list, Path.Combine(Paths.PluginPath, "ShieldBash", "Assets")); AddBundleCandidates(list, Paths.PluginPath); string text3 = null; for (int i = 0; i < list.Count; i++) { string text4 = list[i]; if (!string.IsNullOrEmpty(text4) && File.Exists(text4)) { text3 = text4; break; } } if (text3 == null && !string.IsNullOrEmpty(text2) && Directory.Exists(text2)) { try { string[] files = Directory.GetFiles(text2, "*", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { string fileName = Path.GetFileName(files[i]); if (fileName.Equals("shieldbashbundle", StringComparison.OrdinalIgnoreCase) || fileName.Equals("shieldbashbundle.bundle", StringComparison.OrdinalIgnoreCase)) { text3 = files[i]; break; } } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ShieldBash] Bundle fallback search failed: " + ex2.Message)); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ShieldBash] DLL: " + (text ?? "unknown"))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ShieldBash] AssetBundle: " + (text3 ?? "NOT FOUND"))); if (text3 == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] Put 'shieldbashbundle' next to ShieldBash.dll or into an Assets subfolder."); return false; } AssetBundle val = null; try { val = AssetBundle.LoadFromFile(text3); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] Unity returned null while loading the AssetBundle. Rebuild it with Unity 6000.0.61f1 for StandaloneWindows64."); return false; } string[] allAssetNames = val.GetAllAssetNames(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ShieldBash] Bundle contains " + allAssetNames.Length + " assets.")); _bashClip = FindAnimationClip(val, "AttackShield01"); _hitClip = FindAudioClip(val, HitClipName.Value); _missClip = FindAudioClip(val, MissClipName.Value); if ((Object)(object)_bashClip == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] AnimationClip 'AttackShield01' was not found in the AssetBundle."); ((BaseUnityPlugin)this).Logger.LogError((object)("[ShieldBash] Assets:\n - " + string.Join("\n - ", allAssetNames))); return false; } if ((Object)(object)_hitClip == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ShieldBash] Hit AudioClip was not found: " + HitClipName.Value)); } if ((Object)(object)_missClip == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ShieldBash] Miss AudioClip was not found: " + MissClipName.Value)); } return true; } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ShieldBash] AssetBundle load exception: " + ex3)); return false; } finally { if ((Object)(object)val != (Object)null) { val.Unload(false); } } } private static void AddBundleCandidates(List<string> candidates, string directory) { if (!string.IsNullOrEmpty(directory)) { candidates.Add(Path.Combine(directory, "shieldbashbundle")); candidates.Add(Path.Combine(directory, "shieldbashbundle.bundle")); } } private static AnimationClip FindAnimationClip(AssetBundle bundle, string preferredName) { AnimationClip[] array = bundle.LoadAllAssets<AnimationClip>(); if (array == null || array.Length == 0) { return null; } foreach (AnimationClip val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name.Equals(preferredName, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } private static AudioClip FindAudioClip(AssetBundle bundle, string preferredName) { AudioClip[] array = bundle.LoadAllAssets<AudioClip>(); if (array == null || array.Length == 0) { return null; } string value = (preferredName ?? string.Empty).Trim(); foreach (AudioClip val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name.Equals(value, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } private ZNetView GetZNetView(Character character) { if ((Object)(object)character == (Object)null || CharacterNViewField == null) { return null; } try { object? value = CharacterNViewField.GetValue(character); return (ZNetView)((value is ZNetView) ? value : null); } catch { return null; } } private Animator GetAnimator(Character character) { if ((Object)(object)character == (Object)null || CharacterAnimatorField == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] Character.m_animator was not found."); return null; } try { object? value = CharacterAnimatorField.GetValue(character); return (Animator)((value is Animator) ? value : null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ShieldBash] Cannot read Character.m_animator: " + ex.Message)); return null; } } private Rigidbody GetCharacterBody(Character character) { if ((Object)(object)character == (Object)null || CharacterBodyField == null) { return null; } try { object? value = CharacterBodyField.GetValue(character); return (Rigidbody)((value is Rigidbody) ? value : null); } catch { return null; } } private ItemData GetLeftItem(Humanoid humanoid) { if ((Object)(object)humanoid == (Object)null || HumanoidLeftItemField == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[ShieldBash] Humanoid.m_leftItem was not found."); return null; } try { object? value = HumanoidLeftItemField.GetValue(humanoid); return (ItemData)((value is ItemData) ? value : null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ShieldBash] Cannot read Humanoid.m_leftItem: " + ex.Message)); return null; } } private static void EnsureLocalizationReflection() { if (_locRefReady) { return; } _locRefReady = true; try { _locType = AccessTools.TypeByName("Localization"); if (!(_locType == null)) { _locInstanceProp = _locType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public); _locGetSelectedLanguage = _locType.GetMethod("GetSelectedLanguage", BindingFlags.Instance | BindingFlags.Public); } } catch { _locType = null; _locInstanceProp = null; _locGetSelectedLanguage = null; } } private static string GetGameLanguage() { EnsureLocalizationReflection(); if (_locInstanceProp == null || _locGetSelectedLanguage == null) { return null; } try { object value = _locInstanceProp.GetValue(null, null); if (value == null) { return null; } return _locGetSelectedLanguage.Invoke(value, null) as string; } catch { return null; } } private static bool IsRussianUi() { string gameLanguage = GetGameLanguage(); if (string.IsNullOrEmpty(gameLanguage)) { return false; } gameLanguage = gameLanguage.ToLowerInvariant(); if (!gameLanguage.Contains("russian")) { return gameLanguage.StartsWith("ru"); } return true; } internal string BuildTooltipLineForShield(ItemData item) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (item == null || item.m_shared == null) { return null; } if ((int)item.m_shared.m_itemType != 5) { return null; } Player localPlayer = Player.m_localPlayer; float blockingSkillFactor = GetBlockingSkillFactor(localPlayer); float baseDamage = ComputeShieldBaseDamage(item); float num = DamageRandomMin.Value; float num2 = DamageRandomMax.Value; if (num > num2) { float num3 = num; num = num2; num2 = num3; } float num4 = ApplySkillAndRandom(baseDamage, blockingSkillFactor, num); float num5 = ApplySkillAndRandom(baseDamage, blockingSkillFactor, num2); float num6 = ComputeStaminaCost(localPlayer, item); if (IsRussianUi()) { return $"\nУдар щитом: {num4:0}–{num5:0} (дробящий)\nВыносливость: {num6:0.#}\nКлавиша: {BashKey.Value}; перезарядка: {Cooldown.Value:0.#} с\n"; } return $"\nShield Bash: {num4:0}–{num5:0} (blunt)\nStamina: {num6:0.#}\nKey: {BashKey.Value}; cooldown: {Cooldown.Value:0.#}s\n"; } private static AttackPhase Phase(Attack attack) { return AttackPhases.GetValue(attack, (Attack key) => new AttackPhase()); } private void ConfigureInterrupt() { InterruptEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Combat", "InterruptEnabled", true, "Interrupt one ordinary enemy's melee windup. Creature owner decides; 4s shared protection. Install 1.6.x on server and all clients."); } private static bool IsInterruptCandidate(Character target) { if ((Object)(object)target != (Object)null && !(target is Player) && target is Humanoid && target.GetBaseAI() is MonsterAI && !target.IsBoss() && !target.IsTamed() && !target.IsDead() && !target.IsStaggering()) { return target.InAttack(); } return false; } private static bool IsMeleeWindup(Attack attack) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 if (attack == null || AttackDoneField == null || AttackAbortField == null) { return false; } if ((bool)AttackDoneField.GetValue(attack) || (bool)AttackAbortField.GetValue(attack)) { return false; } if ((int)attack.m_attackType != 0 && (int)attack.m_attackType != 1) { return false; } if (attack.m_loopingAttack || attack.m_attackKillsSelf) { return false; } AttackPhase attackPhase = Phase(attack); if (!attackPhase.Triggered) { return !attackPhase.Interrupted; } return false; } private static bool ConsumeAttackTrigger(Attack attack) { AttackPhase attackPhase = Phase(attack); if (attackPhase.Interrupted) { return false; } attackPhase.Triggered = true; return true; } private static bool HasInterruptProtection(long now, long until) { return until > now; } private static bool IsRecentInterruptRequest(long now, long sent) { if (sent >= now - 7500000) { return sent <= now + 2500000; } return false; } private void RegisterInterruptRpc(Character target) { if ((Object)(object)target == (Object)null || target is Player) { return; } ZNetView zNetView = GetZNetView(target); if (!((Object)(object)zNetView == (Object)null) && zNetView.IsValid()) { zNetView.Register<ZDOID, long>("mexanik.shieldbash.InterruptV1", (Action<long, ZDOID, long>)delegate(long sender, ZDOID attackerId, long sent) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) ReceiveInterrupt(target, sender, attackerId, sent); }); } } private void RequestInterrupt(Player attacker, Character target) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (InterruptEnabled.Value && !((Object)(object)ZNet.instance == (Object)null)) { ZNetView zNetView = GetZNetView(target); if (!((Object)(object)zNetView == (Object)null) && zNetView.IsValid()) { zNetView.InvokeRPC("mexanik.shieldbash.InterruptV1", new object[2] { ((Character)attacker).GetZDOID(), ZNet.instance.GetTime().Ticks }); } } } private void ReceiveInterrupt(Character target, long sender, ZDOID attackerId, long sent) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Invalid comparison between Unknown and I4 //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0292: 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_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) if (!((Behaviour)this).isActiveAndEnabled || !InterruptEnabled.Value || (Object)(object)ZNet.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || !IsInterruptCandidate(target)) { return; } long ticks = ZNet.instance.GetTime().Ticks; if (!IsRecentInterruptRequest(ticks, sent)) { return; } ZNetView zNetView = GetZNetView(target); if ((Object)(object)zNetView == (Object)null || !zNetView.IsValid() || !zNetView.IsOwner()) { return; } GameObject val = ZNetScene.instance.FindInstance(attackerId); Player val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Player>() : null); if ((Object)(object)val2 == (Object)null || ((Character)val2).IsDead()) { return; } ZNetView zNetView2 = GetZNetView((Character)(object)val2); if ((Object)(object)zNetView2 == (Object)null || !zNetView2.IsValid() || zNetView2.GetZDO().GetOwner() != sender) { return; } ItemData leftItem = GetLeftItem((Humanoid)(object)val2); if (leftItem == null || leftItem.m_shared == null || (int)leftItem.m_shared.m_itemType != 5) { return; } Vector3 val3 = ((Component)val2).transform.position + Vector3.up * 1.3f; Vector3 val4 = ((Component)target).transform.position + Vector3.up * 1.1f - val3; float magnitude = ((Vector3)(ref val4)).magnitude; RaycastHit val5 = default(RaycastHit); if (magnitude < 0.001f || magnitude > Mathf.Min(4f, Mathf.Max(0f, Range.Value) + Mathf.Max(0f, Radius.Value) + 0.5f) || Vector3.Dot(((Component)val2).transform.forward, val4 / magnitude) < GetCosHalfAngle() || (Physics.Raycast(val3, val4 / magnitude, ref val5, magnitude, GetWorldLosMask(), (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val5)).collider).GetComponentInParent<Character>() != (Object)(object)target) || CurrentAttackField == null || StaggerFactorField == null || (float)StaggerFactorField.GetValue(target) <= 0f) { return; } object? value = CurrentAttackField.GetValue(target); Attack val6 = (Attack)((value is Attack) ? value : null); if (IsMeleeWindup(val6)) { ZDO zDO = zNetView.GetZDO(); if (!HasInterruptProtection(ticks, zDO.GetLong("mexanik.shieldbash.interruptUntilV1", 0L))) { zDO.Set("mexanik.shieldbash.interruptUntilV1", ticks + 40000000); Phase(val6).Interrupted = true; val6.Abort(); Vector3 val7 = ((Component)target).transform.position - ((Component)val2).transform.position; target.Stagger(((Vector3)(ref val7)).normalized); } } } }