Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ShieldBash v1.5.5
BepInEx/plugins/ShieldBash/ShieldBash.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Managers; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Playables; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ShieldBash")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ShieldBash")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("be1580d5-2dda-4cf4-b5c8-d4f902314e67")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace ShieldBashMod; [BepInPlugin("mexanik.shieldbash", "ShieldBash", "1.5.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class ShieldBashPlugin : BaseUnityPlugin { [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 method in methods) { if (method != null && method.Name == "GetTooltip" && method.ReturnType == typeof(string)) { yield return method; } } } private static void Postfix(ItemData __instance, ref string __result) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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)); } } } } public const string PluginGUID = "mexanik.shieldbash"; public const string PluginName = "ShieldBash"; public const string PluginVersion = "1.5.5"; 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> 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 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 void Awake() { //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_071a: Expected O, but got Unknown //IL_078b: Unknown result type (might be due to invalid IL or missing references) //IL_0795: 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"); 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 (CPU saver)."); 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)"); 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() { 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Invalid comparison between Unknown and I4 if (ZInput.instance == null || !ZInput.GetButtonDown(_bashButton.Name)) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || _isBashing || Time.time < _nextUseTime) { 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)) { return; } float cost = ComputeStaminaCost(localPlayer, leftItem); if (TryUseStaminaNoMessage(localPlayer, cost)) { Animator animator = GetAnimator((Character)localPlayer); if (!((Object)(object)animator == (Object)null)) { EnsureBuffers(); _nextUseTime = Time.time + Cooldown.Value; ((MonoBehaviour)this).StartCoroutine(DoBash(localPlayer, animator, _bashClip, applyDamage: true)); BroadcastBashVisual(localPlayer); } } } private IEnumerator DoBash(Player player, Animator animator, AnimationClip clip, bool applyDamage) { if (applyDamage) { _isBashing = true; } bool prevRootMotion = animator.applyRootMotion; PlayableGraph graph = default(PlayableGraph); try { if (AntiSlideTime.Value > 0.0001f) { ((MonoBehaviour)this).StartCoroutine(AntiSlideRoutine(player, AntiSlideTime.Value)); } animator.applyRootMotion = false; graph = PlayableGraph.Create("ShieldBashGraph"); AnimatorControllerPlayable controllerPlayable = AnimatorControllerPlayable.Create(graph, animator.runtimeAnimatorController); AnimationClipPlayable clipPlayable = AnimationClipPlayable.Create(graph, clip); ((AnimationClipPlayable)(ref clipPlayable)).SetApplyFootIK(false); ((AnimationClipPlayable)(ref clipPlayable)).SetApplyPlayableIK(false); AnimationLayerMixerPlayable mixer = AnimationLayerMixerPlayable.Create(graph, 2); ((PlayableGraph)(ref graph)).Connect<AnimatorControllerPlayable, AnimationLayerMixerPlayable>(controllerPlayable, 0, mixer, 0); ((PlayableGraph)(ref graph)).Connect<AnimationClipPlayable, AnimationLayerMixerPlayable>(clipPlayable, 0, mixer, 1); PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(mixer, 0, 0f); PlayableExtensions.SetInputWeight<AnimationLayerMixerPlayable>(mixer, 1, 1f); AnimationPlayableOutput output = AnimationPlayableOutput.Create(graph, "ShieldBashOutput", animator); PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationLayerMixerPlayable>(output, mixer); ((PlayableGraph)(ref graph)).Play(); float hitAt = Mathf.Clamp(HitDelay.Value, 0.01f, Mathf.Max(0.01f, clip.length)); yield return (object)new WaitForSeconds(hitAt); if ((Object)(object)player != (Object)null) { if (applyDamage) { ApplyBashDamageAndSfx(player); } else { PlayRemoteBashSfx(player); } } float remain = Mathf.Max(0.01f, clip.length - hitAt); yield return (object)new WaitForSeconds(remain); } finally { if (((PlayableGraph)(ref graph)).IsValid()) { ((PlayableGraph)(ref graph)).Destroy(); } if ((Object)(object)animator != (Object)null) { animator.applyRootMotion = prevRootMotion; } if (applyDamage) { _isBashing = false; } } } private void BroadcastBashVisual(Player player) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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() && !zNetView.IsOwner() && !((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_0015: 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_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_0034: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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 && !((Object)(object)player == (Object)null) && !((Object)(object)body == (Object)null)) { Vector3 v = body.linearVelocity; v.x = 0f; v.z = 0f; body.linearVelocity = v; SetMoveDirZero(player); t += Time.deltaTime; yield return null; } } } private static void SetMoveDirZero(Player player) { //IL_0027: 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 num = 0f; if (shield != null && shield.m_shared != null) { int num2 = Mathf.Max(1, shield.m_quality); num = shield.m_shared.m_blockPower + shield.m_shared.m_blockPowerPerLevel * (float)(num2 - 1); } float blockingSkillFactor = GetBlockingSkillFactor(player); float num3 = Mathf.Max(0f, BaseStaminaCost.Value) + num * Mathf.Max(0f, BlockPowerStaminaScale.Value); float num4 = blockingSkillFactor * Mathf.Clamp01(SkillStaminaReduction.Value); float num5 = num3 * (1f - num4); float num6 = Mathf.Max(0f, MinStaminaCost.Value); float num7 = Mathf.Max(num6, MaxStaminaCost.Value); return Mathf.Clamp(num5, num6, num7); } 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)(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); float num2 = baseDamage * (1f + skillFactor * num); num2 *= randMul; return Mathf.Clamp(num2, 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_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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) 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) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_01ab: 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_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: 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_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: 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_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: 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_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: 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_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0259: 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_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: 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_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_07c0: Unknown result type (might be due to invalid IL or missing references) //IL_07cb: 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_07df: 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_07f3: Unknown result type (might be due to invalid IL or missing references) //IL_0822: Unknown result type (might be due to invalid IL or missing references) //IL_0669: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) //IL_0671: Unknown result type (might be due to invalid IL or missing references) //IL_0673: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_07aa: Unknown result type (might be due to invalid IL or missing references) //IL_06a3: Unknown result type (might be due to invalid IL or missing references) //IL_06a5: Unknown result type (might be due to invalid IL or missing references) //IL_06e1: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0393: 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_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: 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_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Expected O, but got Unknown //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } HitOnceReset(); ItemData leftItem = GetLeftItem((Humanoid)player); float num = ComputeShieldBaseDamage(leftItem); float num2 = DamageRandomMin.Value; float num3 = DamageRandomMax.Value; if (num2 > num3) { float num4 = num2; num2 = num3; num3 = num4; } float num5 = Random.Range(num2, num3); float blockingSkillFactor = GetBlockingSkillFactor(player); float num6 = ApplySkillAndRandom(num, blockingSkillFactor, num5); float randMul = ((!WorldDamageUseRandom.Value) ? 1f : num5); float num7 = ApplySkillAndRandom(num, blockingSkillFactor, randMul) * Mathf.Clamp(WorldDamageScale.Value, 0f, 5f); float num8 = Mathf.Clamp01(Mathf.InverseLerp(MinDamage.Value, MaxDamage.Value, num6)); float num9 = Mathf.Lerp(HitSfxVolumeMin.Value, HitSfxVolumeMax.Value, num8); float num10 = Mathf.Max(0f, MissSfxVolume.Value); GetMaterialMix(leftItem, out var volMul, out var pitchMul); float num11 = Random.Range(Mathf.Min(RandomVolJitterMin.Value, RandomVolJitterMax.Value), Mathf.Max(RandomVolJitterMin.Value, RandomVolJitterMax.Value)); float num12 = 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 num13 = Physics.OverlapCapsuleNonAlloc(val3, val4, Radius.Value, _overlapCols, overlapMask, (QueryTriggerInteraction)2); int num14 = 0; 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 < num13; i++) { Collider val5 = _overlapCols[i]; if ((Object)(object)val5 == (Object)null) { continue; } Character componentInParent = ((Component)val5).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) { Player val6 = (Player)(object)((componentInParent is Player) ? componentInParent : null); if ((Object)(object)val6 != (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; float num16 = Vector3.Dot(forward, val9); if (num16 < cosHalfAngle) { continue; } if (LineOfSightCheck.Value && 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())) { float num17 = Mathf.Clamp(num6, MinDamage.Value, MaxDamage.Value); Vector3 safeHitPoint = GetSafeHitPoint(val5, nearPoint, val7); float num18 = 0f; if (DebugLogDamageAfterArmor.Value) { num18 = 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 = num17; componentInParent.Damage(val12); 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} (damage={3:0.0}) hp {4:0.0}->{5:0.0}", "ShieldBash", ((Object)componentInParent).name, num19, num17, num18, health)); } num14++; if (num14 == 1) { pos = safeHitPoint; } if (PlayHitSfxPerTarget.Value) { float volumeMul = Mathf.Max(0f, num9 * volMul * num11); float pitchMul2 = Mathf.Max(0.01f, pitchMul * num12); PlayLocalHitAt(player, safeHitPoint, volumeMul, pitchMul2); } } } else { if (!DamageWorldObjects.Value) { continue; } Vector3 hitPoint = val; if (TryDamageWorldObject(val5, player, val, forward, cosHalfAngle, ref losChecks, num15, num7, nearPoint, out hitPoint)) { num14++; if (num14 == 1) { pos = hitPoint; } if (PlayHitSfxPerTarget.Value) { float volumeMul2 = Mathf.Max(0f, num9 * volMul * num11); float pitchMul3 = Mathf.Max(0.01f, pitchMul * num12); PlayLocalHitAt(player, hitPoint, volumeMul2, pitchMul3); } } } } if (!PlayHitSfxPerTarget.Value) { if (num14 > 0) { float num20 = 0f; if (num14 > 1) { float num21 = MultiHitBonusMin.Value; float num22 = MultiHitBonusMax.Value; if (num21 > num22) { float num23 = num21; num21 = num22; num22 = num23; } num20 = Random.Range(num21, num22); } float volumeMul3 = Mathf.Max(0f, (num9 + num20) * volMul * num11); float pitchMul4 = Mathf.Max(0.01f, pitchMul * num12); 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, num10 * volMul * num11); float pitchMul5 = Mathf.Max(0.01f, 1.02f * pitchMul * num12); 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}, char={4:0.0}, world={5:0.0}, hits={6}, LoS={7}/{8}, overlap={9}", "ShieldBash", num, blockingSkillFactor, num5, num6, num7, num14, losChecks, num15, num13)); } } 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_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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0306: 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_030a: Unknown result type (might be due to invalid IL or missing references) //IL_030f: 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_01c9: 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_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Expected O, but got Unknown //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: 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) 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 && 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 flag = text2.Contains("iron") || text2.Contains("blackmetal") || text2.Contains("silver") || text2.Contains("bronze") || text2.Contains("metal"); bool flag2 = false; if (!flag) { flag2 = 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 player) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown 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_0009: 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_0009: 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_003b: 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(); return gameLanguage.Contains("russian") || gameLanguage.StartsWith("ru"); } internal string BuildTooltipLineForShield(ItemData item) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 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"; } return $"\nShield Bash: {num4:0}–{num5:0} (blunt)\nStamina: {num6:0.#}\n"; } }