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.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using BoplFixedMath; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; [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("Katana")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Bopl Battle instant melee katana. Kills on touch, 5s cooldown.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("Katana")] [assembly: AssemblyTitle("Katana")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [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 Katana { public static class AbilityApiClonesFix { private const string Culprit = "AbilityApi"; private static bool done; public static void Ensure() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown if (done) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(PlayerCollision), "killPlayer", (Type[])null, (Type[])null); if (methodInfo == null) { done = true; return; } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo); if (patchInfo == null || patchInfo.Prefixes == null || patchInfo.Prefixes.Count == 0) { return; } List list = new List(); foreach (Patch prefix in patchInfo.Prefixes) { MethodInfo patchMethod = prefix.PatchMethod; if (!(patchMethod == null) && !(patchMethod.DeclaringType == null) && patchMethod.DeclaringType.FullName.Contains("AbilityApi")) { list.Add(patchMethod); } } if (list.Count == 0) { done = true; return; } Harmony val = new Harmony("katana.abilityapi.clonefix"); foreach (MethodInfo item in list) { val.Unpatch((MethodBase)methodInfo, item); } done = true; } } public static class KatanaAbility { public const string AbilityName = "katana"; public const string TemplateNameFragment = "invis"; public const string IconTextureName = "KatanaIcon"; public const int CooldownSeconds = 5; public static readonly Fix BoplDiameter = (Fix)2.2f; public static readonly Fix RangeMultiplier = (Fix)2f; public const float HeldWorldSize = 2.2f; public const float HoldDistance = 1.15f; public const float HoldHeight = -0.05f; public const float HeldRotateFixDegrees = -45f; public const int SlashVisualTicks = 48; public static readonly Vector4 CircleExtents = new Vector4(0.04882813f, 0.04882813f, 0.08300781f, 0.9287109f); public static bool IsKatana(GameObject go) { if ((Object)(object)go != (Object)null) { return ((Object)go).name.ToLower().Contains("katana"); } return false; } public static bool IsKatanaIcon(Sprite sprite) { if ((Object)(object)sprite != (Object)null && (Object)(object)sprite.texture != (Object)null) { return ((Object)sprite.texture).name == "KatanaIcon"; } return false; } public static Vec2 AimOf(int playerId) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) PlayerHandler val = PlayerHandler.Get(); Player val2 = ((val == null) ? null : val.GetPlayer(playerId)); if (val2 == null) { return new Vec2(Fix.One, Fix.Zero); } Vec2 val3 = val2.AimVector(); if (Vec2.Magnitude(val3) > (Fix)0.2f) { return Vec2.Normalized(val3); } return new Vec2(Fix.One, Fix.Zero); } public static float PlayerScale(int playerId) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) PlayerHandler val = PlayerHandler.Get(); Player val2 = ((val == null) ? null : val.GetPlayer(playerId)); if (val2 != null) { return Mathf.Max(0.01f, (float)val2.Scale); } return 1f; } public static Sprite LoadIcon(Sprite template) { //IL_002c: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Texture2D val = LoadTexture("Katana.AbilityIcon.png"); if ((Object)(object)val == (Object)null) { return null; } int size = 128; float pixelsPerUnit = 100f; if ((Object)(object)template != (Object)null) { Rect rect = template.rect; if (((Rect)(ref rect)).width > 8f) { rect = template.rect; size = Mathf.RoundToInt(((Rect)(ref rect)).width); } pixelsPerUnit = template.pixelsPerUnit; } Texture2D obj = BlitCentered(val, size, 0.72f); ((Object)obj).name = "KatanaIcon"; ((Texture)obj).filterMode = (FilterMode)1; ((Texture)obj).wrapMode = (TextureWrapMode)1; obj.Apply(false, false); Sprite obj2 = Build(obj, pixelsPerUnit); ((Object)obj2).name = "katana"; return obj2; } public static Sprite LoadHeldKatana() { Texture2D val = LoadTexture("Katana.AbilityIcon.png"); if ((Object)(object)val == (Object)null) { return null; } ((Object)val).name = "KatanaHeld"; return Build(val, (float)((Texture)val).width / 2.2f); } private static Texture2D BlitCentered(Texture2D source, int size, float fill) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); Color[] pixels = (Color[])(object)new Color[size * size]; val.SetPixels(pixels); int num = Mathf.Max(1, Mathf.RoundToInt((float)size * fill)); int num2 = (size - num) / 2; int num3 = (size - num) / 2; Color[] pixels2 = source.GetPixels(); int width = ((Texture)source).width; int height = ((Texture)source).height; for (int i = 0; i < num; i++) { int num4 = Mathf.Clamp(i * height / num, 0, height - 1); for (int j = 0; j < num; j++) { int num5 = Mathf.Clamp(j * width / num, 0, width - 1); Color val2 = pixels2[num4 * width + num5]; if (!(val2.a < 0.05f)) { val.SetPixel(num2 + j, num3 + i, val2); } } } return val; } private static Sprite Build(Texture2D texture, float pixelsPerUnit) { //IL_0027: 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) ((Texture)texture).filterMode = (FilterMode)1; ((Texture)texture).wrapMode = (TextureWrapMode)1; return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), pixelsPerUnit, 0u, (SpriteMeshType)0); } private static Texture2D LoadTexture(string resourceName) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { Plugin.Log.LogError((object)("Katana: embedded resource '" + resourceName + "' not found.")); return null; } byte[] array; using (MemoryStream memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { Plugin.Log.LogError((object)("Katana: '" + resourceName + "' failed to decode as a PNG.")); return null; } val.Apply(false, false); return val; } } [HarmonyPatch(typeof(AbilityGrid), "Awake")] public static class KatanaInjectionPatch { private static bool hasInjected; public static void Prefix(AbilityGrid __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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) if (hasInjected) { return; } NamedSpriteList abilityIcons = __instance.abilityIcons; if ((Object)(object)abilityIcons == (Object)null || abilityIcons.sprites == null) { Plugin.Log.LogWarning((object)"Katana: AbilityGrid.abilityIcons was empty this Awake; not injecting yet (will retry on the next grid build)."); return; } NamedSprite val = default(NamedSprite); bool flag = false; foreach (NamedSprite sprite in abilityIcons.sprites) { if (sprite.name != null && sprite.name.ToLower().Contains("invis")) { val = sprite; flag = true; break; } } if (!flag || (Object)(object)val.associatedGameObject == (Object)null) { Plugin.Log.LogError((object)"Katana: could not find a native instant ability to clone, so the katana was not added. (Looked for an ability whose name contains 'invis'.)"); return; } GameObject val2 = Object.Instantiate(val.associatedGameObject); Object.DontDestroyOnLoad((Object)(object)val2); ((Object)val2).name = "katana"; StripTemplateEffect(val2); InstantAbility component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogError((object)"Katana: the cloned ability has no InstantAbility component."); return; } component.SetCoolDown((Fix)5L); Sprite val3 = KatanaAbility.LoadIcon(val.sprite) ?? val.sprite; abilityIcons.sprites.Add(new NamedSprite("katana", val3, val2, true)); hasInjected = true; Plugin.Log.LogInfo((object)("Katana: ability injected (cloned '" + val.name + "', " + $"cooldown {5}s).")); } private static void StripTemplateEffect(GameObject clone) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown InstantAbility component = clone.GetComponent(); if ((Object)(object)component != (Object)null) { component.funcOnEnter = new UnityEvent(); component.isInvisibilty = false; component.EffectOnEnter = null; } Invisibility component2 = clone.GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } SpriteRenderer[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (SpriteRenderer obj in componentsInChildren) { obj.sprite = null; ((Renderer)obj).enabled = false; } } } [HarmonyPatch(typeof(AbilityReadyIndicator), "SetSprite")] public static class KatanaCirclePatch { public static void Postfix(AbilityReadyIndicator __instance, Sprite sprite) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (KatanaAbility.IsKatanaIcon(sprite)) { SpriteRenderer spriteRen = __instance.GetSpriteRen(); if (!((Object)(object)spriteRen == (Object)null) && !((Object)(object)((Renderer)spriteRen).material == (Object)null)) { ((Renderer)spriteRen).material.SetVector("_CircleExtents", KatanaAbility.CircleExtents); } } } } [HarmonyPatch(typeof(InstantAbility), "EnterAbility")] public static class KatanaCastPatch { public static void Postfix(InstantAbility __instance) { if (KatanaAbility.IsKatana(((Component)__instance).gameObject)) { SpriteRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren(true); foreach (SpriteRenderer obj in componentsInChildren) { obj.sprite = null; ((Renderer)obj).enabled = false; } Slash(__instance.playerInfo.playerId); } } private static void Slash(int playerId) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) List origins = PlayerBodies.PositionsOf(playerId); if (origins.Count == 0) { Plugin.Log.LogWarning((object)$"Katana: player {playerId} cast the slash but no live body was found."); return; } Fix val = PlayerBodies.RadiusOf(playerId, KatanaAbility.BoplDiameter / (Fix)2L) * (Fix)2L * KatanaAbility.RangeMultiplier; Fix slashRadiusSqr = val * val; PlayerBodies.KillOthersWhere(playerId, playerId, (CauseOfDeath)0, delegate(Vec2 position) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < origins.Count; i++) { if (Vec2.SqrMagnitude(origins[i] - position) <= slashRadiusSqr) { return true; } } return false; }); ProjectileReflect.ReflectNear(playerId, origins, val); ProjectileReflect.BeginSwing(playerId, val); SlashVisuals.Spawn(playerId); } } [HarmonyPatch(typeof(Updater), "TickSimulation")] public static class KatanaTickPatch { public static void Postfix() { AbilityApiClonesFix.Ensure(); ProjectileReflect.Tick(); SlashVisuals.Tick(); } } [HarmonyPatch(typeof(PlayerHandler), "ResetForNextStage")] public static class KatanaResetPatch { public static void Prefix() { PlayerBodies.ForgetAll(); ProjectileReflect.Forget(); SlashVisuals.DestroyAll(); } } [HarmonyPatch(typeof(Updater), "PreLevelLoad")] public static class KatanaLevelLoadPatch { public static void Prefix() { PlayerBodies.ForgetAll(); ProjectileReflect.Forget(); SlashVisuals.DestroyAll(); } } internal static class PlayerBodies { private static readonly HashSet alreadyKilled = new HashSet(); public static void ForgetAll() { alreadyKilled.Clear(); } public static bool IsProtected(int playerId) { PlayerHandler val = PlayerHandler.Get(); Player val2 = ((val == null) ? null : val.GetPlayer(playerId)); if (val2 != null && val2.InPlatformTransform) { return true; } ControlPlatform[] array = Object.FindObjectsOfType(); foreach (ControlPlatform val3 in array) { if (!((Object)(object)val3 == (Object)null) && ((Behaviour)val3).isActiveAndEnabled) { IPlayerIdHolder component = ((Component)val3).GetComponent(); if (component != null && component.GetPlayerId() == playerId) { return true; } } } return false; } public static List PositionsOf(int playerId) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) List list = new List(); PlayerCollision[] array = Object.FindObjectsOfType(); foreach (PlayerCollision val in array) { if (!((Object)(object)val == (Object)null) && !((MonoUpdatable)val).IsDestroyed && ((Component)val).gameObject.activeInHierarchy && val.GetPlayerId() == playerId) { FixTransform component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null && !component.IsDestroyed) { list.Add(component.position); } } } return list; } public static Fix RadiusOf(int playerId, Fix fallback) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) PlayerCollision[] array = Object.FindObjectsOfType(); foreach (PlayerCollision val in array) { if (!((Object)(object)val == (Object)null) && !((MonoUpdatable)val).IsDestroyed && ((Component)val).gameObject.activeInHierarchy && val.GetPlayerId() == playerId) { PlayerPhysics component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null && component.radius > Fix.Zero) { return component.radius; } } } return fallback; } public static int KillOthersWhere(int killerId, int reportedKillerId, CauseOfDeath causeOfDeath, Func isInside) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) int num = 0; PlayerCollision[] array = Object.FindObjectsOfType(); foreach (PlayerCollision val in array) { if ((Object)(object)val == (Object)null || ((MonoUpdatable)val).IsDestroyed || !((Component)val).gameObject.activeInHierarchy) { continue; } int playerId = val.GetPlayerId(); if (playerId != killerId && !IsProtected(playerId)) { FixTransform component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null) && !component.IsDestroyed && isInside(component.position) && !alreadyKilled.Contains(((Object)val).GetInstanceID()) && val.killPlayer(reportedKillerId, true, false, causeOfDeath)) { alreadyKilled.Add(((Object)val).GetInstanceID()); num++; } } } return num; } } [BepInPlugin("com.solsticio.boplbattle.katana", "Katana", "1.0.1")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.solsticio.boplbattle.katana"; public const string PluginName = "Katana"; public const string PluginVersion = "1.0.1"; internal static ManualLogSource Log; private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Katana: loading..."); new Harmony("com.solsticio.boplbattle.katana").PatchAll(); Log.LogInfo((object)$"Katana: loaded (instant melee, cooldown {5}s)."); } } internal static class ProjectileReflect { private sealed class Window { public int playerId; public Fix radius; public int ticksLeft; } private static readonly HashSet reflected = new HashSet(); private static readonly List windows = new List(); public static void Forget() { reflected.Clear(); windows.Clear(); } public static void BeginSwing(int playerId, Fix radius) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) windows.Add(new Window { playerId = playerId, radius = radius, ticksLeft = 48 }); } public static void Tick() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) for (int num = windows.Count - 1; num >= 0; num--) { Window window = windows[num]; List origins = PlayerBodies.PositionsOf(window.playerId); ReflectNear(window.playerId, origins, window.radius); window.ticksLeft--; if (window.ticksLeft <= 0) { windows.RemoveAt(num); } } } public static int ReflectNear(int playerId, List origins, Fix radius) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0129: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_010c: Unknown result type (might be due to invalid IL or missing references) if (origins == null || origins.Count == 0) { return 0; } Fix val = radius * radius; int num = 0; BoplBody[] array = Object.FindObjectsOfType(); foreach (BoplBody val2 in array) { if ((Object)(object)val2 == (Object)null || ((MonoUpdatable)val2).IsDestroyed || (Object)(object)((Component)val2).GetComponent() != (Object)null) { continue; } Vec2 position = val2.position; bool flag = false; for (int j = 0; j < origins.Count; j++) { if (Vec2.SqrMagnitude(origins[j] - position) <= val) { flag = true; break; } } if (!flag) { continue; } int instanceID = ((Object)val2).GetInstanceID(); if (reflected.Contains(instanceID)) { continue; } Vec2 val3 = val2.StartVelocity; try { if (AccessTools.Property(typeof(BoplBody), "velocity")?.GetValue(val2, null) is Vec2 val4 && Vec2.SqrMagnitude(val4) > Fix.Zero) { val3 = val4; } } catch (Exception) { } if (Vec2.SqrMagnitude(val3) <= Fix.Zero) { continue; } Vec2 val5 = (val2.StartVelocity = -val3); try { PropertyInfo propertyInfo = AccessTools.Property(typeof(BoplBody), "velocity"); if (propertyInfo != null && propertyInfo.CanWrite) { propertyInfo.SetValue(val2, val5, null); } } catch (Exception) { } FieldInfo fieldInfo = AccessTools.Field(typeof(BoplBody), "ownerId"); if (fieldInfo != null) { fieldInfo.SetValue(val2, playerId); } reflected.Add(instanceID); num++; } return num; } } internal static class SlashVisuals { private sealed class SlashFx { public GameObject go; public int playerId; public int ticksLeft; } private static readonly List live = new List(); private static Sprite heldSprite; public static void Spawn(int playerId) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)heldSprite == (Object)null) { heldSprite = KatanaAbility.LoadHeldKatana(); } if (!((Object)(object)heldSprite == (Object)null)) { GameObject val = new GameObject("KatanaHeld"); SpriteRenderer obj = val.AddComponent(); obj.sprite = heldSprite; obj.color = Color.white; ((Renderer)obj).sortingOrder = 80; live.Add(new SlashFx { go = val, playerId = playerId, ticksLeft = 48 }); Place(val, playerId); } } public static void Tick() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) for (int num = live.Count - 1; num >= 0; num--) { SlashFx slashFx = live[num]; slashFx.ticksLeft--; if ((Object)(object)slashFx.go != (Object)null && slashFx.ticksLeft > 0) { Place(slashFx.go, slashFx.playerId); SpriteRenderer component = slashFx.go.GetComponent(); if ((Object)(object)component != (Object)null && slashFx.ticksLeft <= 4) { Color color = component.color; color.a = (float)slashFx.ticksLeft / 4f; component.color = color; } } if (slashFx.ticksLeft <= 0) { if ((Object)(object)slashFx.go != (Object)null) { Object.Destroy((Object)(object)slashFx.go); } live.RemoveAt(num); } } } public static void DestroyAll() { foreach (SlashFx item in live) { if ((Object)(object)item.go != (Object)null) { Object.Destroy((Object)(object)item.go); } } live.Clear(); } private static void Place(GameObject go, int playerId) { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) //IL_0095: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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) SpriteRenderer val = FindPlayerSprite(playerId); Vec2 val2 = KatanaAbility.AimOf(playerId); float num = KatanaAbility.PlayerScale(playerId); int sortingLayerID = 0; int sortingOrder = 80; Vector3 position = default(Vector3); if ((Object)(object)val != (Object)null) { position = ((Component)val).transform.position; sortingLayerID = ((Renderer)val).sortingLayerID; sortingOrder = ((Renderer)val).sortingOrder + 2; } else { List list = PlayerBodies.PositionsOf(playerId); if (list.Count == 0) { return; } ((Vector3)(ref position))..ctor((float)list[0].x, (float)list[0].y, 0f); } Vector3 val3 = new Vector3((float)val2.x, (float)val2.y, 0f) * (1.15f * num); val3.y += -0.05f * num; go.transform.position = position + val3; float num2 = Mathf.Atan2((float)val2.y, (float)val2.x) * 57.29578f + -45f; go.transform.rotation = Quaternion.Euler(0f, 0f, num2); go.transform.localScale = new Vector3(num, num, 1f); SpriteRenderer component = go.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).sortingLayerID = sortingLayerID; ((Renderer)component).sortingOrder = sortingOrder; } } private static SpriteRenderer FindPlayerSprite(int playerId) { SlimeController[] array = Object.FindObjectsOfType(); foreach (SlimeController val in array) { if (val.GetPlayerId() == playerId) { SpriteRenderer playerSprite = val.GetPlayerSprite(); if ((Object)(object)playerSprite != (Object)null && ((Component)playerSprite).gameObject.activeInHierarchy) { return playerSprite; } } } return null; } } internal static class UniqueKatanaSlots { public static void Ensure(SlimeController slime) { if ((Object)(object)slime == (Object)null || slime.abilities == null) { return; } HashSet hashSet = new HashSet(); for (int i = 0; i < slime.abilities.Count; i++) { AbilityMonoBehaviour val = slime.abilities[i]; if ((Object)(object)val == (Object)null || !KatanaAbility.IsKatana(((Component)val).gameObject)) { continue; } int instanceID = ((Object)val).GetInstanceID(); if (!hashSet.Add(instanceID)) { InstantAbility val2 = Clone(val); if ((Object)(object)val2 != (Object)null) { slime.abilities[i] = (AbilityMonoBehaviour)(object)val2; } } } } public static AbilityMonoBehaviour CloneIfKatana(AbilityMonoBehaviour ability) { if ((Object)(object)ability == (Object)null || !KatanaAbility.IsKatana(((Component)ability).gameObject)) { return ability; } return (AbilityMonoBehaviour)(((object)Clone(ability)) ?? ((object)ability)); } private static InstantAbility Clone(AbilityMonoBehaviour ability) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate(((Component)ability).gameObject); Object.DontDestroyOnLoad((Object)(object)obj); ((Object)obj).name = "katana"; InstantAbility component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { component.SetCoolDown((Fix)5L); } return component; } } [HarmonyPatch(typeof(SlimeController), "AddAbility")] public static class KatanaAddAbilityPatch { public static void Prefix(ref AbilityMonoBehaviour ability) { ability = UniqueKatanaSlots.CloneIfKatana(ability); } } [HarmonyPatch(typeof(SlimeController), "AddAdditionalAbility")] public static class KatanaAddAdditionalAbilityPatch { public static void Prefix(ref AbilityMonoBehaviour ability) { ability = UniqueKatanaSlots.CloneIfKatana(ability); } } [HarmonyPatch(typeof(SlimeController), "OldUpdate")] public static class KatanaUniqueSlotsPatch { public static void Postfix(SlimeController __instance) { UniqueKatanaSlots.Ensure(__instance); } } }