using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using HarmonyLib; using InControl; using Microsoft.CodeAnalysis; using Silksong.AssetHelper.ManagedAssets; using Silksong.UnityHelper.Util; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } } [BepInPlugin("lagerthon.Slapsong", "Slapsong", "2.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Slapsong : BaseUnityPlugin { internal static ManualLogSource Log; public static Slapsong Instance; private ConfigEntry slapKey; public static ConfigEntry dmg; public static ConfigEntry recoil; public static ConfigEntry recoilSpeed; public static ConfigEntry recoilDuration; private static ConfigEntry slapVol; private static ConfigEntry runToSlap; public static ManagedAsset nuuGO; public static GameObject nuu; private static bool nuuBool; public static bool isSlapHit; private AudioClip cachedSlapAudio; private AudioSource slapAudioSource; public static BoxCollider2D slapBoxFront; public static BoxCollider2D slapBoxBack; private HeroController hero; private bool isHeroSlapping = false; private static bool attackCancelRequested; private bool queuedSlap = false; public static bool slapHasHitEnemy; private bool stickSlapArmed = true; private tk2dSpriteAnimationClip cloakLessSlap; private bool cloakLessSlapLoaded = false; public const string AnimationName = "CloaklessSlap"; public static Sprite[] Frames { get; private set; } public static tk2dSpriteAnimationClip Clip { get; private set; } private void Awake() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; slapKey = ((BaseUnityPlugin)this).Config.Bind("Input", "SlapKey", (KeyCode)108, "Key to slap."); dmg = ((BaseUnityPlugin)this).Config.Bind("Slap", "Damage dealt to enemies", 9999, new ConfigDescription("Damage dealt to enemies", (AcceptableValueBase)(object)new AcceptableValueRange(1, 9999), Array.Empty())); recoil = ((BaseUnityPlugin)this).Config.Bind("Slap", "Enemy recoil strength", 2f, new ConfigDescription("Enemy recoil strength upon slap", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f), Array.Empty())); recoilSpeed = ((BaseUnityPlugin)this).Config.Bind("Slap", "Enemy recoil speed", 30f, new ConfigDescription("Enemy recoil speed upon slap", (AcceptableValueBase)(object)new AcceptableValueRange(15f, 30f), Array.Empty())); recoilDuration = ((BaseUnityPlugin)this).Config.Bind("Slap", "Enemy recoil duration", 0.15f, new ConfigDescription("Enemy recoil duration upon slap", (AcceptableValueBase)(object)new AcceptableValueRange(0.15f, 0.5f), Array.Empty())); slapVol = ((BaseUnityPlugin)this).Config.Bind("Slap", "Slap Volume", 1f, new ConfigDescription("Volume of the slap", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 1f), Array.Empty())); runToSlap = ((BaseUnityPlugin)this).Config.Bind("Slap", "Run to slap time (secs)", 0.2f, new ConfigDescription("Time that Hornet takes in stopping if slap is triggered while running", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 0.3f), Array.Empty())); nuuGO = ManagedAsset.FromSceneAsset("halfway_01", "_NPCs/Hunter Fan Control/Nuu"); GameObject val = new GameObject("SlapsongAudio"); Object.DontDestroyOnLoad((Object)(object)val); slapAudioSource = val.AddComponent(); slapAudioSource.playOnAwake = false; SceneManager.sceneLoaded += OnSceneLoaded; LoadCloakLessSlap(((BaseUnityPlugin)this).Info.Location); new Harmony("lagerthon.Slapsong").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Slapsong loaded."); } private void Update() { //IL_00e3: 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) if ((Object)(object)hero == (Object)null) { return; } if (isHeroSlapping) { HeroActions inputActions = ManagerSingleton.Instance.inputActions; bool flag = ((OneAxisInputControl)inputActions.Attack).WasPressed || ((OneAxisInputControl)inputActions.Dash).WasPressed || ((OneAxisInputControl)inputActions.Cast).WasPressed || ((OneAxisInputControl)inputActions.QuickCast).WasPressed || ((OneAxisInputControl)inputActions.Taunt).WasPressed || ((OneAxisInputControl)inputActions.Jump).WasPressed || ((OneAxisInputControl)inputActions.Left).WasPressed || ((OneAxisInputControl)inputActions.Right).WasPressed; bool keyDown = Input.GetKeyDown(slapKey.Value); if (flag) { attackCancelRequested = true; } if (keyDown) { queuedSlap = true; attackCancelRequested = true; } } if (Input.GetKeyDown(slapKey.Value) && !isHeroSlapping && !hero.controlReqlinquished) { ((MonoBehaviour)this).StartCoroutine(Slap(hero)); } float rightStickX = GetRightStickX(); if (hero.cState.facingRight ? (rightStickX > 0.5f) : (rightStickX < -0.5f)) { if (stickSlapArmed && !hero.controlReqlinquished) { stickSlapArmed = false; if (isHeroSlapping) { queuedSlap = true; attackCancelRequested = true; } else { ((MonoBehaviour)this).StartCoroutine(Slap(hero)); } } } else if (Mathf.Abs(rightStickX) < 0.25f) { stickSlapArmed = true; } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) hero = HeroController.instance; if ((Object)(object)hero == (Object)null) { return; } if (!cloakLessSlapLoaded) { tk2dSpriteAnimator component = ((Component)hero).GetComponent(); if (!component.Library.clips.Any((tk2dSpriteAnimationClip c) => c.name == "CloaklessSlap")) { component.Library.clips = component.Library.clips.Append(Clip).ToArray(); cloakLessSlap = component.GetClipByName("CloaklessSlap"); } cloakLessSlapLoaded = true; } SlapHitBox(hero); if ((Object)(object)hero != (Object)null && !nuuBool) { ((MonoBehaviour)this).StartCoroutine(Nuu()); } if (!PlayerData.instance.CaravanLechSpaAcceptState) { return; } GameObject val = GameObject.Find("Caravan Lech"); if (!((Object)(object)val == (Object)null)) { Transform val2 = val.transform.Find("Caravan Lech Wounded"); if ((Object)(object)val2 != (Object)null) { GameObject val3 = Object.Instantiate(((Component)val2).gameObject, val.transform.position, val.transform.rotation); ((Object)val3).name = "Caravan Lech Wounded Clone"; val3.layer = LayerMask.NameToLayer("Enemies"); CircleCollider2D val4 = val3.AddComponent(); val4.radius = 1f; ((Collider2D)val4).offset = new Vector2(0f, 0.5f); val3.transform.SetParent((Transform)null); val.SetActive(false); } } } private float GetRightStickX() { InputDevice val = ManagerSingleton.Instance?.gameController; if (val == null) { return 0f; } return ((OneAxisInputControl)val.RightStickX).Value; } public static bool IsCloakLess() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return PlayerData.instance.CurrentCrestID == ((object)(CrestType)7/*cast due to .constrained prefix*/).ToString(); } private IEnumerator Nuu() { nuuBool = true; ((ManagedAssetBase)(object)nuuGO).Load(); yield return (object)new WaitUntil((Func)(() => ((ManagedAssetBase)(object)nuuGO).IsLoaded)); nuu = ManagedAssetExtensions.InstantiateAsset(nuuGO); Object.DontDestroyOnLoad((Object)(object)nuu); nuu.SetActive(false); CacheSlapAudio(); } private void CacheSlapAudio() { if ((Object)(object)cachedSlapAudio != (Object)null) { return; } AudioClip[] array = Resources.FindObjectsOfTypeAll(); foreach (AudioClip val in array) { if (((val != null) ? ((Object)val).name : null) == "hornet_slap_B_2") { cachedSlapAudio = val; break; } } } private IEnumerator Slap(HeroController hero) { if ((int)hero.hero_state != 1 && (int)hero.hero_state != 2) { yield break; } if (queuedSlap) { yield return (object)new WaitForSeconds(0.1f); queuedSlap = false; } isHeroSlapping = true; attackCancelRequested = false; slapHasHitEnemy = false; CancelSlapOnDamage.heroDamaged = false; HeroAnimationController heroAnim = ((Component)hero).GetComponent(); Rigidbody2D rb = ((Component)hero).GetComponent(); if ((Object)(object)rb != (Object)null && (int)hero.hero_state == 2) { Vector2 startVelocity = rb.velocity; float stopTime = runToSlap.Value; float t = 0f; while (t < stopTime) { if (CancelSlapOnDamage.heroDamaged || attackCancelRequested) { EndSlap(); yield break; } t += Time.deltaTime; float progress = Mathf.Clamp01(t / stopTime); rb.velocity = Vector2.Lerp(startVelocity, Vector2.zero, progress); yield return null; } rb.velocity = Vector2.zero; } hero.IgnoreInput(); hero.StopAnimationControl(); ((Behaviour)slapBoxFront).enabled = false; ((Behaviour)slapBoxBack).enabled = false; if (IsCloakLess()) { heroAnim.PlayClipForced(cloakLessSlap.name); } else { heroAnim.PlayClipForced("Idle Slap"); } tk2dSpriteAnimationClip animClip = heroAnim.animator.CurrentClip; float totalLength = heroAnim.GetClipDuration(animClip.name); float slapBoxStart = totalLength * 0.25f; float slapBoxMid = totalLength * 0.4f; float slapBoxEnd = totalLength * 0.85f; float elapsed = 0f; while (heroAnim.animator.IsPlaying(animClip) && elapsed < totalLength) { if (CancelSlapOnDamage.heroDamaged || attackCancelRequested) { EndSlap(); yield break; } elapsed += Time.deltaTime; ((Behaviour)slapBoxFront).enabled = elapsed >= slapBoxStart && elapsed < slapBoxMid; ((Behaviour)slapBoxBack).enabled = elapsed >= slapBoxMid && elapsed < slapBoxEnd; yield return null; } EndSlap(); } private void EndSlap() { ((Behaviour)slapBoxFront).enabled = false; ((Behaviour)slapBoxBack).enabled = false; hero.AcceptInput(); hero.StartAnimationControl(); if (queuedSlap) { attackCancelRequested = false; ((MonoBehaviour)this).StartCoroutine(Slap(hero)); } isHeroSlapping = false; attackCancelRequested = false; } public void PlaySlapSound() { slapAudioSource.PlayOneShot(cachedSlapAudio, slapVol.Value); } private void SlapHitBox(HeroController hero) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_00b3: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)slapBoxFront != (Object)null) || !((Object)(object)slapBoxBack != (Object)null)) { GameObject val = new GameObject("SlapHitbox"); val.transform.SetParent(((Component)hero).transform, false); val.transform.localPosition = Vector3.zero; Rigidbody2D val2 = val.AddComponent(); val2.bodyType = (RigidbodyType2D)1; GameObject val3 = new GameObject("Slap Hit Box"); val3.transform.SetParent(((Component)hero).transform, false); slapBoxFront = val3.AddComponent(); ((Collider2D)slapBoxFront).isTrigger = true; ((Behaviour)slapBoxFront).enabled = false; slapBoxFront.size = new Vector2(1.25f, 0.5f); ((Collider2D)slapBoxFront).offset = new Vector2(-0.675f, 0f); slapBoxBack = val3.AddComponent(); ((Collider2D)slapBoxBack).isTrigger = true; ((Behaviour)slapBoxBack).enabled = false; slapBoxBack.size = new Vector2(1.25f, 0.5f); ((Collider2D)slapBoxBack).offset = new Vector2(0.575f, 0f); val3.AddComponent(); } } public static void LoadCloakLessSlap(string modPath) { string directoryName = Path.GetDirectoryName(modPath); string path = Path.Combine(directoryName, "CloakLessSlap"); Frames = (from f in Directory.GetFiles(path, "*.png") orderby int.Parse(Path.GetFileNameWithoutExtension(f)) select SpriteUtil.LoadSpriteFromFile(f, 64f, (Vector2?)null, false)).ToArray(); Clip = Tk2dUtil.CreateTk2dAnimationClip("CloaklessSlap", 15, (IEnumerable)Frames, (WrapMode)2, 0, 64f); } } public class SlapDamageHandler : MonoBehaviour { public bool isFront; private string slapEvent; private float dir; private static FieldInfo recoilDurationField; private static void SetEnemyRecoilDuration(Recoil recoil, float duration) { if (recoilDurationField == null) { recoilDurationField = typeof(Recoil).GetField("recoilDuration", BindingFlags.Instance | BindingFlags.NonPublic); } if (recoilDurationField != null) { recoilDurationField.SetValue(recoil, duration); } } private void OnTriggerEnter2D(Collider2D other) { //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020d: 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_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)HeroController.instance != (Object)null && HeroController.instance.cState.facingRight; if (((Object)((Component)((Component)other).transform.root).gameObject).name == "Caravan Lech Wounded Clone") { GameObject gameObject = ((Component)((Component)other).transform.root).gameObject; PlayMakerFSM[] componentsInChildren = gameObject.GetComponentsInChildren(true); PlayMakerFSM val = ((IEnumerable)componentsInChildren).FirstOrDefault((Func)((PlayMakerFSM f) => f.FsmName == "Wounded Behaviour")); if ((Object)(object)val != (Object)null) { isFront = ((Behaviour)Slapsong.slapBoxFront).enabled; if (flag) { slapEvent = (isFront ? "HIT_RIGHT" : "HIT_LEFT"); } else { slapEvent = (isFront ? "HIT_LEFT" : "HIT_RIGHT"); } val.SendEvent(slapEvent); Slapsong.Instance.PlaySlapSound(); Slapsong.slapHasHitEnemy = true; } } else { if (((Component)other).gameObject.layer != LayerMask.NameToLayer("Enemies")) { return; } HealthManager component = ((Component)other).GetComponent(); if (!((Object)(object)component == (Object)null)) { Recoil component2 = ((Component)other).GetComponent(); if ((Object)(object)component2 != (Object)null) { SetEnemyRecoilDuration(component2, Slapsong.recoilDuration.Value); } component2.SetRecoilSpeed(Slapsong.recoilSpeed.Value); isFront = ((Behaviour)Slapsong.slapBoxFront).enabled; if (flag) { dir = (isFront ? 0f : 180f); } else { dir = (isFront ? 180f : 0f); } HitInstance val2 = new HitInstance { Source = ((Component)this).gameObject, DamageDealt = Slapsong.dmg.Value, Multiplier = 1f, AttackType = (AttackTypes)1, HitEffectsType = (EffectsTypes)1, Direction = dir, IgnoreInvulnerable = false, MagnitudeMultiplier = Slapsong.recoil.Value + (float)Slapsong.dmg.Value / 9999f }; Slapsong.isSlapHit = true; component.Hit(val2); Slapsong.isSlapHit = false; Slapsong.Instance.PlaySlapSound(); Slapsong.slapHasHitEnemy = true; } } } } [HarmonyPatch(typeof(HeroController), "HeroDamaged")] internal class CancelSlapOnDamage { public static bool heroDamaged; private static void Prefix() { heroDamaged = true; } }