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 ComboSpear v1.0.2
BepInEx/plugins/ComboSpear.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ComboSpear")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ComboSpear")] [assembly: AssemblyTitle("ComboSpear")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SpearCombo { [BepInPlugin("andythedemon.combospear", "Combo Spear", "1.0.1")] public class Plugin : BaseUnityPlugin { internal readonly struct Setting<T> { private readonly T value; internal T Value => value; internal Setting(T v) { value = v; } } public const string Guid = "andythedemon.combospear"; public const string PluginName = "Combo Spear"; public const string Version = "1.0.1"; internal const string ComboTrigger = "spearcombo"; internal const string VanillaPoke = "spear_poke"; internal const string ThrowTrigger = "spear_throw"; internal const string GuardTrigger = "spearguard"; internal const string IgnoredTrigger = "spear_dup_ignored"; internal const float LungeHitSeconds = 0.667f; internal const float ThrowWindowSeconds = 1.6f; internal const string KnifeLunge = "knife-lunge"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static readonly Setting<float> NormalHitDamage = new Setting<float>(1f); internal static readonly Setting<float> BlockHitDamage = new Setting<float>(1f); internal static readonly Setting<float> ThrowDamage = new Setting<float>(0.5f); internal static readonly Setting<string>[] Hit = new Setting<string>[3] { new Setting<string>("knife_stab0"), new Setting<string>("knife_stab1"), new Setting<string>("knife_stab2") }; internal static readonly Setting<float>[] HitSpeed = new Setting<float>[3] { new Setting<float>(1f), new Setting<float>(1f), new Setting<float>(1f) }; internal static readonly Setting<Vector3>[] HitRotation = new Setting<Vector3>[3] { new Setting<Vector3>(Vector3.zero), new Setting<Vector3>(Vector3.zero), new Setting<Vector3>(Vector3.zero) }; internal static readonly Setting<Vector3>[] HitOffset = new Setting<Vector3>[3] { new Setting<Vector3>(Vector3.zero), new Setting<Vector3>(Vector3.zero), new Setting<Vector3>(Vector3.zero) }; internal static readonly Setting<float> LastHitDamage = new Setting<float>(2f); internal static readonly Setting<float> Range = new Setting<float>(3.2f); internal static readonly Setting<Vector3> ComboGrip = new Setting<Vector3>(new Vector3(-8f, 23f, 12f)); internal static readonly Setting<float> ComboGripBlend = new Setting<float>(0.12f); internal static readonly Setting<float> ComboGripOut = new Setting<float>(0.25f); internal static readonly Setting<bool> JumpBackThrow = new Setting<bool>(v: true); internal static readonly Setting<bool> KeepBlockPose = new Setting<bool>(v: false); internal static readonly Setting<bool> DefenceCombo = new Setting<bool>(v: true); internal static readonly Setting<float> GuardReset = new Setting<float>(1f); internal static readonly Setting<float> GuardHold = new Setting<float>(0f); internal static readonly Setting<string>[] GuardClip = new Setting<string>[3] { new Setting<string>("SpearGuard1"), new Setting<string>("SpearGuard2"), new Setting<string>("SpearGuard3") }; internal static readonly Setting<float>[] GuardDamage = new Setting<float>[3] { new Setting<float>(0.5f), new Setting<float>(0.7f), new Setting<float>(1f) }; internal static readonly Setting<float> JumpBackHeight = new Setting<float>(1f); internal static readonly Setting<float> JumpBackDistance = new Setting<float>(2f); internal static readonly Setting<float> JumpBackDelay = new Setting<float>(0.2f); internal static readonly Setting<string> ThrowCustomClip = new Setting<string>("SpearThrowBack"); internal static readonly Setting<string> ThrowCustomClipFree = new Setting<string>("SpearThrowBack_Free"); internal static readonly Setting<string> ThrowReplacesClip = new Setting<string>("throw_spear"); internal static readonly Setting<string> PlainThrowClip = new Setting<string>("SpearThrowPlain"); internal static readonly Setting<bool> Flip = new Setting<bool>(v: true); internal static readonly Setting<bool> Dump = new Setting<bool>(v: false); internal static readonly Setting<string> CustomBundle = new Setting<string>("spearcombo.bundle"); internal static readonly Setting<bool> TrueDamageNumbers = new Setting<bool>(v: true); internal static readonly Setting<string>[] HitCustomClip = new Setting<string>[3] { new Setting<string>("SpearJab1"), new Setting<string>("SpearJab2"), new Setting<string>("SpearLunge") }; internal static readonly Setting<string>[] HitCustomClipFree = new Setting<string>[3] { new Setting<string>("SpearJab1_Free"), new Setting<string>("SpearJab2_Free"), new Setting<string>("SpearLunge_Free") }; internal static readonly Setting<string>[] HitReplaceClip = new Setting<string>[3] { new Setting<string>("knife_slash0"), new Setting<string>("knife_slash1"), new Setting<string>("knife_slash2") }; internal static string PluginFolder; private bool dumped; private void Awake() { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Expected O, but got Unknown //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Expected O, but got Unknown //IL_02fe: Expected O, but got Unknown //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Expected O, but got Unknown //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_01a0: 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_01c8: Expected O, but got Unknown //IL_01c8: Expected O, but got Unknown //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) //IL_058b: Expected O, but got Unknown //IL_058b: Expected O, but got Unknown //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_05c2: Unknown result type (might be due to invalid IL or missing references) //IL_05cd: Expected O, but got Unknown //IL_05cd: Expected O, but got Unknown //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05f5: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turns Combo Spear on or off. Off: spears attack, block and throw exactly as in vanilla. Takes effect the next time the game starts."); if (!Enabled.Value) { Log.LogInfo((object)"Combo Spear 1.0.1 is turned off in its config (General / Enabled) - nothing is changed."); return; } Log.LogInfo((object)$"Damage: normal hits x{NormalHitDamage.Value:0.##}, block hits x{BlockHitDamage.Value:0.##}, jump-back throw x{ThrowDamage.Value:0.##}."); PluginFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); Refs.Init(); if (Chainloader.PluginInfos.ContainsKey("goldenrevolver.ProperSpears")) { Log.LogWarning((object)"Proper Spears is installed too - both change spears; disable one of them."); } Harmony val = new Harmony("andythedemon.combospear"); val.PatchAll(typeof(Plugin).Assembly); try { MethodInfo methodInfo = AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Player), "InAttack", (Type[])null, (Type[])null); if (methodInfo != null && methodInfo2 != null && Refs.CurrentAttack != null && Refs.Zanim != null) { val.Patch((MethodBase)methodInfo2, new HarmonyMethod(AccessTools.Method(typeof(LungeCancel), "InAttackPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(LungeCancel), "Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LungeCancel), "Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); } else { Log.LogError((object)"StartAttack / Player.InAttack / m_currentAttack / m_zanim not found; cancelling the lunge is off."); } } catch (Exception ex) { Log.LogError((object)("Could not patch the lunge cancel (" + ex.GetType().Name + "); cancelling the lunge is off.")); } try { MethodInfo methodInfo3 = AccessTools.Method(typeof(Character), "ApplyDamage", new Type[4] { typeof(HitData), typeof(bool), typeof(bool), typeof(DamageModifier) }, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(DamageText), "ShowText", new Type[4] { typeof(DamageModifier), typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null); if (methodInfo3 != null && methodInfo4 != null) { val.Patch((MethodBase)methodInfo3, new HarmonyMethod(AccessTools.Method(typeof(TrueDamage), "ApplyPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(TrueDamage), "ApplyFinalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); val.Patch((MethodBase)methodInfo4, new HarmonyMethod(AccessTools.Method(typeof(TrueDamage), "ShowTextPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"True damage numbers: on (shows the damage a hit really deals)."); } else { Log.LogError((object)"Character.ApplyDamage / DamageText.ShowText not found; damage numbers are left as they are."); } } catch (Exception ex2) { Log.LogError((object)("Could not patch the damage numbers (" + ex2.GetType().Name + "); they are left as they are.")); } try { MethodInfo methodInfo5 = AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, (Type[])null); if (methodInfo5 != null && Refs.CurrentAttack != null) { val.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(SoftThrow), "Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.LogError((object)"Humanoid.StartAttack / m_currentAttack not found; the jump-back throw hits at full damage."); } } catch (Exception ex3) { Log.LogError((object)("Could not patch the jump-back throw damage (" + ex3.GetType().Name + "); it hits at full damage.")); } try { MethodInfo methodInfo6 = AccessTools.Method(typeof(Attack), "FireProjectileBurst", (Type[])null, (Type[])null); if (methodInfo6 != null) { val.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(GameThrowWatch), "BurstPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception ex4) { Log.LogError((object)("Could not watch projectile bursts (" + ex4.GetType().Name + "); the throw fallback may double-fire.")); } try { MethodInfo methodInfo7 = AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, (Type[])null); MethodInfo methodInfo8 = AccessTools.Method(typeof(Character), "RPC_Damage", (Type[])null, (Type[])null); MethodInfo methodInfo9 = AccessTools.Method(typeof(Humanoid), "IsBlocking", (Type[])null, (Type[])null); if (methodInfo7 != null && methodInfo8 != null && methodInfo9 != null && Refs.Blocking != null && Refs.CurrentAttack != null) { val.Patch((MethodBase)methodInfo7, new HarmonyMethod(AccessTools.Method(typeof(GuardCombo), "Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(GuardCombo), "Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); val.Patch((MethodBase)methodInfo8, new HarmonyMethod(AccessTools.Method(typeof(GuardCombo), "DamagePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(GuardCombo), "DamageFinalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); val.Patch((MethodBase)methodInfo9, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(GuardCombo), "IsBlockingPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.LogError((object)"StartAttack / RPC_Damage / IsBlocking / m_blocking not found; the defence combo is off."); } } catch (Exception ex5) { Log.LogError((object)("Could not patch the defence combo (" + ex5.GetType().Name + "); it is off.")); } Log.LogInfo((object)"Combo Spear 1.0.1 loaded."); } private void Update() { if (Enabled == null || !Enabled.Value) { return; } WiresShim.Ensure(); if (dumped || !Dump.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } dumped = true; try { AnimationDump.Write(Player.m_localPlayer); } catch (Exception ex) { Log.LogError((object)("Animation dump failed: " + ex)); } } } internal sealed class ConfigurationManagerAttributes { public Action<ConfigEntryBase> CustomDrawer; public int? Order; } internal static class Refs { internal static FieldRef<Attack, int> ChainLevels; internal static FieldRef<Attack, float> LastChainDamage; internal static FieldRef<Attack, int> ChainLevel; internal static FieldRef<ZSyncAnimation, Animator> AnimatorOf; internal static FieldRef<VisEquipment, GameObject> RightItem; internal static FieldRef<VisEquipment, int> LeftItemHash; internal static FieldRef<VisEquipment, int> RightItemHash; internal static FieldInfo SecondaryAttack; internal static FieldInfo CurrentAttack; internal static FieldInfo Zanim; internal static FieldInfo Blocking; internal static FieldRef<Humanoid, bool> InternalBlocking; internal static FieldRef<Player, float> QueuedAttack; internal static FieldRef<Humanoid, float> TimeSinceLastAttack; internal static FieldInfo BlockingAnimHash; internal static MethodInfo FireProjectileBurst; internal static Transform CharacterRoot(Transform t) { Character componentInParent = ((Component)t).GetComponentInParent<Character>(); if (!((Object)(object)componentInParent != (Object)null)) { return t.root; } return ((Component)componentInParent).transform; } internal static void Init() { ChainLevels = Get<Attack, int>("m_attackChainLevels"); LastChainDamage = Get<Attack, float>("m_lastChainDamageMultiplier"); ChainLevel = Get<Attack, int>("m_currentAttackCainLevel"); AnimatorOf = Get<ZSyncAnimation, Animator>("m_animator"); RightItem = Get<VisEquipment, GameObject>("m_rightItemInstance"); LeftItemHash = Get<VisEquipment, int>("m_currentLeftItemHash"); RightItemHash = Get<VisEquipment, int>("m_currentRightItemHash"); SecondaryAttack = AccessTools.Field(typeof(SharedData), "m_secondaryAttack"); CurrentAttack = AccessTools.Field(typeof(Humanoid), "m_currentAttack"); Zanim = AccessTools.Field(typeof(Character), "m_zanim"); Blocking = AccessTools.Field(typeof(Character), "m_blocking"); InternalBlocking = Get<Humanoid, bool>("m_internalBlockingState"); QueuedAttack = Get<Player, float>("m_queuedAttackTimer"); TimeSinceLastAttack = Get<Humanoid, float>("m_timeSinceLastAttack"); BlockingAnimHash = AccessTools.Field(typeof(Humanoid), "s_blocking"); FireProjectileBurst = AccessTools.Method(typeof(Attack), "FireProjectileBurst", (Type[])null, (Type[])null); if (CurrentAttack == null || Zanim == null) { Plugin.Log.LogError((object)"m_currentAttack / m_zanim not found; cancelling the lunge is off."); } } private static FieldRef<T, F> Get<T, F>(string field) where T : class { try { return AccessTools.FieldRefAccess<T, F>(field); } catch (Exception ex) { Plugin.Log.LogError((object)("Field " + typeof(T).Name + "." + field + " not found (" + ex.GetType().Name + "); that feature is off.")); return null; } } internal static int Levels(Attack a) { if (ChainLevels == null) { return 1; } return ChainLevels.Invoke(a); } } internal static class Combo { private static string resolvedLunge; internal static bool IsComboSpear(SharedData s) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (s != null && (int)s.m_skillType == 5 && s.m_attack != null) { if (!(s.m_attack.m_attackAnimation == "spear_poke")) { return s.m_attack.m_attackAnimation == "spearcombo"; } return true; } return false; } internal static SharedData SharedOf(GameObject go) { ItemDrop val = (Object.op_Implicit((Object)(object)go) ? go.GetComponent<ItemDrop>() : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.m_itemData?.m_shared; } internal static SharedData SharedFromHash(int hash) { if (hash != 0 && !((Object)(object)ObjectDB.instance == (Object)null)) { return SharedOf(ObjectDB.instance.GetItemPrefab(hash)); } return null; } internal static void Apply(SharedData s) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if (s == null || (int)s.m_skillType != 5 || s.m_attack == null) { return; } Attack attack = s.m_attack; if (attack.m_attackAnimation != "spear_poke" || Refs.ChainLevels == null) { return; } attack.m_attackAnimation = "spearcombo"; Refs.ChainLevels.Invoke(attack) = 3; DestructibleType resetChainIfHit = attack.m_resetChainIfHit; attack.m_resetChainIfHit = (DestructibleType)0; if (Refs.LastChainDamage != null) { Refs.LastChainDamage.Invoke(attack) = Plugin.LastHitDamage.Value; } attack.m_attackRange = Plugin.Range.Value; attack.m_attackHeight = 1f; attack.m_attackAngle = 30f; attack.m_attackRayWidth = 0.4f; if (Plugin.JumpBackThrow.Value) { object? obj = Refs.SecondaryAttack?.GetValue(s); Attack val = (Attack)((obj is Attack) ? obj : null); if (val != null) { val.m_damageMultiplier = 1f; } } Plugin.Log.LogInfo((object)$"Combo applied to {s.m_name} (chain reset-if-hit {resetChainIfHit} -> None)."); } internal static string MapTrigger(string name, out int level) { return MapTrigger(name, "spearcombo", out level); } internal static string MapTrigger(string name, string prefix, out int level) { level = 0; if (name.Length > prefix.Length) { int.TryParse(name.Substring(prefix.Length), out level); } level = Mathf.Clamp(level, 0, 2); return Resolve(Plugin.Hit[level].Value); } internal static string Resolve(string configured) { if (!(configured == "knife-lunge")) { return configured; } return LungeTrigger(); } private static string LungeTrigger() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 if (resolvedLunge != null) { return resolvedLunge; } if ((Object)(object)ObjectDB.instance != (Object)null && Refs.ChainLevels != null) { foreach (GameObject item in ObjectDB.instance.m_items) { SharedData val = SharedOf(item); if (val != null && (int)val.m_skillType == 2 && val.m_attack != null) { int num = Refs.Levels(val.m_attack); if (num >= 3 && !string.IsNullOrEmpty(val.m_attack.m_attackAnimation)) { resolvedLunge = val.m_attack.m_attackAnimation + (num - 1); Plugin.Log.LogInfo((object)("knife-lunge = '" + resolvedLunge + "' (from " + ((Object)item).name + ").")); return resolvedLunge; } } } } resolvedLunge = "knife_stab2"; Plugin.Log.LogWarning((object)("Could not read the knife combo; guessing '" + resolvedLunge + "'. Pick the lunge from the list if it does nothing.")); return resolvedLunge; } } internal class AnimOption { public string Trigger; public string Label; } internal static class AnimationCatalog { private static readonly HashSet<string> PlayerItemTypes = new HashSet<string> { "OneHandedWeapon", "TwoHandedWeapon", "TwoHandedWeaponLeft", "Bow", "Torch", "Tool" }; private static List<AnimOption> cache; internal static List<AnimOption> Get() { if (cache != null) { return cache; } if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_recipes == null || ObjectDB.instance.m_recipes.Count == 0) { return null; } HashSet<SharedData> hashSet = new HashSet<SharedData>(); foreach (Recipe recipe in ObjectDB.instance.m_recipes) { SharedData val = ((!((Object)(object)recipe != (Object)null) || !((Object)(object)recipe.m_item != (Object)null)) ? null : recipe.m_item.m_itemData?.m_shared); if (val != null) { hashSet.Add(val); } } HashSet<string> seen = new HashSet<string> { "knife-lunge" }; List<AnimOption> list = new List<AnimOption>(); foreach (GameObject item in ObjectDB.instance.m_items) { SharedData val2 = Combo.SharedOf(item); if (val2 != null && hashSet.Contains(val2) && PlayerItemTypes.Contains(((object)Unsafe.As<ItemType, ItemType>(ref val2.m_itemType)/*cast due to .constrained prefix*/).ToString())) { string weapon = Localize(val2.m_name); AddAttack(list, seen, weapon, "primary", val2.m_attack); object? obj = Refs.SecondaryAttack?.GetValue(val2); AddAttack(list, seen, weapon, "secondary", (Attack)((obj is Attack) ? obj : null)); } } list.Sort((AnimOption a, AnimOption b) => string.CompareOrdinal(a.Label, b.Label)); List<AnimOption> list2 = new List<AnimOption>(); list2.Add(new AnimOption { Trigger = "knife-lunge", Label = "knife-lunge (knife combo finisher, auto-detected)" }); list2.AddRange(list); cache = list2; return cache; } private static string Localize(string token) { try { return (Localization.instance != null) ? Localization.instance.Localize(token) : token; } catch { return token; } } private static void AddAttack(List<AnimOption> list, HashSet<string> seen, string weapon, string kind, Attack a) { if (a == null || string.IsNullOrEmpty(a.m_attackAnimation)) { return; } bool num = a.m_attackAnimation == "spearcombo"; string text = (num ? "spear_poke" : a.m_attackAnimation); int num2 = (num ? 1 : Refs.Levels(a)); if (num2 <= 1) { if (seen.Add(text)) { list.Add(new AnimOption { Trigger = text, Label = text + " (" + weapon + ", " + kind + ")" }); } return; } for (int i = 0; i < num2; i++) { string text2 = text + i; if (seen.Add(text2)) { list.Add(new AnimOption { Trigger = text2, Label = $"{text2} ({weapon}, {kind} hit {i + 1}/{num2})" }); } } } } internal static class AnimPicker { private static readonly Dictionary<ConfigEntryBase, bool> open = new Dictionary<ConfigEntryBase, bool>(); private static readonly Dictionary<ConfigEntryBase, Vector2> scroll = new Dictionary<ConfigEntryBase, Vector2>(); internal static void Draw(ConfigEntryBase entryBase) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<string> val = (ConfigEntry<string>)(object)entryBase; List<AnimOption> list = AnimationCatalog.Get(); open.TryGetValue((ConfigEntryBase)(object)val, out var value); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }) && list != null) { Step(val, list, -1); } string text = GUILayout.TextField(val.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (text != val.Value) { val.Value = text; } if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }) && list != null) { Step(val, list, 1); } if (GUILayout.Button(value ? "Close" : "List", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) })) { value = (open[(ConfigEntryBase)(object)val] = !value); } GUILayout.EndHorizontal(); if (value) { if (list == null) { GUILayout.Label("Enter a world first - the list is read from the game.", Array.Empty<GUILayoutOption>()); } else { scroll.TryGetValue((ConfigEntryBase)(object)val, out var value2); scroll[(ConfigEntryBase)(object)val] = GUILayout.BeginScrollView(value2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(260f) }); foreach (AnimOption item in list) { if (GUILayout.Button((item.Trigger == val.Value) ? ("> " + item.Label) : item.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) })) { val.Value = item.Trigger; open[(ConfigEntryBase)(object)val] = false; } } GUILayout.EndScrollView(); } } GUILayout.EndVertical(); } private static void Step(ConfigEntry<string> entry, List<AnimOption> options, int dir) { int num = options.FindIndex((AnimOption o) => o.Trigger == entry.Value); num = ((num >= 0) ? ((num + dir + options.Count) % options.Count) : 0); entry.Value = options[num].Trigger; } } internal static class AnimationDump { internal static void Write(Player player) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Valheim attack animations (written by Spear Combo). Use these names for Hit1..Hit3."); stringBuilder.AppendLine(); stringBuilder.AppendLine("== Attacks of player weapons (craftable) =="); List<AnimOption> list = AnimationCatalog.Get(); if (list != null) { foreach (AnimOption item in list) { stringBuilder.AppendLine(item.Label); } } Animator val = ((Refs.AnimatorOf != null) ? Refs.AnimatorOf.Invoke(((Component)player).GetComponent<ZSyncAnimation>()) : null); if ((Object)(object)val != (Object)null && (Object)(object)val.runtimeAnimatorController != (Object)null) { stringBuilder.AppendLine(); stringBuilder.AppendLine("== Animation clips in the player controller (for custom-clip replacement later) =="); SortedSet<string> sortedSet = new SortedSet<string>(StringComparer.Ordinal); AnimationClip[] animationClips = val.runtimeAnimatorController.animationClips; foreach (AnimationClip val2 in animationClips) { if ((Object)(object)val2 != (Object)null) { sortedSet.Add($"{((Object)val2).name} ({val2.length:0.00}s)"); } } foreach (string item2 in sortedSet) { stringBuilder.AppendLine(item2); } } string text = Path.Combine(Paths.BepInExRootPath, "SpearCombo-animations.txt"); File.WriteAllText(text, stringBuilder.ToString()); Plugin.Log.LogInfo((object)("Animation list written to " + text)); } } internal class FlipMark : MonoBehaviour { public bool Flipped; public bool Fang; public bool PoseActive; public float ReflipAt; public float GripW; public float RegripW; public bool RegripToss; public float LastTossLog; public bool AimLock; public float LastAimLog; public bool RegripJump; public bool TossCaptured; public Quaternion TossRot; public Vector3 TossPos; public bool TossHoldLogged; public int Level = -1; private ComboState state; private Humanoid owner; private void LateUpdate() { if (!Flipped) { GripW = 0f; return; } if ((Object)(object)state == (Object)null) { state = ((Component)this).GetComponentInParent<ComboState>(); } RegripW = (((Object)(object)state != (Object)null && state.ThrowAt > 0f) ? SpearFlip.Regrip(Time.time - state.ThrowAt) : 0f); RegripToss = RegripW > 0f; RegripJump = RegripW > 0f; LastTossLog = Time.time; AimLock = (Object)(object)state != (Object)null && ((state.PlainThrowAt > 0f && Time.time - state.PlainThrowAt < 0.95f) || (state.ThrowAt > 0f && Time.time - state.ThrowAt < 1.15f)); if (RegripW <= 0f && (Object)(object)state != (Object)null && state.PlainThrowAt > 0f) { RegripW = SpearFlip.PlainRegrip(Time.time - state.PlainThrowAt); RegripToss = RegripW > 0f; RegripJump = false; } if ((Object)(object)owner == (Object)null) { owner = ((Component)this).GetComponentInParent<Humanoid>(); } bool flag = (Object)(object)state != (Object)null && state.Guard && Time.time <= state.LastActive + Plugin.GuardReset.Value && SpearFlip.BlockHeld(owner); float num = (((Object)(object)state != (Object)null && ((!state.Exiting && (state.Level >= 0 || Time.time < state.LastActive + 0.15f)) || flag)) ? 1f : 0f); if (GripW != num || GripW != 0f || !(RegripW <= 0f)) { float num2 = Time.deltaTime / Mathf.Max(0.01f, (num > GripW) ? Plugin.ComboGripBlend.Value : Plugin.ComboGripOut.Value); GripW = Mathf.MoveTowards(GripW, num, num2); SpearFlip.ApplyPose(((Component)this).gameObject, this, ((Object)(object)state != (Object)null) ? state.Level : (-1)); } } } internal static class SpearFlip { private static readonly Vector3 PalmOffset = new Vector3(-0.016f, 0.0185f, 0.0002f); private const float TossStart = 0.2f; private const float TossEnd = 0.713f; private const float TossLift = 0.26f; private const float TossLandFrom = 0.4f; private const float TossPeak = 2.45f; private const float BodyClear = 0.34f; private const float SpearLength = 1.9f; private static readonly Vector3 TossShift = new Vector3(-0.06f, 0.06f, 0f); internal const float PlainTurnStart = 0.2f; internal const float PlainTurnEnd = 0.713f; internal static float JumpTossStart => 0.3f; internal static float JumpTossEnd => 0.8f; internal static bool BlockHeld(Humanoid h) { if ((Object)(object)h == (Object)null) { return false; } if ((Object)(object)h != (Object)(object)Player.m_localPlayer) { return ((Character)h).IsBlocking(); } bool flag = default(bool); int num; if (Refs.Blocking != null) { object value = Refs.Blocking.GetValue(h); if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) == 0) { return GuardCombo.BlockButtonHeld(); } return true; } internal static Quaternion RegripRot(Quaternion r1, float w) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.Inverse(r1); float num = default(float); Vector3 val2 = default(Vector3); ((Quaternion)(ref val)).ToAngleAxis(ref num, ref val2); if (num > 180f) { num = 360f - num; val2 = -val2; } return r1 * Quaternion.AngleAxis((num - 360f) * w, val2); } internal static float PlainRegrip(float t) { if (t < 0f || t > 0.833f) { return 0f; } return Mathf.Clamp01((t - 0.2f) / 0.513f); } internal static float Regrip(float t) { if (t < 0f || t > JumpTossEnd + 0.12f) { return 0f; } return Mathf.Clamp01((t - 0.2f) / 0.513f); } internal static void Flip(GameObject go, bool fang) { FlipMark flipMark = go.GetComponent<FlipMark>() ?? go.AddComponent<FlipMark>(); flipMark.Fang = fang; flipMark.Flipped = true; ApplyPose(go, flipMark, -1); } internal static void ApplyPose(GameObject go, FlipMark m, int hitLevel) { //IL_0008: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_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_072a: Unknown result type (might be due to invalid IL or missing references) //IL_072f: Unknown result type (might be due to invalid IL or missing references) //IL_0733: Unknown result type (might be due to invalid IL or missing references) //IL_0738: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Unknown result type (might be due to invalid IL or missing references) //IL_0742: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Unknown result type (might be due to invalid IL or missing references) //IL_074f: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_0198: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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_01c7: 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_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: 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_0131: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_08be: Unknown result type (might be due to invalid IL or missing references) //IL_08d4: Unknown result type (might be due to invalid IL or missing references) //IL_07ad: Unknown result type (might be due to invalid IL or missing references) //IL_07a4: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021a: 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_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_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_024c: 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_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_07b2: Unknown result type (might be due to invalid IL or missing references) //IL_07b6: Unknown result type (might be due to invalid IL or missing references) //IL_07bb: Unknown result type (might be due to invalid IL or missing references) //IL_07be: Unknown result type (might be due to invalid IL or missing references) //IL_07c3: Unknown result type (might be due to invalid IL or missing references) //IL_07c8: Unknown result type (might be due to invalid IL or missing references) //IL_07cd: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: 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_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033c: 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_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0819: Unknown result type (might be due to invalid IL or missing references) //IL_0828: Unknown result type (might be due to invalid IL or missing references) //IL_0837: Unknown result type (might be due to invalid IL or missing references) //IL_0846: Unknown result type (might be due to invalid IL or missing references) //IL_0855: Unknown result type (might be due to invalid IL or missing references) //IL_0864: Unknown result type (might be due to invalid IL or missing references) //IL_087b: Unknown result type (might be due to invalid IL or missing references) //IL_0887: Unknown result type (might be due to invalid IL or missing references) //IL_0893: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0383: 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_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0389: 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_0396: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: 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_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: 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_0452: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: 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_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_0504: Unknown result type (might be due to invalid IL or missing references) //IL_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_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_060f: Unknown result type (might be due to invalid IL or missing references) //IL_0614: Unknown result type (might be due to invalid IL or missing references) //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0623: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_0632: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_0584: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_0695: Unknown result type (might be due to invalid IL or missing references) //IL_06a4: 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_06d2: 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_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05ad: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Unknown result type (might be due to invalid IL or missing references) Transform transform = go.transform; transform.localRotation = Quaternion.identity; transform.localPosition = Vector3.zero; m.PoseActive = false; if (!m.Flipped) { return; } transform.Rotate(180f, 25f, 0f); transform.Translate(Vector3.forward * (m.Fang ? (-0.72f) : (-0.5f)) + PalmOffset, (Space)1); if (m.GripW > 0f) { float num = m.GripW * m.GripW * (3f - 2f * m.GripW); Quaternion val = Quaternion.Slerp(Quaternion.identity, Quaternion.Euler(Plugin.ComboGrip.Value), num); transform.localRotation = val * transform.localRotation; transform.localPosition = val * transform.localPosition; m.PoseActive = true; } if (m.RegripW <= 0f) { m.TossCaptured = false; m.TossHoldLogged = false; } if (m.RegripW > 0f) { if (m.RegripToss) { Transform val2 = Refs.CharacterRoot(transform); if (!m.TossCaptured) { m.TossRot = Quaternion.Inverse(val2.rotation) * transform.rotation; m.TossPos = val2.InverseTransformPoint(transform.position); m.TossCaptured = true; } float regripW = m.RegripW; UnderGrip(transform, out var rot, out var pos); Vector3 val3 = GroundForward(val2); Vector3 val4 = rot * Vector3.forward; Vector3 val5 = pos + val4 * Vector3.Dot(transform.parent.position - pos, val4); Vector3 val6 = val5 + Quaternion.FromToRotation(rot * Vector3.back, val3) * (pos - val5); Vector3 val7 = (m.RegripJump ? val6 : val2.TransformPoint(m.TossPos)); Vector3 val8 = Vector3.Lerp(val7, pos, 0.5f); float num2 = Mathf.Max(0.26f, val2.position.y + 2.45f - val8.y) * Mathf.Sin(MathF.PI * regripW); Quaternion val9 = Quaternion.FromToRotation(rot * Vector3.back, val3) * rot; Quaternion val10 = val2.rotation * m.TossRot; Vector3 val11 = GroundForward(val2); Quaternion val12 = Quaternion.FromToRotation(val10 * Vector3.back, val11) * val10; float num3 = 1f; float num4 = Mathf.Clamp01((regripW - 0.9f) / 0.1f); num3 = num3 * num3 * (3f - 2f * num3); num4 = num4 * num4 * (3f - 2f * num4); transform.rotation = Quaternion.Slerp(Quaternion.Slerp(val10, val12, num3), val9, num4); Vector3 val13 = (m.RegripJump ? TossPathJump.Sample(regripW) : TossPath.Sample(regripW)); Vector3 val14 = GroundForward(val2); Vector3 val15 = Vector3.Cross(Vector3.up, val14); transform.position = val7 + val15 * (0f - val13.x) + val14 * val13.z + Vector3.up * val13.y; float num5 = num4; Vector3 val16 = (m.RegripJump ? TossPathJump.Sample(1f) : TossPath.Sample(1f)); Vector3 val17 = val7 + val15 * (0f - val16.x) + val14 * val16.z + Vector3.up * val16.y; float num6 = Mathf.Clamp01((regripW - 0.4f) / 0.6f); num6 = num6 * num6 * (3f - 2f * num6); transform.position += (val6 - val17) * num6; if (num5 > 0f) { transform.position = Vector3.Lerp(transform.position, val6, num5); } if (transform.position.y > val2.position.y + 0.55f && transform.position.y < val2.position.y + 1.85f) { Vector3 position = transform.position; Vector3 val18 = transform.rotation * Vector3.back; Vector3 val19 = position + val18 * 1.9f; Vector2 val20 = default(Vector2); ((Vector2)(ref val20))..ctor(position.x, position.z); Vector2 val21 = new Vector2(val19.x, val19.z); Vector2 val22 = default(Vector2); ((Vector2)(ref val22))..ctor(val2.position.x, val2.position.z); Vector2 val23 = val21 - val20; float num7 = ((((Vector2)(ref val23)).sqrMagnitude > 1E-06f) ? Mathf.Clamp01(Vector2.Dot(val22 - val20, val23) / ((Vector2)(ref val23)).sqrMagnitude) : 0f); Vector2 val24 = val20 + val23 * num7 - val22; float magnitude = ((Vector2)(ref val24)).magnitude; if (magnitude < 0.34f) { Vector3 val25; if (!(magnitude > 0.0001f)) { val25 = val2.right * (0.34f - magnitude); } else { Vector3 val26 = new Vector3(val24.x, 0f, val24.y); val25 = ((Vector3)(ref val26)).normalized * (0.34f - magnitude); } Vector3 val27 = val25; transform.position += val27 * (1f - num5); } } if (Time.time - m.LastTossLog > 0.1f && regripW > 0.02f && (regripW < 0.98f || !m.TossHoldLogged)) { m.LastTossLog = Time.time; if (regripW >= 0.98f) { m.TossHoldLogged = true; } Vector3 val28 = val2.InverseTransformDirection(transform.rotation * Vector3.back); Vector3 val29 = val2.InverseTransformDirection(val9 * Vector3.back); Plugin.Log.LogDebug((object)(string.Format("[toss] {0} w={1:0.00} lift={2:0.000} height={3:0.00}m tip(body: x right, y up, z fwd)={4:0.00},{5:0.00},{6:0.00} ", m.RegripJump ? "JUMP-table" : "plain-table", regripW, num2, transform.position.y - val2.position.y, val28.x, val28.y, val28.z) + $"held-grip tip={val29.x:0.00},{val29.y:0.00},{val29.z:0.00} item={((Object)go).name}")); } } m.PoseActive = true; } if (m.AimLock) { Vector3 val30 = GroundForward(Refs.CharacterRoot(transform)); transform.rotation = Quaternion.FromToRotation(transform.rotation * Vector3.back, val30) * transform.rotation; } if ((m.AimLock || m.RegripW > 0f) && Time.time - m.LastAimLog > 0.05f) { m.LastAimLog = Time.time; Transform val31 = Refs.CharacterRoot(transform); Vector3 val32 = (((Object)(object)val31 != (Object)null) ? val31.forward : Vector3.zero); Vector3 val33 = GroundForward(val31); Vector3 val34 = transform.rotation * Vector3.back; Plugin.Log.LogDebug((object)(string.Format("[aim] aim={0} w={1:0.00} body={2} ", m.AimLock, m.RegripW, ((Object)(object)val31 != (Object)null) ? ((Object)val31).name : "null") + $"bfwd=({val32.x:0.00},{val32.y:0.00},{val32.z:0.00}) gfwd=({val33.x:0.00},{val33.y:0.00},{val33.z:0.00}) " + $"tip=({val34.x:0.00},{val34.y:0.00},{val34.z:0.00})")); } if (hitLevel >= 0) { transform.Rotate(Plugin.HitRotation[hitLevel].Value); transform.Translate(Plugin.HitOffset[hitLevel].Value); m.PoseActive = true; } } private static Vector3 GroundForward(Transform body) { //IL_0008: 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_0014: 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_0020: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[3] { Vector3.forward, Vector3.up, Vector3.right }; foreach (Vector3 val in array) { Vector3 val2 = body.rotation * val; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { return ((Vector3)(ref val2)).normalized; } } return Vector3.forward; } internal static void UnderGrip(Transform spear, out Quaternion rot, out Vector3 pos) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: 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_0150: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) rot = spear.rotation; pos = spear.position; Transform parent = spear.parent; Transform val = (((Object)(object)parent != (Object)null) ? parent.parent : null); if ((Object)(object)val == (Object)null) { return; } Transform val2 = val.Find("RightHandIndex1"); Transform val3 = val.Find("RightHandMiddle1"); Transform val4 = val.Find("RightHandRing1"); Transform val5 = val.Find("RightHandPinky1"); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null) && !((Object)(object)val5 == (Object)null)) { Vector3 val6 = Vector3.Cross(val2.position - val5.position, val3.position - val.position); if (!(((Vector3)(ref val6)).sqrMagnitude < 1E-10f)) { Vector3 val7 = ((val2.position + val3.position + val4.position + val5.position) / 4f + val.position) * 0.5f; Vector3 val8 = spear.rotation * Vector3.forward; Vector3 val9 = spear.position + val8 * Vector3.Dot(val7 - spear.position, val8); Quaternion val10 = Quaternion.AngleAxis(180f, ((Vector3)(ref val6)).normalized); rot = val10 * spear.rotation; pos = val9 + val10 * (spear.position - val9); } } } internal static GameObject RightItemOf(Component c) { Humanoid component = c.GetComponent<Humanoid>(); VisEquipment val = (((Object)(object)component != (Object)null) ? component.GetVisEquipment() : null); if (!((Object)(object)val != (Object)null) || Refs.RightItem == null) { return null; } return Refs.RightItem.Invoke(val); } } internal class JumpBack : MonoBehaviour { private float fireAt = -1f; internal void Arm(float delay) { fireAt = Time.time + delay; ((Behaviour)this).enabled = true; } private void Update() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if (!(fireAt < 0f) && !(Time.time < fireAt)) { fireAt = -1f; ((Behaviour)this).enabled = false; Character component = ((Component)this).GetComponent<Character>(); if (!((Object)(object)component == (Object)null) && !component.IsDead() && component.IsOnGround()) { float num = Mathf.Max(0.1f, 0f - Physics.gravity.y); float num2 = Mathf.Sqrt(2f * num * Mathf.Max(0f, Plugin.JumpBackHeight.Value)); float num3 = 2f * num2 / num; float num4 = ((num3 > 0.01f) ? (Plugin.JumpBackDistance.Value / num3) : 0f); Vector3 val = -((Component)component).transform.forward; val.y = 0f; ((Vector3)(ref val)).Normalize(); component.ForceJump(val * num4 + Vector3.up * num2, false); } } } } internal static class GuardCombo { internal static bool SwallowedSinceStart; internal static float ArmedGuardAt = -10f; internal static int AttackStateHash; internal static int BlockStateHash; internal static float lastProbe; internal static int CallCount; internal static float LastCallAt; private static float pendingGap; private static bool pendingContinuing; private static float guardStartedAt = -10f; private static float lastTraceAt = -10f; private static Character damaged; private static bool blockWasHeld; private static readonly int ShieldBlockingState = Animator.StringToHash("Shield blocking"); private static void Trace(string text) { if (!(Time.time - lastTraceAt < 0.25f)) { lastTraceAt = Time.time; Plugin.Log.LogDebug((object)("[guard] " + text)); } } internal static bool BlockButtonHeld() { try { if (Hud.InRadial()) { return false; } return ZInput.GetButton("Block") || ZInput.GetButton("JoyBlock"); } catch { return false; } } internal static bool Prefix(Humanoid __instance, bool secondaryAttack, out bool __state, ref bool __result) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) __state = false; if (secondaryAttack || !Plugin.DefenceCombo.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || Refs.Blocking == null) { return true; } object value = Refs.Blocking.GetValue(__instance); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } bool flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0; bool flag3 = BlockButtonHeld(); bool flag4 = flag2 || flag3; if (flag4) { ArmedGuardAt = Time.time; } if (flag4 && Refs.Zanim != null) { object? value2 = Refs.Zanim.GetValue(__instance); ZSyncAnimation val = (ZSyncAnimation)((value2 is ZSyncAnimation) ? value2 : null); if (val != null) { Animator component = ((Component)val).GetComponent<Animator>(); if ((Object)(object)component != (Object)null) { AnimatorStateInfo currentAnimatorStateInfo = component.GetCurrentAnimatorStateInfo(0); BlockStateHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash; } } } if (flag4 && Refs.Zanim != null) { object? value3 = Refs.Zanim.GetValue(__instance); ZSyncAnimation val2 = (ZSyncAnimation)((value3 is ZSyncAnimation) ? value3 : null); if (val2 != null) { ClearBlockPose(__instance, val2); } } if (!flag4) { ComboState component2 = ((Component)__instance).GetComponent<ComboState>(); if ((Object)(object)component2 == (Object)null || !component2.Guard || Time.time > component2.LastActive + 0.5f) { Trace("skip: block neither held nor recent -> game starts a NORMAL combo hit"); return true; } } SharedData val3 = __instance.GetCurrentWeapon()?.m_shared; if (val3 == null || val3.m_attack == null) { if (flag4) { Trace("skip: no weapon/attack"); } return true; } string attackAnimation = val3.m_attack.m_attackAnimation; if (attackAnimation != "spearcombo" && attackAnimation != "spearguard") { if (flag4) { Trace("skip: attack name '" + attackAnimation + "' (block held) -> game starts a NORMAL hit"); } return true; } object? obj = Refs.CurrentAttack?.GetValue(__instance); Attack val4 = (Attack)((obj is Attack) ? obj : null); ComboState component3 = ((Component)__instance).GetComponent<ComboState>(); bool flag5 = (Object)(object)component3 != (Object)null && component3.GuardHolding; bool flag6 = val4 != null && val4.m_attackAnimation == "spearguard" && !val4.IsDone() && !flag5 && Time.time - guardStartedAt < 1.5f; Trace(string.Format("block(field={0},button={1}) running='{2}' ", flag2, flag3, (val4 != null) ? val4.m_attackAnimation : "<none>") + string.Format("done={0} held={1} sinceStart={2:0.00} ", (val4 != null) ? val4.IsDone().ToString() : "-", flag5, Time.time - guardStartedAt) + "-> " + (flag6 ? "REFUSE (hit still playing)" : "allow")); if (flag6) { __state = false; __result = false; return false; } val3.m_attack.m_attackAnimation = "spearguard"; if (Refs.LastChainDamage != null) { Refs.LastChainDamage.Invoke(val3.m_attack) = 1f; } ComboState component4 = ((Component)__instance).GetComponent<ComboState>(); pendingGap = (((Object)(object)component4 != (Object)null) ? (Time.time - component4.LastActive) : 999f); pendingContinuing = (Object)(object)component4 != (Object)null && component4.Guard && pendingGap <= Plugin.GuardReset.Value; if (pendingContinuing && Refs.TimeSinceLastAttack != null) { Refs.TimeSinceLastAttack.Invoke(__instance) = 0f; } object? obj2 = Refs.Zanim?.GetValue(__instance); ZSyncAnimation val5 = (ZSyncAnimation)((obj2 is ZSyncAnimation) ? obj2 : null); if (val5 != null) { if (Refs.BlockingAnimHash != null && !Plugin.KeepBlockPose.Value) { ClearBlockPose(__instance, val5); } if (Refs.AnimatorOf != null) { Animator val6 = Refs.AnimatorOf.Invoke(val5); if ((Object)(object)val6 != (Object)null && val6.speed < 0.01f) { val6.speed = 1f; } } } guardStartedAt = Time.time; __state = true; return true; } internal static void Finalizer(Humanoid __instance, bool __state, bool __result) { if (!__state) { return; } SharedData val = __instance.GetCurrentWeapon()?.m_shared; if (val == null || val.m_attack == null) { return; } val.m_attack.m_attackAnimation = "spearcombo"; if (Refs.LastChainDamage != null) { Refs.LastChainDamage.Invoke(val.m_attack) = Plugin.LastHitDamage.Value; } if (!__result) { return; } object? obj = Refs.CurrentAttack?.GetValue(__instance); Attack val2 = (Attack)((obj is Attack) ? obj : null); if (val2 != null && val2.m_attackAnimation == "spearguard" && Refs.ChainLevel != null) { if (SwallowedSinceStart) { SwallowedSinceStart = false; return; } int num = Mathf.Clamp(Refs.ChainLevel.Invoke(val2), 0, 2); val2.m_damageMultiplier = Plugin.GuardDamage[num].Value * Plugin.BlockHitDamage.Value; Plugin.Log.LogDebug((object)($"Defence hit {num + 1} of 3: damage x{val2.m_damageMultiplier:0.##} " + $"(base {Plugin.GuardDamage[num].Value:0.##} x block-hit scale {Plugin.BlockHitDamage.Value:0.##}) (" + string.Format("{0}, {1:0.00}s since the last defence hit).", pendingContinuing ? "continuing the combo" : "fresh chain", pendingGap))); } } internal static void DamagePrefix(Character __instance) { damaged = __instance; } internal static void DamageFinalizer() { damaged = null; } internal static void IsBlockingPostfix(Humanoid __instance, ref bool __result) { if ((Object)(object)damaged != (Object)(object)__instance) { if (!__result || !((Object)(object)__instance == (Object)(object)Player.m_localPlayer)) { return; } ComboState component = ((Component)__instance).GetComponent<ComboState>(); if (component == null || !component.Guard) { return; } bool num; if (!HoldsShield(__instance)) { if (component.Level >= 0) { goto IL_0061; } num = Time.time < component.LastActive + 0.35f; } else { num = DefenceHitRunning(__instance); } if (!num) { return; } goto IL_0061; } if (__result || !(__instance is Player) || Refs.Blocking == null || Refs.CurrentAttack == null) { return; } object value = Refs.Blocking.GetValue(__instance); if (value is bool && (bool)value) { object? value2 = Refs.CurrentAttack.GetValue(__instance); Attack val = (Attack)((value2 is Attack) ? value2 : null); if (val != null && !(val.m_attackAnimation != "spearguard") && !((Character)__instance).IsStaggering() && !((Character)__instance).InDodge()) { __result = true; } } return; IL_0061: __result = false; } internal static void KeepQueuedClick(ComboState st, ZSyncAnimation zanim) { if ((Object)(object)st == (Object)null || !st.Guard || st.Level < 0 || Refs.QueuedAttack == null) { return; } Humanoid component = ((Component)zanim).GetComponent<Humanoid>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component != (Object)(object)Player.m_localPlayer)) { Player val = (Player)(object)((component is Player) ? component : null); if (!((Object)(object)val == (Object)null) && !(Refs.QueuedAttack.Invoke(val) <= 0f)) { Refs.QueuedAttack.Invoke(val) = 0.5f; } } } private static void ClearBlockPose(Humanoid h, ZSyncAnimation zanim) { if (Refs.BlockingAnimHash != null) { zanim.SetBool((int)Refs.BlockingAnimHash.GetValue(null), false); } if ((Object)(object)h != (Object)null && Refs.InternalBlocking != null) { Refs.InternalBlocking.Invoke(h) = false; } } internal static void SnapToBlockOnPress(ZSyncAnimation zanim, ComboState st, GameObject spear, FlipMark mark, int level) { bool flag = BlockButtonHeld(); bool num = flag && !blockWasHeld; blockWasHeld = flag; if (!num || !Plugin.DefenceCombo.Value) { return; } Humanoid component = ((Component)zanim).GetComponent<Humanoid>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component != (Object)(object)Player.m_localPlayer) && (level >= 0 || ((Object)(object)st != (Object)null && st.Level >= 0))) { if ((Object)(object)mark != (Object)null && (Object)(object)spear != (Object)null) { mark.Flipped = true; mark.ReflipAt = Time.time + 1.5f; SpearFlip.ApplyPose(spear, mark, -1); } if (Refs.BlockingAnimHash != null) { zanim.SetBool((int)Refs.BlockingAnimHash.GetValue(null), true); } if (Refs.InternalBlocking != null) { Refs.InternalBlocking.Invoke(component) = true; } Plugin.Log.LogDebug((object)"[block] RMB during a chain - block stance snapped in (no side swing)"); } } internal static void SuppressBlockPose(ZSyncAnimation zanim, ComboState st) { if ((Object)(object)st == (Object)null || !Plugin.DefenceCombo.Value || Refs.BlockingAnimHash == null || !st.Guard || Time.time > st.LastActive + Plugin.GuardReset.Value) { return; } Humanoid component = ((Component)zanim).GetComponent<Humanoid>(); if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer) { return; } bool flag = default(bool); int num; if (Refs.Blocking != null) { object value = Refs.Blocking.GetValue(component); if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) == 0 && !BlockButtonHeld()) { return; } if (HoldsShield(component)) { object? obj = Refs.CurrentAttack?.GetValue(component); Attack val = (Attack)((obj is Attack) ? obj : null); if (val == null || val.IsDone()) { ReturnToBlock(component, zanim, st); return; } } if (Plugin.KeepBlockPose.Value) { if (Refs.BlockingAnimHash != null) { zanim.SetBool((int)Refs.BlockingAnimHash.GetValue(null), true); } if (Refs.InternalBlocking != null) { Refs.InternalBlocking.Invoke(component) = true; } } else { ClearBlockPose(component, zanim); } } private static bool HoldsShield(Humanoid h) { if (!TriggerPatch.LeftHandEmpty((Component)(object)h)) { return !TriggerPatch.LeftHandTorch((Component)(object)h); } return false; } private static bool DefenceHitRunning(Humanoid h) { object? obj = Refs.CurrentAttack?.GetValue(h); Attack val = (Attack)((obj is Attack) ? obj : null); if (val != null && val.m_attackAnimation == "spearguard") { return !val.IsDone(); } return false; } private static void ReturnToBlock(Humanoid h, ZSyncAnimation zanim, ComboState st) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (Refs.BlockingAnimHash != null) { zanim.SetBool((int)Refs.BlockingAnimHash.GetValue(null), true); } if (st.BlockReturned || st.Level < 0 || ((Character)h).InDodge() || Refs.AnimatorOf == null) { return; } st.BlockReturned = true; Animator val = Refs.AnimatorOf.Invoke(zanim); if (!((Object)(object)val == (Object)null) && val.HasState(0, ShieldBlockingState)) { AnimatorStateInfo val2 = (val.IsInTransition(0) ? val.GetNextAnimatorStateInfo(0) : val.GetCurrentAnimatorStateInfo(0)); if (((AnimatorStateInfo)(ref val2)).shortNameHash != ShieldBlockingState) { val.CrossFadeInFixedTime(ShieldBlockingState, 0.1f, 0); } } } } internal static class WiresShim { private static bool tried; private static float lastLogAt = -10f; internal static void Ensure() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown if (tried) { return; } tried = true; try { Assembly assembly = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies) { if (assembly2.GetName().Name == "WiresCombatFlow") { assembly = assembly2; break; } } Type type = ((assembly != null) ? assembly.GetType("WiresCombatFlow.CombatFlow") : null); MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "TryCancel", (Type[])null, (Type[])null) : null); if (methodInfo == null) { Plugin.Log.LogInfo((object)"Wires Combat Flow not detected - its recovery-cancel cannot touch the defence hits."); return; } new Harmony("andythedemon.combospear.wires").Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(WiresShim), "TryCancelPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"Wires Combat Flow detected - its recovery-cancel is now skipped while a defence hit plays."); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not bind the Wires cancel immunity (" + ex.GetType().Name + "); defence hits stay cancellable by it.")); } } internal static bool TryCancelPrefix(Player player, int cancel) { if ((Object)(object)player != (Object)(object)Player.m_localPlayer || Refs.CurrentAttack == null) { return true; } object? value = Refs.CurrentAttack.GetValue(player); Attack val = (Attack)((value is Attack) ? value : null); if (val == null) { return true; } ComboState component = ((Component)player).GetComponent<ComboState>(); bool flag = ((Object)(object)component != (Object)null && component.Guard && Time.time <= component.LastActive + Plugin.GuardReset.Value) || Time.time <= GuardCombo.ArmedGuardAt + 0.5f; if (val.m_attackAnimation != "spearguard" && !flag) { return true; } if (Time.time - lastLogAt > 2f) { lastLogAt = Time.time; Plugin.Log.LogDebug((object)"Wires recovery-cancel suppressed during a defence hit (its Stop/reject/crossfade skipped)."); } return false; } } internal static class SoftThrow { internal static void Postfix(Humanoid __instance, bool secondaryAttack, bool __result) { if (!__result || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } ComboState component = ((Component)__instance).GetComponent<ComboState>(); if (!secondaryAttack) { object? obj = Refs.CurrentAttack?.GetValue(__instance); Attack val = (Attack)((obj is Attack) ? obj : null); if (val != null && val.m_attackAnimation == "spearcombo") { float value = Plugin.NormalHitDamage.Value; if (!Mathf.Approximately(value, 1f)) { val.m_damageMultiplier = value; } } } else if (!((Object)(object)component == (Object)null) && component.SoftThrowPending) { component.SoftThrowPending = false; object? obj2 = Refs.CurrentAttack?.GetValue(__instance); Attack val2 = (Attack)((obj2 is Attack) ? obj2 : null); if (val2 != null) { val2.m_damageMultiplier = Plugin.ThrowDamage.Value; Plugin.Log.LogDebug((object)$"Jump-back throw damage x{Plugin.ThrowDamage.Value:0.##} (this throw only)."); } } } } internal static class GameThrowWatch { private struct Burst { public Attack attack; public float at; } private static readonly List<Burst> bursts = new List<Burst>(16); internal static void BurstPostfix(Attack __instance) { if (__instance != null) { bursts.Add(new Burst { attack = __instance, at = Time.time }); if (bursts.Count > 16) { bursts.RemoveAt(0); } } } internal static bool FiredSince(Attack attack, float sinceAt) { for (int num = bursts.Count - 1; num >= 0; num--) { if (bursts[num].attack == attack && bursts[num].at >= sinceAt) { return true; } } return false; } } internal static class LungeCancel { private static bool bypass; internal static bool InAttackPrefix(Player __instance, ref bool __result) { if (!bypass || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } __result = false; return false; } internal static void Prefix(Humanoid __instance, bool secondaryAttack, out bool __state) { __state = false; if (!secondaryAttack) { return; } if (!Plugin.JumpBackThrow.Value) { Plugin.Log.LogDebug((object)"[jg] exit: JumpBackThrow disabled"); } else { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } object? value = Refs.CurrentAttack.GetValue(__instance); Attack val = (Attack)((value is Attack) ? value : null); if (val == null) { Plugin.Log.LogDebug((object)"[jg] exit: current attack null"); return; } if (val.m_attackAnimation != "spearcombo") { Plugin.Log.LogDebug((object)("[jg] exit: anim=" + val.m_attackAnimation + " want=spearcombo")); return; } object? value2 = Refs.Zanim.GetValue(__instance); ZSyncAnimation val2 = (ZSyncAnimation)((value2 is ZSyncAnimation) ? value2 : null); if (val2 == null) { Plugin.Log.LogDebug((object)"[jg] exit: no zanim"); } else if (ComboState.LungeHitLanded(val2)) { if (!((Character)__instance).IsOnGround()) { Plugin.Log.LogDebug((object)"[jg] exit: airborne"); return; } bypass = true; __state = true; } } } internal static void Finalizer(Humanoid __instance, bool __state, bool __result) { if (!__state) { return; } bypass = false; if (__result) { Plugin.Log.LogDebug((object)"Special during the lunge: lunge cut, jump-back throw started."); ComboState obj = ((Component)__instance).GetComponent<ComboState>() ?? ((Component)__instance).gameObject.AddComponent<ComboState>(); obj.ThrowAt = Time.time; obj.PlainThrowAt = -10f; obj.ThrowFired = false; GameObject val = SpearFlip.RightItemOf((Component)(object)__instance); FlipMark flipMark = (((Object)(object)val != (Object)null) ? val.GetComponent<FlipMark>() : null); if ((Object)(object)flipMark != (Object)null) { flipMark.Flipped = true; flipMark.ReflipAt = Time.time + 1.6f; } Plugin.Log.LogDebug((object)string.Format("[toss] jump toss armed at {0:0.00} (item={1}, flip={2})", Time.time, ((Object)(object)val != (Object)null) ? ((Object)val).name : "null", (Object)(object)flipMark != (Object)null)); } else { string text; try { ItemData currentWeapon = __instance.GetCurrentWeapon(); Attack val2 = currentWeapon?.m_shared?.m_secondaryAttack; text = (((Character)__instance).IsStaggering() ? "the character is staggering (took a hit)" : (((Character)__instance).InDodge() ? "the character is dodging" : ((!((Character)__instance).CanMove()) ? "the character cannot move" : (((Character)__instance).InMinorAction() ? "a minor action is playing" : ((currentWeapon == null) ? "nothing in hand" : ((!currentWeapon.HaveSecondaryAttack()) ? "the weapon has no secondary attack" : ((val2 != null && !string.IsNullOrEmpty(val2.m_attackAnimation)) ? ((val2.m_cantUseInDungeon && ((Character)__instance).InInterior()) ? "the throw is blocked indoors" : ((!val2.m_requiresReload || __instance.IsWeaponLoaded()) ? "vanilla refused it, no blocking state detected" : "the weapon is not loaded")) : "the secondary attack has no animation"))))))); } catch (Exception ex) { text = "state read failed (" + ex.GetType().Name + ")"; } Plugin.Log.LogDebug((object)("Special during the lunge: the throw could not start - " + text + ".")); } } } internal class ComboState : MonoBehaviour { public int Level = -1; public string Clip; public float CaptureAt; public float ExpireAt; public float LastActive = -10f; public float ThrowAt = -10f; public float PlainThrowAt = -10f; public bool ThrowFired; public Attack PendingThrow; public int PreloadedSet = -1; public bool Guard; public bool GuardHolding; public bool GuardHoldDone; public bool BlockReturned; public bool Exiting; public bool SpeedSet; public float GuardHoldFrom = -10f; public float HitAt = -1f; public float LungeUntil = -10f; public bool SoftThrowPending; internal static void Begin(ZSyncAnimation zanim, int level, bool guard = false) { ComboState comboState = ((Component)zanim).GetComponent<ComboState>() ?? ((Component)zanim).gameObject.AddComponent<ComboState>(); comboState.Level = level; comboState.Guard = guard; comboState.GuardHolding = false; comboState.GuardHoldDone = false; comboState.BlockReturned = false; comboState.Exiting = false; comboState.Clip = null; comboState.CaptureAt = Time.time + 0.05f; comboState.LastActive = Time.time; comboState.PlainThrowAt = -10f; comboState.ExpireAt = Time.time + 4f; if (guard) { comboState.HitAt = -1f; comboState.LungeUntil = -10f; } else if (level >= 2) { comboState.HitAt = Time.time + 0.667f; comboState.LungeUntil = comboState.HitAt + 1.6f; } } internal static bool InThrowWindow(ZSyncAnimation zanim) { ComboState comboState = (((Object)(object)zanim != (Object)null) ? ((Component)zanim).GetComponent<ComboState>() : null); if ((Object)(object)comboState != (Object)null && comboState.HitAt > 0f) { return Time.time <= comboState.LungeUntil; } return false; } internal static bool LungeHitLanded(ZSyncAnimation zanim) { ComboState comboState = (((Object)(object)zanim != (Object)null) ? ((Component)zanim).GetComponent<ComboState>() : null); if ((Object)(object)comboState != (Object)null) { Plugin.Log.LogDebug((object)("[jumpgate] level=" + comboState.Level + " hitAt=" + comboState.HitAt.ToString("F2") + " lungeUntil=" + comboState.LungeUntil.ToString("F2") + " now=" + Time.time.ToString("F2") + " ok=" + (comboState.Level >= 2 && comboState.HitAt > 0f && Time.time >= comboState.HitAt && Time.time <= comboState.LungeUntil))); } if ((Object)(object)comboState != (Object)null && comboState.Level >= 2 && comboState.HitAt > 0f && Time.time >= comboState.HitAt) { return Time.time <= comboState.LungeUntil; } return false; } internal static void Spend(ZSyncAnimation zanim) { ComboState comboState = (((Object)(object)zanim != (Object)null) ? ((Component)zanim).GetComponent<ComboState>() : null); if (!((Object)(object)comboState == (Object)null)) { comboState.LungeUntil = -10f; comboState.Level = -1; } } internal static void MarkSoftThrow(ZSyncAnimation zanim) { (((Component)zanim).GetComponent<ComboState>() ?? ((Component)zanim).gameObject.AddComponent<ComboState>()).SoftThrowPending = true; } internal static void Throw(ZSyncAnimation zanim) { ComboState component = ((Component)zanim).GetComponent<ComboState>(); if ((Object)(object)component != (Object)null) { component.PreloadedSet = -1; } ComboState obj = ((Component)zanim).GetComponent<ComboState>() ?? ((Component)zanim).gameObject.AddComponent<ComboState>(); obj.Level = -1; obj.LastActive = Time.time + 1f; obj.Exiting = false; obj.ThrowAt = Time.time; obj.PlainThrowAt = -10f; GameObject val = SpearFlip.RightItemOf((Component)(object)zanim); FlipMark flipMark = (((Object)(object)val != (Object)null) ? val.GetComponent<FlipMark>() : null); if ((Object)(object)flipMark != (Object)null) { flipMark.Flipped = true; flipMark.ReflipAt = Time.time + 1.6f; } else { Plugin.Log.LogWarning((object)"[toss] jump throw started but the spear item's FlipMark was not found"); } obj.ThrowFired = false; obj.PendingThrow = null; } internal static void End(ZSyncAnimation zanim) { ComboState component = ((Component)zanim).GetComponent<ComboState>(); if ((Object)(object)component != (Object)null) { component.Level = -1; } } } internal static class CustomClips { private class Slot { public AnimatorOverrideController Controller; public RuntimeAnimatorController Base; public string AppliedSignature = ""; } private static AssetBundle bundle; private static bool bundleTried; private static readonly Dictionary<string, AnimationClip> clips = new Dictionary<string, AnimationClip>(); private static readonly ConditionalWeakTable<Animator, Slot> slots = new ConditionalWeakTable<Animator, Slot>(); internal const string EmbeddedBundleName = "spearcombo.bundle"; private static Stream embeddedBundleStream; internal const string TorchSuffix = "_Torch"; internal const string VanillaBlockHold = "Sword And Shield Idle"; internal const string BlockHoldClip = "SpearBlockHold"; private static bool loggedNoHold; private static AssetBundle LoadEmbeddedBundle() { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith("spearcombo.bundle", StringComparison.OrdinalIgnoreCase)) { text = text2; break; } } if (text == null) { return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { return null; } MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); memoryStream.Position = 0L; embeddedBundleStream = memoryStream; return AssetBundle.LoadFromStream((Stream)memoryStream); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not load the embedded bundle (" + ex.GetType().Name + ": " + ex.Message + ").")); return null; } } internal static AnimationClip Clip(string name) { if (string.IsNullOrEmpty(name)) { return null; } if (clips.TryGetValue(name, out var value)) { return value; } if (!bundleTried) { bundleTried = true; string text = Path.Combine(Plugin.PluginFolder, Plugin.CustomBundle.Value); if (File.Exists(text)) { bundle = AssetBundle.LoadFromFile(text); Plugin.Log.Log((LogLevel)(Object.op_Implicit((Object)(object)bundle) ? 16 : 4), (object)(Object.op_Implicit((Object)(object)bundle) ? ("Loaded bundle " + text) : ("Bundle found but could not be read: " + text))); } else { bundle = LoadEmbeddedBundle(); Plugin.Log.Log((LogLevel)(Object.op_Implicit((Object)(object)bundle) ? 16 : 4), (object)(Object.op_Implicit((Object)(object)bundle) ? "No bundle file next to the DLL - loaded the embedded copy from this assembly (release build)." : ("Bundle not found: " + text + ", and this build has no embedded bundle."))); } } value = (Object.op_Implicit((Object)(object)bundle) ? bundle.LoadAsset<AnimationClip>(name) : null); if ((Object)(object)value == (Object)null) { Plugin.Log.LogWarning((object)("Custom clip '" + name + "' not found in the bundle.")); } else if (name != "SpearBlockHold" && !Array.Exists(value.events, (AnimationEvent e) => e.functionName == "OnAttackTrigger")) { Plugin.Log.LogWarning((object)("Custom clip '" + name + "' has no OnAttackTrigger event - it would never hit. Ignoring it.")); value = null; } else { Plugin.Log.LogInfo((object)$"Custom clip '{name}' loaded ({value.length:0.00}s)."); } clips[name] = value; return value; } internal static void Apply(Animator animator, bool on, bool freeHand = false, bool throwing = false, bool torch = false, bool guard = false) { if ((Object)(object)animator == (Object)null) { return; } List<KeyValuePair<string, AnimationClip>> pairs = new List<KeyValuePair<string, AnimationClip>>(); if (throwing) { string name = ((freeHand && !string.IsNullOrEmpty(Plugin.ThrowCustomClipFree.Value)) ? Plugin.ThrowCustomClipFree.Value : Plugin.ThrowCustomClip.Value); if (torch && (Object)(object)Clip(Plugin.ThrowCustomClip.Value + "_Torch") != (Object)null) { name = Plugin.ThrowCustomClip.Value + "_Torch"; } AnimationClip val = Clip(name); if ((Object)(object)val != (Object)null) { pairs.Add(new KeyValuePair<string, AnimationClip>(Plugin.ThrowReplacesClip.Value, val)); } } else if (on) { string value = Plugin.PlainThrowClip.Value; string name2 = ((freeHand && (Object)(object)Clip(value + "_Free") != (Object)null) ? (value + "_Free") : ((torch && (Object)(object)Clip(value + "_Torch") != (Object)null) ? (value + "_Torch") : value)); AnimationClip val2 = (string.IsNullOrEmpty(value) ? null : Clip(name2)); if ((Object)(object)val2 != (Object)null) { pairs.Add(new KeyValuePair<string, AnimationClip>(Plugin.ThrowReplacesClip.Value, val2)); } } if (on && !throwing) { for (int i = 0; i < 3; i++) { string value2 = Plugin.HitReplaceClip[i].Value; string name3 = ((freeHand && !string.IsNullOrEmpty(Plugin.HitCustomClipFree[i].Value)) ? Plugin.HitCustomClipFree[i].Value : Plugin.HitCustomClip[i].Value); if (guard) { string value3 = Plugin.GuardClip[i].Value; name3 = ((freeHand && (Object)(object)Clip(value3 + "_Free") != (Object)null) ? (value3 + "_Free") : ((torch && (Object)(object)Clip(value3 + "_Torch") != (Object)null) ? (value3 + "_Torch") : value3)); } else if (torch && (Object)(object)Clip(Plugin.HitCustomClip[i].Value + "_Torch") != (Object)null) { name3 = Plugin.HitCustomClip[i].Value + "_Torch"; } AnimationClip val3 = (string.IsNullOrEmpty(value2) ? null : Clip(name3)); if ((Object)(object)val3 != (Object)null) { pairs.Add(new KeyValuePair<string, AnimationClip>(value2, val3)); } } } if (on && !freeHand && !torch) { AnimationClip val4 = Clip("SpearBlockHold