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 ArcaneDecor WaterGardens KoiFish v1.0.0
plugins/ArcaneDecorWaterGardensKoiFish/WaterGardensKoi.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using RunicLilyPads; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("KoiSmoke")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WaterGardensKoi")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ArcaneDecor:WaterGardens:KoiFish")] [assembly: AssemblyTitle("ArcaneDecor:WaterGardens:KoiFish")] [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 WaterGardensKoi { internal static class KoiAssets { internal sealed class Data { internal Mesh Mesh; internal Material Material; } internal static readonly string[] Names = new string[5] { "ogon", "sanke", "kohaku", "orange", "gold" }; private static readonly Data[] Cache = new Data[5]; internal static Vector3 Pivot(int index) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Vector3(0f, 0f, 0.35f - (float)index * 0.16f); } private static Stream Open(string name) { return typeof(Plugin).Assembly.GetManifestResourceStream("Koi." + name); } internal static void Preload() { Load(3); Load(4); Load(2); } internal static Data Load(int index) { //IL_00af: 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_00d2: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: 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_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Expected O, but got Unknown //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Expected O, but got Unknown //IL_0301: Unknown result type (might be due to invalid IL or missing references) if (Cache[index] != null) { return Cache[index]; } string text = Names[index]; Data data = new Data(); using (Stream input = Open(text + ".meshbin")) { using BinaryReader binaryReader = new BinaryReader(input); if (binaryReader.ReadInt32() != 1464290609) { throw new InvalidDataException(text); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); Vector3[] array = (Vector3[])(object)new Vector3[num]; Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector2[] array3 = (Vector2[])(object)new Vector2[num]; int[] array4 = new int[num2]; BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[num]; for (int i = 0; i < num; i++) { array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array2[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array3[i] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); float num3 = (float)KoiMath.BoneCoordinate(array[i].z); int num4 = Mathf.FloorToInt(num3); int boneIndex = Mathf.Min(num4 + 1, 5); float num5 = num3 - (float)num4; int num6 = i; BoneWeight val = default(BoneWeight); ((BoneWeight)(ref val)).boneIndex0 = num4; ((BoneWeight)(ref val)).boneIndex1 = boneIndex; ((BoneWeight)(ref val)).weight0 = 1f - num5; ((BoneWeight)(ref val)).weight1 = num5; array5[num6] = val; } for (int j = 0; j < num2; j++) { array4[j] = binaryReader.ReadInt32(); } Matrix4x4[] array6 = (Matrix4x4[])(object)new Matrix4x4[6]; for (int k = 0; k < 6; k++) { int num7 = k; Matrix4x4 val2 = Matrix4x4.TRS(Pivot(k), Quaternion.identity, Vector3.one); array6[num7] = ((Matrix4x4)(ref val2)).inverse; } data.Mesh = new Mesh { name = "Koi " + text, indexFormat = (IndexFormat)1, vertices = array, normals = array2, uv = array3, triangles = array4, boneWeights = array5, bindposes = array6 }; data.Mesh.RecalculateBounds(); data.Mesh.RecalculateTangents(); } GameObject prefab = PrefabManager.Instance.GetPrefab("Fish1"); Renderer val3 = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponentInChildren<Renderer>(true) : null); if (!Object.op_Implicit((Object)(object)val3)) { throw new InvalidOperationException("Native Fish1 material unavailable."); } data.Material = new Material(val3.sharedMaterial); using (Stream stream = Open(text + ".jpg")) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val4 = new Texture2D(2, 2, (TextureFormat)3, true); if (!ImageConversion.LoadImage(val4, memoryStream.ToArray(), true)) { throw new InvalidDataException("Koi texture " + text); } data.Material.mainTexture = (Texture)(object)val4; data.Material.SetColor("_Color", Color.white); } Cache[index] = data; return data; } internal static Transform[] Build(Transform parent, int variety) { //IL_0025: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) Data data = Load(variety); Transform[] array = (Transform[])(object)new Transform[6]; for (int i = 0; i < 6; i++) { array[i] = new GameObject("body_" + i).transform; array[i].SetParent(parent, false); array[i].localPosition = Pivot(i); } SkinnedMeshRenderer obj = ((Component)parent).gameObject.AddComponent<SkinnedMeshRenderer>(); obj.sharedMesh = data.Mesh; ((Renderer)obj).sharedMaterial = data.Material; obj.bones = array; obj.rootBone = parent; obj.quality = (SkinQuality)2; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).localBounds = new Bounds(Vector3.zero, new Vector3(1.2f, 0.8f, 1.3f)); obj.updateWhenOffscreen = false; return array; } } internal static class KoiMath { internal static double Aspect(int shape) { if (shape != 1) { return 1.0; } return 0.65; } internal static double Radius(int shape, double angle) { switch (shape) { case 2: angle = Math.Atan2(Math.Sin(angle), Math.Cos(angle)); return 1.0 - 0.4 * Math.Exp((0.0 - angle) * angle / 0.32); case 3: return 0.9 + 0.07 * Math.Sin(3.0 * angle) + 0.03 * Math.Cos(5.0 * angle); default: return 1.0; } } internal static double Distance(int shape, double x, double z, double width) { x /= width * 0.5; z /= width * 0.5 * Aspect(shape); return Math.Sqrt(x * x + z * z) / Radius(shape, Math.Atan2(z, x)); } internal static void Orbit(int shape, double width, double time, int index, double seed, out double x, out double z) { double num = time * (0.12 + (double)index * 0.009) * (double)((index % 2 == 0) ? 1 : (-1)) + (double)index * 1.8 + seed; double num2 = width * 0.5 * Radius(shape, num) * (0.51 + 0.08 * Math.Sin(time * 0.09 + (double)index)); x = Math.Cos(num) * num2; z = Math.Sin(num) * num2 * Aspect(shape); } internal static double Blend(double elapsed, double seconds) { double num = Math.Max(0.0, Math.Min(1.0, elapsed / seconds)); return num * num * (3.0 - 2.0 * num); } internal static double BoneCoordinate(double z) { return Math.Max(0.0, Math.Min(5.0, (0.35 - z) / 0.16)); } } internal sealed class KoiMenuBridge : MonoBehaviour { private static TMP_FontAsset fallbackFont; private static readonly FieldInfo FontField = AccessTools.Field(typeof(PondMenu), "font"); private static readonly FieldInfo Panel = AccessTools.Field(typeof(PondMenu), "panel"); private static readonly FieldInfo Canvas = AccessTools.Field(typeof(PondMenu), "canvas"); internal static KoiMenuBridge Active; internal KoiSchool School; internal KoiSettings Draft; private PondMenu expanded; private TMP_Text buttonLabel; internal static void EnsureFont(PondMenu menu) { object? value = FontField.GetValue(menu); TMP_FontAsset val = (TMP_FontAsset)((value is TMP_FontAsset) ? value : null); if (val != null && Object.op_Implicit((Object)(object)val)) { return; } if (!Object.op_Implicit((Object)(object)fallbackFont)) { Font val2 = null; Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val3 in array) { if (((Object)val3).name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0) { val2 = val3; break; } } if (!Object.op_Implicit((Object)(object)val2)) { val2 = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); } fallbackFont = TMP_FontAsset.CreateFontAsset(val2); if (!Object.op_Implicit((Object)(object)fallbackFont)) { fallbackFont = TMP_FontAsset.CreateFontAsset(Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf")); } if (!Object.op_Implicit((Object)(object)fallbackFont)) { throw new InvalidOperationException("No usable menu font available."); } ((Object)fallbackFont).name = "WaterGardens Koi menu fallback"; } FontField.SetValue(menu, fallbackFont); } internal static void Attach(PondMenu menu, GardenPiece pond) { //IL_0024: 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_005e: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00d4: 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) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_0153: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) KoiSchool component = ((Component)pond).GetComponent<KoiSchool>(); if (Object.op_Implicit((Object)(object)component) && pond.Shape >= 0) { KoiMenuBridge koiMenuBridge = ((GameObject)Canvas.GetValue(menu)).AddComponent<KoiMenuBridge>(); koiMenuBridge.School = component; koiMenuBridge.Draft = component.Options.Copy(); Active = koiMenuBridge; RectTransform val = (RectTransform)Panel.GetValue(menu); GameObject val2 = new GameObject("Fish menu toggle", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent((Transform)(object)val, false); Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(0f, 1f); val3.pivot = val4; Vector2 anchorMin = (val3.anchorMax = val4); val3.anchorMin = anchorMin; val3.anchoredPosition = new Vector2(420f, -18f); val3.sizeDelta = new Vector2(138f, 38f); ((Graphic)val2.GetComponent<Image>()).color = new Color(0.22f, 0.27f, 0.28f, 1f); Button component2 = val2.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)val2.GetComponent<Image>(); ((UnityEvent)component2.onClick).AddListener(new UnityAction(koiMenuBridge.Toggle)); GameObject val6 = new GameObject("Fish", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); RectTransform val7 = (RectTransform)val6.transform; ((Transform)val7).SetParent((Transform)(object)val3, false); val7.anchorMin = Vector2.zero; val7.anchorMax = Vector2.one; anchorMin = (val7.offsetMax = Vector2.zero); val7.offsetMin = anchorMin; koiMenuBridge.buttonLabel = val6.GetComponent<TMP_Text>(); TMP_Text componentInChildren = ((Component)val).GetComponentInChildren<TMP_Text>(); koiMenuBridge.buttonLabel.font = componentInChildren.font; koiMenuBridge.buttonLabel.fontSize = 20f; koiMenuBridge.buttonLabel.alignment = (TextAlignmentOptions)514; koiMenuBridge.buttonLabel.text = "Fish >"; componentInChildren.rectTransform.sizeDelta = new Vector2(392f, 38f); } } internal void Toggle() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002f: 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_017a: Unknown result type (might be due to invalid IL or missing references) if (expanded != null) { Collapse(); return; } expanded = new PondMenu(412f); ((RectTransform)Panel.GetValue(expanded)).anchoredPosition = new Vector2(616f, -16f); expanded.Heading("FISH", 18f, 30, 40f); float num = 78f; expanded.Range("Orange Koi", 0f, 10f, (float)Draft.Orange, (Action<float>)delegate(float v) { Draft.Orange = Mathf.RoundToInt(v); }, (Func<string>)(() => Draft.Orange.ToString()), ref num); expanded.Range("Golden Koi", 0f, 10f, (float)Draft.Golden, (Action<float>)delegate(float v) { Draft.Golden = Mathf.RoundToInt(v); }, (Func<string>)(() => Draft.Golden.ToString()), ref num); expanded.Range("Kohaku (white and orange)", 0f, 10f, (float)Draft.Kohaku, (Action<float>)delegate(float v) { Draft.Kohaku = Mathf.RoundToInt(v); }, (Func<string>)(() => Draft.Kohaku.ToString()), ref num); expanded.Range("Fish size", 1f, 3f, Draft.Scale, (Action<float>)delegate(float v) { Draft.Scale = Mathf.Round(v * 10f) / 10f; }, (Func<string>)(() => Draft.Scale.ToString("0.0") + "x"), ref num); Slider[] componentsInChildren = ((Component)(RectTransform)Panel.GetValue(expanded)).GetComponentsInChildren<Slider>(); foreach (Slider val in componentsInChildren) { if (val.maxValue == 10f) { val.wholeNumbers = true; } } expanded.Heading("Use the pond's Save button to apply fish settings.", 310f, 18, 42f); expanded.Action("Collapse fish menu", 362f, (Action)Collapse); buttonLabel.text = "Fish <"; } private void Collapse() { PondMenu obj = expanded; if (obj != null) { obj.Dispose(); } expanded = null; if (Object.op_Implicit((Object)(object)buttonLabel)) { buttonLabel.text = "Fish >"; } } private void OnDisable() { Collapse(); if ((Object)(object)Active == (Object)(object)this) { Active = null; } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class FishMenuFontPatch { private static void Postfix(PondMenu __instance) { KoiMenuBridge.EnsureFont(__instance); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class FishMenuPatch { private static void Postfix(PondMenu __instance, GardenPiece target) { KoiMenuBridge.Attach(__instance, target); } } [HarmonyPatch(typeof(GardenPiece), "Save")] internal static class FishSavePatch { private static void Postfix(GardenPiece __instance, bool __result) { KoiMenuBridge active = KoiMenuBridge.Active; if (__result && Object.op_Implicit((Object)(object)active) && Object.op_Implicit((Object)(object)active.School) && (Object)(object)active.School.Pond == (Object)(object)__instance) { active.School.QueueOptions(active.Draft); } } } public sealed class KoiSchool : MonoBehaviour { internal static readonly List<KoiSchool> Schools = new List<KoiSchool>(); internal readonly List<PondFood> Food = new List<PondFood>(); private static readonly FieldInfo SettingsField = typeof(GardenPiece).GetField("Settings", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly float[] Amplitudes = new float[6] { 0f, 1f, 3f, 7f, 14f, 23f }; private static readonly Func<Vector3, float> Surface = (Func<Vector3, float>)Delegate.CreateDelegate(typeof(Func<Vector3, float>), typeof(GardenPiece).Assembly.GetType("RunicLilyPads.PondNetwork").GetMethod("WaterLevel", BindingFlags.Static | BindingFlags.NonPublic)); internal GardenPiece Pond; internal float Width = 6f; internal float Depth = 1.2f; internal float Water; internal KoiSettings Options = new KoiSettings(); private ZNetView view; internal Transform[] fish; private Transform[][] bones; private Vector3[] returnFrom; private float next; private double seed; private double returnStart = -10.0; private bool near; private string lastOptions = ""; private KoiSettings pending; private float pendingUntil; private PondFood previousFood; private bool previousFed; private KoiSplash splash; internal int Count => Options.Total; internal static double Clock { get { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return Time.timeAsDouble; } return (double)ZNet.instance.GetTime().Ticks / 10000000.0; } } internal bool Live { get { if (Object.op_Implicit((Object)(object)Pond) && Object.op_Implicit((Object)(object)view)) { return view.IsValid(); } return false; } } private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Pond = ((Component)this).GetComponent<GardenPiece>(); view = ((Component)this).GetComponent<ZNetView>(); seed = (double)((Component)this).transform.position.x * 0.163 + (double)((Component)this).transform.position.z * 0.087; Schools.Add(this); } private void OnDestroy() { Schools.Remove(this); foreach (PondFood item in Food) { if (Object.op_Implicit((Object)(object)item)) { item.School = null; } } } internal void QueueOptions(KoiSettings settings) { if (settings.Valid) { pending = settings.Copy(); pendingUntil = Time.time + 5f; } } internal bool Inside(Vector3 point, float margin = 1f) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) return KoiMath.Distance(Pond.Shape, Local(point).x, Local(point).z, Width) < (double)margin; } private Vector3 Local(Vector3 point) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0035: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Inverse(Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f)) * (point - ((Component)this).transform.position); } internal static KoiSchool At(Vector3 point) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) KoiSchool koiSchool = null; foreach (KoiSchool school in Schools) { if (Object.op_Implicit((Object)(object)school) && school.Live && school.Inside(point) && point.y <= school.Water + 2f && point.y >= school.Water - school.Depth - 0.5f && (!Object.op_Implicit((Object)(object)koiSchool) || school.Water > koiSchool.Water)) { koiSchool = school; } } return koiSchool; } internal void ReadSettings() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0039: 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) GardenSettings val = (GardenSettings)SettingsField.GetValue(Pond); Width = val.Width; Depth = val.Depth; float num = Surface(((Component)this).transform.position); Water = (float.IsNegativeInfinity(num) ? (((Component)this).transform.position.y - 0.15f) : num); string text = view.GetZDO().GetString("koi_settings_v1", ""); if (text != lastOptions && KoiSettings.TryDecode(text, out var value)) { Options = value; lastOptions = text; Rebuild(); } } internal Vector3 KeepInside(Vector3 point, int index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00e6: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_0104: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Local(point); float num = (float)KoiMath.Distance(Pond.Shape, val.x, val.z, Width); float num2 = Mathf.Clamp(0.95f - Length(index) * 0.55f / (Width * 0.5f * (float)KoiMath.Aspect(Pond.Shape) * ((Pond.Shape == 2) ? 0.6f : ((Pond.Shape == 3) ? 0.8f : 1f))), 0.15f, 0.9f); if (num > num2) { val.x *= num2 / num; val.z *= num2 / num; Vector3 result = ((Component)this).transform.position + Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f) * val; result.y = point.y; return result; } return point; } internal Vector3 Orbit(int index, double time) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) KoiMotion.Wander(Pond.Shape, Width, time, index, seed, out var x, out var z); Vector3 val = KeepInside(((Component)this).transform.position + Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f) * new Vector3((float)x, 0f, (float)z), index); float num = Surface(val); if (float.IsNegativeInfinity(num)) { num = Water; } float num2 = Mathf.Min(Depth * 0.55f, 0.65f); float num3 = Mathf.Min(0.025f * Options.Scale, Depth * 0.15f); val.y = num - Mathf.Lerp(num2, num3, (float)KoiMotion.SurfaceBlend(time, index, seed)); return val; } internal PondFood Target() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) PondFood pondFood = null; foreach (PondFood item in Food) { if (Object.op_Implicit((Object)(object)item) && item.StartTicks > 0 && (!Object.op_Implicit((Object)(object)pondFood) || item.StartTicks < pondFood.StartTicks || (item.StartTicks == pondFood.StartTicks && ((Component)item).transform.position.x < ((Component)pondFood).transform.position.x))) { pondFood = item; } } return pondFood; } internal float Length(int index) { return (0.44f + (float)(index % 3) * 0.025f) * Options.Scale; } private Vector3 Destination(int index, PondFood food) { //IL_0046: 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_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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) float num = (float)index * MathF.PI * 2f / (float)Mathf.Max(1, Count); float num2 = Mathf.Min(0.25f * Options.Scale, Width * 0.12f); Vector3 point = ((Component)food).transform.position + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * num2; point.y = Water - 0.04f; return KeepInside(point, index); } internal double GatherDuration(PondFood food) { //IL_0036: 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) if (!Object.op_Implicit((Object)(object)food)) { return 0.0; } double time = (double)food.StartTicks / 10000000.0; double num = 1.5; for (int i = 0; i < Count; i++) { num = Math.Max(num, (double)Vector3.Distance(Orbit(i, time), Destination(i, food)) / (0.65 * (double)Options.Scale)); } return num; } internal double FeedingElapsed(PondFood food, double now) { return now - (double)food.StartTicks / 10000000.0 - food.GatherSeconds; } internal bool Feeding(PondFood food, double now) { if (Object.op_Implicit((Object)(object)food) && Count > 0 && FeedingElapsed(food, now) >= 0.0) { return FeedingElapsed(food, now) < 3.0; } return false; } internal Vector3 Position(int index, double time, PondFood food = null) { //IL_008b: 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_0094: 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) //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_001b: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_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_006d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)food)) { food = Target(); } if (!Object.op_Implicit((Object)(object)food)) { Vector3 val = Orbit(index, time); if (returnFrom != null && index < returnFrom.Length && time - returnStart < 1.5) { return Vector3.Lerp(returnFrom[index], val, (float)KoiMath.Blend(time - returnStart, 1.5)); } return val; } double num = (double)food.StartTicks / 10000000.0; Vector3 val2 = Destination(index, food); Vector3 point = Vector3.Lerp(Orbit(index, num), val2, (float)KoiMath.Blend(time - num, food.GatherSeconds)); double num2 = FeedingElapsed(food, time); if (num2 >= 0.0 && num2 < 3.0) { point.y = Water + (-0.04f + 0.012f * (float)Math.Sin(num2 * 3.0 + (double)index * 1.7)) * Options.Scale; } return KeepInside(point, index); } internal bool ReadyToEat(PondFood food, double now) { if (Object.op_Implicit((Object)(object)food) && (Object)(object)Target() == (Object)(object)food && Count > 0) { return FeedingElapsed(food, now) >= 3.0; } return false; } private void Rebuild() { if (fish != null) { Transform[] array = fish; foreach (Transform val in array) { if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } fish = null; bones = null; returnFrom = null; previousFood = null; previousFed = false; if (near && Count > 0) { Build(); } } private void Build() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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) fish = (Transform[])(object)new Transform[Count]; bones = new Transform[Count][]; returnFrom = (Vector3[])(object)new Vector3[Count]; for (int i = 0; i < Count; i++) { fish[i] = new GameObject("pond_koi_" + KoiAssets.Names[Options.Variety(i)]).transform; fish[i].SetParent(((Component)this).transform, false); fish[i].localScale = Vector3.one * Length(i); bones[i] = KoiAssets.Build(fish[i], Options.Variety(i)); } if (!Object.op_Implicit((Object)(object)splash)) { splash = ((Component)this).gameObject.AddComponent<KoiSplash>(); } } private void Update() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_0290: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: 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_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: 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_039d: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039f: 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_03b5: 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_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) if (!Live) { return; } if (pending != null) { if (Time.time > pendingUntil) { pending = null; } else if (view.IsOwner()) { view.GetZDO().Set("koi_settings_v1", pending.Encode()); pending = null; next = 0f; } } if (Time.time >= next) { next = Time.time + 0.5f; ReadSettings(); int num; if ((int)SystemInfo.graphicsDeviceType != 4 && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { Vector3 val = ((Component)Player.m_localPlayer).transform.position - ((Component)this).transform.position; num = ((((Vector3)(ref val)).sqrMagnitude < 3600f) ? 1 : 0); } else { num = 0; } bool flag = (byte)num != 0; near = flag; if (flag && fish == null && Count > 0) { Build(); } if (fish != null) { Transform[] array = fish; foreach (Transform val2 in array) { if (((Component)val2).gameObject.activeSelf != flag) { ((Component)val2).gameObject.SetActive(flag); } } } } if (!near || fish == null) { if (Object.op_Implicit((Object)(object)splash)) { splash.Stop(); } return; } double clock = Clock; PondFood pondFood = Target(); bool flag2 = Feeding(pondFood, clock); if (previousFed && !flag2) { for (int j = 0; j < fish.Length; j++) { returnFrom[j] = fish[j].position; } returnStart = clock; } if ((Object)(object)pondFood != (Object)(object)previousFood && Object.op_Implicit((Object)(object)previousFood)) { for (int k = 0; k < fish.Length; k++) { returnFrom[k] = fish[k].position; } returnStart = clock; } previousFood = pondFood; previousFed = flag2; if (Object.op_Implicit((Object)(object)splash)) { if (flag2) { splash.Show(((Component)pondFood).transform.position, Water, Options.Scale, Count); } else { splash.Stop(); } } for (int l = 0; l < Count; l++) { Vector3 val3 = KoiMotion.Adjust(Position(l, clock, pondFood), this, l); Vector3 val4 = KoiMotion.Direction(Position(l, clock + 0.08, pondFood) - val3, this, l, val3); if (Object.op_Implicit((Object)(object)pondFood) && ((Vector3)(ref val4)).sqrMagnitude < 1E-05f) { val4 = ((Component)pondFood).transform.position - val3; val4.y = 0f; } if (flag2) { val4.y = 0f; float num2 = (float)Math.Sin(clock * 3.0 + (double)l * 1.7) * 8f; fish[l].rotation = KoiMotion.Turn(Quaternion.LookRotation((((Vector3)(ref val4)).sqrMagnitude > 1E-05f) ? val4 : Vector3.forward, Vector3.up) * Quaternion.Euler(num2, 0f, 0f), this, l); } else if (((Vector3)(ref val4)).sqrMagnitude > 1E-06f) { fish[l].rotation = KoiMotion.Turn(Quaternion.LookRotation(val4, Vector3.up), this, l); } fish[l].position = val3; for (int m = 0; m < 6; m++) { bones[l][m].localRotation = Quaternion.Euler(0f, (float)Math.Sin(clock * (double)(flag2 ? 8 : 7) - (double)l * 0.8 - (double)m * 0.7) * Amplitudes[m] * (flag2 ? 0.8f : 1f), 0f); } } } } public sealed class PondFood : MonoBehaviour { internal KoiSchool School; internal long StartTicks; internal double GatherSeconds = 2.0; private ZNetView view; private ItemDrop item; private Rigidbody body; private float next; private bool eating; private long measuredTicks; private int measuredCount; private float measuredScale; private void Awake() { view = ((Component)this).GetComponent<ZNetView>(); item = ((Component)this).GetComponent<ItemDrop>(); body = ((Component)this).GetComponent<Rigidbody>(); } private void OnDestroy() { if (Object.op_Implicit((Object)(object)School)) { School.Food.Remove(this); } } private void Update() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_01ed: 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_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: 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_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0265: 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) if (Time.time < next || !Object.op_Implicit((Object)(object)view) || !view.IsValid()) { return; } next = Time.time + 0.15f; KoiSchool koiSchool = KoiSchool.At(((Component)this).transform.position); if ((Object)(object)koiSchool != (Object)(object)School) { if (Object.op_Implicit((Object)(object)School)) { School.Food.Remove(this); } School = koiSchool; if (Object.op_Implicit((Object)(object)School)) { School.Food.Add(this); } measuredTicks = 0L; } if (!Object.op_Implicit((Object)(object)School) || School.Count == 0 || ((Component)this).transform.position.y > School.Water + 0.15f) { if (Object.op_Implicit((Object)(object)body)) { body.useGravity = true; } if (view.IsOwner() && view.GetZDO().GetLong("koi_food_time", 0L) != 0L) { view.GetZDO().Set("koi_food_time", 0L); } StartTicks = 0L; measuredTicks = 0L; return; } ZDO zDO = view.GetZDO(); StartTicks = zDO.GetLong("koi_food_time", 0L); if (view.IsOwner()) { if (StartTicks == 0L || zDO.GetInt("koi_food_version", 0) < 2) { StartTicks = ZNet.instance.GetTime().Ticks; zDO.Set("koi_food_time", StartTicks); zDO.Set("koi_food_version", 2); } Vector3 val = ((Component)this).transform.position; val.y = School.Water + 0.01f; if (!School.Inside(val, 0.7f)) { Vector3 val2 = ((Component)School).transform.position - val; val2.y = 0f; val += ((Vector3)(ref val2)).normalized * 0.05f; } if (Object.op_Implicit((Object)(object)body)) { body.useGravity = false; body.linearVelocity = Vector3.zero; body.angularVelocity = Vector3.zero; body.position = val; } else { ((Component)this).transform.position = val; } } if (view.IsOwner() && (StartTicks != measuredTicks || measuredCount != School.Count || measuredScale != School.Options.Scale)) { measuredTicks = StartTicks; measuredCount = School.Count; measuredScale = School.Options.Scale; GatherSeconds = School.GatherDuration(this); zDO.Set("koi_gather_seconds", (float)GatherSeconds); } else { GatherSeconds = zDO.GetFloat("koi_gather_seconds", 2f); } if (view.IsOwner() && !eating && item.CanEat() && School.ReadyToEat(this, KoiSchool.Clock)) { eating = true; bool flag = item.m_itemData.m_stack > 1; if (item.RemoveOne() && flag) { StartTicks = ZNet.instance.GetTime().Ticks; zDO.Set("koi_food_time", StartTicks); } eating = false; } } } internal sealed class KoiSettings { internal int Orange = 1; internal int Golden = 1; internal int Kohaku = 1; internal float Scale = 1f; internal int Total => Orange + Golden + Kohaku; internal bool Valid { get { if (Orange >= 0 && Orange <= 10 && Golden >= 0 && Golden <= 10 && Kohaku >= 0 && Kohaku <= 10 && !float.IsNaN(Scale) && !float.IsInfinity(Scale) && Scale >= 1f) { return Scale <= 3f; } return false; } } internal KoiSettings Copy() { return (KoiSettings)MemberwiseClone(); } internal int Variety(int index) { if (index >= Orange) { if (index >= Orange + Golden) { return 2; } return 4; } return 3; } internal string Encode() { return string.Join("|", Orange, Golden, Kohaku, Scale.ToString("R", CultureInfo.InvariantCulture)); } internal static bool TryDecode(string raw, out KoiSettings value) { value = new KoiSettings(); if (string.IsNullOrEmpty(raw)) { return true; } if (raw.Length > 80) { return false; } string[] array = raw.Split('|'); if (array.Length == 4 && int.TryParse(array[0], out value.Orange) && int.TryParse(array[1], out value.Golden) && int.TryParse(array[2], out value.Kohaku) && float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out value.Scale)) { return value.Valid; } return false; } } public sealed class KoiSplash : MonoBehaviour { private const int PoolSize = 3; private GameObject[] pool; private ParticleSystem[][] particles; private int slot; private float pulse; private void Awake() { //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = PrefabManager.Instance.GetPrefab("Fish1"); Fish val = ((prefab != null) ? prefab.GetComponent<Fish>() : null); GameObject val2 = null; if (Object.op_Implicit((Object)(object)val)) { EffectData[] effectPrefabs = val.m_jumpEffects.m_effectPrefabs; foreach (EffectData val3 in effectPrefabs) { if (Object.op_Implicit((Object)(object)val3.m_prefab) && Object.op_Implicit((Object)(object)val3.m_prefab.GetComponentInChildren<ParticleSystem>(true))) { val2 = val3.m_prefab; break; } } } if (!Object.op_Implicit((Object)(object)val2)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Native fish splash unavailable; feeding bob animation remains active."); } return; } pool = (GameObject[])(object)new GameObject[3]; particles = new ParticleSystem[3][]; for (int j = 0; j < 3; j++) { pool[j] = Object.Instantiate<GameObject>(val2, ((Component)this).transform); ((Object)pool[j]).name = "koi_feeding_splash_" + j; MonoBehaviour[] componentsInChildren = pool[j].GetComponentsInChildren<MonoBehaviour>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } AudioSource[] componentsInChildren2 = pool[j].GetComponentsInChildren<AudioSource>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.Destroy((Object)(object)componentsInChildren2[i]); } particles[j] = pool[j].GetComponentsInChildren<ParticleSystem>(true); ParticleSystem[] array = particles[j]; foreach (ParticleSystem obj in array) { obj.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = obj.main; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).maxParticles = Mathf.Min(((MainModule)(ref main)).maxParticles, 160); } } } internal void Show(Vector3 point, float water, float scale, int count) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (pool != null && !(Time.time < pulse)) { pulse = Time.time + Mathf.Lerp(0.35f, 0.16f, Mathf.Clamp01((float)count / 30f)); float num = (float)slot * 2.4f + Time.time; point.y = water + 0.01f; pool[slot].transform.position = point + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 0.18f * scale; pool[slot].transform.localScale = Vector3.one * 0.5f * scale; ParticleSystem[] array = particles[slot]; for (int i = 0; i < array.Length; i++) { array[i].Play(true); } slot = (slot + 1) % 3; } } internal void Stop() { if (particles == null) { return; } ParticleSystem[][] array = particles; foreach (ParticleSystem[] array2 in array) { foreach (ParticleSystem val in array2) { if (Object.op_Implicit((Object)(object)val) && val.IsAlive(true)) { val.Stop(true, (ParticleSystemStopBehavior)0); } } } } private void OnDisable() { Stop(); } } [BepInPlugin("chazman.WaterGardensKoi", "ArcaneDecor:WaterGardens:KoiFish", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "chazman.WaterGardensKoi"; internal const string FoodName = "WaterGardensKoiPellets"; internal static Material PelletMaterial; internal static ManualLogSource Log; private Harmony harmony; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("chazman.WaterGardensKoi"); harmony.PatchAll(); PrefabManager.OnVanillaPrefabsAvailable += Register; } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= Register; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private void Register() { PrefabManager.OnVanillaPrefabsAvailable -= Register; try { RegisterFood(); KoiAssets.Preload(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Pond fish controls and native-toss Koi Food ready."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Koi registration failed: " + ex)); } } private void RegisterFood() { //IL_005e: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00fe: 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_0135: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown GameObject prefab = PrefabManager.Instance.GetPrefab("Raspberry"); if (!Object.op_Implicit((Object)(object)prefab)) { throw new InvalidOperationException("Native Raspberry unavailable."); } GameObject val = PrefabManager.Instance.CreateClonedPrefab("WaterGardensKoiPellets", prefab); ItemDrop component = val.GetComponent<ItemDrop>(); SharedData shared = component.m_itemData.m_shared; shared.m_name = "Koi Food"; shared.m_description = "Round koi pellets. Put in a toolbar slot and use to toss one pile. Place a supply pile with the Water Garden hammer menu, then pick it up."; shared.m_itemType = (ItemType)1; shared.m_weight = 0.05f; shared.m_maxStackSize = 50; shared.m_food = (shared.m_foodStamina = (shared.m_foodEitr = 0f)); shared.m_damages = default(DamageTypes); shared.m_useDurability = false; shared.m_attack = new Attack(); shared.m_secondaryAttack = new Attack(); PelletMaterial = new Material(prefab.GetComponentInChildren<Renderer>(true).sharedMaterial); PelletMaterial.mainTexture = (Texture)(object)Texture2D.whiteTexture; PelletMaterial.SetColor("_Color", new Color(0.38f, 0.24f, 0.1f)); ReplaceVisuals(val); component.m_autoPickup = false; shared.m_icons = (Sprite[])(object)new Sprite[1] { PelletIcon() }; val.AddComponent<PondFood>(); ItemConfig val2 = new ItemConfig { Name = shared.m_name, Description = shared.m_description, Amount = 10, CraftingStation = null }; val2.AddRequirement("Raspberry", 1, 0); val2.AddRequirement("Mushroom", 1, 0); if (!ItemManager.Instance.AddItem(new CustomItem(val, false, val2))) { throw new InvalidOperationException("Koi Food registration rejected."); } RegisterPile(val); } private void RegisterPile(GameObject food) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0095: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_0170: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab("piece_watergardens_koi_food", "Pickable_Mushroom"); GameObject val2 = ReplaceVisuals(val); Pickable component = val.GetComponent<Pickable>(); component.m_itemPrefab = food; component.m_amount = 10; component.m_dontScale = true; component.m_respawnTimeMinutes = 0f; component.m_hideWhenPicked = val2; component.m_overrideName = "Koi Food"; component.m_spawnOffset = 0.2f; component.m_useInteractAnimation = true; component.m_extraDrops = new DropTable(); component.m_harvestable = false; component.m_aggravateRange = 0f; Piece obj = val.GetComponent<Piece>() ?? val.AddComponent<Piece>(); obj.m_usage = (UsageTagFlags)0; obj.m_groundOnly = false; obj.m_groundPiece = false; obj.m_noInWater = false; obj.m_canBeRemoved = true; obj.m_icon = food.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0]; WearNTear obj2 = val.GetComponent<WearNTear>() ?? val.AddComponent<WearNTear>(); obj2.m_supports = false; obj2.m_health = 100f; obj2.m_burnable = false; obj2.m_new = (obj2.m_worn = (obj2.m_broken = val2)); obj2.m_autoCreateFragments = false; obj2.m_fragmentRoots = Array.Empty<GameObject>(); obj2.m_noSupportWear = (obj2.m_noRoofWear = false); PieceConfig val3 = new PieceConfig { Name = "Koi Food", Description = "A small supply pile of round koi pellets. Pick it up to receive 10 Koi Food, then use a toolbar slot to toss one pile.", PieceTable = "Hammer", Category = "Water Garden", Enabled = true }; val3.AddRequirement("Raspberry", 1, true); val3.AddRequirement("Mushroom", 1, true); if (!PieceManager.Instance.AddPiece(new CustomPiece(val, false, val3))) { throw new InvalidOperationException("Hammer Koi Food registration rejected."); } } private static Sprite PelletIcon() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_011d: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { bool flag = false; Vector2[] array2 = (Vector2[])(object)new Vector2[3] { new Vector2(23f, 23f), new Vector2(42f, 28f), new Vector2(29f, 42f) }; foreach (Vector2 val2 in array2) { Vector2 val3 = new Vector2((float)j, (float)i) - val2; if (((Vector2)(ref val3)).sqrMagnitude < 95f) { flag = true; } } array[i * 64 + j] = (Color)(flag ? new Color(0.65f, 0.43f, 0.18f, 1f) : Color.clear); } } val.SetPixels(array); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private static GameObject ReplaceVisuals(GameObject root) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_008b: 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_00e4: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } ParticleSystem[] componentsInChildren2 = root.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } GameObject val = new GameObject("koi_pellets"); val.transform.SetParent(root.transform, false); for (int j = 0; j < 9; j++) { GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "round_pellet"; obj.transform.SetParent(val.transform, false); obj.transform.localScale = Vector3.one * 0.052f; obj.transform.localPosition = new Vector3(Mathf.Sin((float)j * 2.4f) * 0.075f, 0.027f + ((j > 5) ? 0.035f : 0f), Mathf.Cos((float)j * 2.4f) * 0.075f); Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>()); obj.GetComponent<Renderer>().sharedMaterial = PelletMaterial; } return val; } } [HarmonyPatch(typeof(GardenPiece), "Start")] internal static class AttachKoi { private static void Postfix(GardenPiece __instance) { if (__instance.Shape >= 0 && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent("RiverGardenSection")) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<KoiSchool>())) { ((Component)__instance).gameObject.AddComponent<KoiSchool>(); } } } [HarmonyPatch(typeof(Humanoid), "UseItem")] internal static class TossKoiFood { private static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item, bool fromInventoryGui) { object obj; if (item == null) { obj = null; } else { GameObject dropPrefab = item.m_dropPrefab; obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); } if ((string?)obj != "WaterGardensKoiPellets" || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || fromInventoryGui) { return true; } inventory = inventory ?? __instance.GetInventory(); if (inventory == __instance.GetInventory() && inventory.ContainsItem(item) && item.m_stack > 0) { __instance.DropItem(inventory, item, 1); } return false; } } internal static class KoiMotion { internal static Quaternion Turn(Quaternion desired, KoiSchool school, int index) { //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_0023: Unknown result type (might be due to invalid IL or missing references) return Quaternion.RotateTowards(school.fish[index].rotation, desired, 120f * Mathf.Min(Time.deltaTime, 0.05f)); } internal static Vector3 Direction(Vector3 original, KoiSchool school, int index, Vector3 next) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_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_0024: 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) Vector3 result = next - school.fish[index].position; if (!(((Vector3)(ref result)).sqrMagnitude > 1E-08f)) { return original; } return result; } internal static Vector3 Adjust(Vector3 desired, KoiSchool school, int index) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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) //IL_01bc: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) Transform[] fish = school.fish; if (fish == null || index >= fish.Length || !Object.op_Implicit((Object)(object)fish[index])) { return desired; } Vector3 position = fish[index].position; Vector3 val = Vector3.zero; List<Player> allPlayers = Player.GetAllPlayers(); for (int i = 0; i < allPlayers.Count; i++) { Player val2 = allPlayers[i]; if (!Object.op_Implicit((Object)(object)val2) || ((Character)val2).IsDead()) { continue; } Vector3 position2 = ((Component)val2).transform.position; if (position2.y > school.Water + 0.12f || position2.y < school.Water - school.Depth - 1.8f || !school.Inside(position2)) { continue; } Vector3 val3 = position - position2; val3.y = 0f; float magnitude = ((Vector3)(ref val3)).magnitude; if (!(magnitude >= 1.6f)) { if (magnitude < 0.025f) { float num = (float)index * 2.39996f; ((Vector3)(ref val3))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num)); } else { val3 /= magnitude; } float num2 = 1f - magnitude / 1.6f; val += val3 * (1.6f * num2 * num2); } } desired = school.KeepInside(desired + Vector3.ClampMagnitude(val, 1.6f), index); desired = Vector3.Lerp(position, desired, 1f - Mathf.Exp(-3f * Mathf.Min(Time.deltaTime, 0.05f))); return Vector3.MoveTowards(position, desired, (0.8f + 0.35f * school.Options.Scale) * Mathf.Min(Time.deltaTime, 0.05f)); } internal static double Random(double seed, int index, long step, int channel) { long num = (long)(seed * 100003.0) ^ ((index + 1) * -7046029254386353131L) ^ (step * -4658895280553007687L) ^ ((channel + 1) * -7723592293110705685L); long num2 = (num ^ (num >>> 30)) * -4658895280553007687L; long num3 = (num2 ^ (num2 >>> 27)) * -7723592293110705685L; return (double)((ulong)(num3 ^ (num3 >>> 31)) >> 11) * 1.1102230246251565E-16; } internal static void Point(double seed, int index, long step, out double x, out double z) { double num = Random(seed, index, step, 0) * Math.PI * 2.0; double num2 = Math.Sqrt(Random(seed, index, step, 1)) * 0.86; x = Math.Cos(num) * num2; z = Math.Sin(num) * num2; } internal static void Wander(int shape, double width, double time, int index, double seed, out double x, out double z) { double num = 5.0 + Random(seed, index, 0L, 2) * 5.0; double num2 = time / num + Random(seed, index, 0L, 3) * 100.0; long num3 = (long)Math.Floor(num2); num2 -= (double)num3; double num4 = 1.0 - num2; double num5 = num4 * num4 * num4 / 6.0; double num6 = (3.0 * num2 * num2 * num2 - 6.0 * num2 * num2 + 4.0) / 6.0; double num7 = (-3.0 * num2 * num2 * num2 + 3.0 * num2 * num2 + 3.0 * num2 + 1.0) / 6.0; double num8 = num2 * num2 * num2 / 6.0; Point(seed, index, num3 - 1, out var x2, out var z2); x = x2 * num5; z = z2 * num5; Point(seed, index, num3, out x2, out z2); x += x2 * num6; z += z2 * num6; Point(seed, index, num3 + 1, out x2, out z2); x += x2 * num7; z += z2 * num7; Point(seed, index, num3 + 2, out x2, out z2); x += x2 * num8; z += z2 * num8; double num9 = KoiMath.Radius(shape, Math.Atan2(z, x)) * width * 0.5; x *= num9; z *= num9 * KoiMath.Aspect(shape); } internal static double SurfaceBlend(double time, int index, double seed) { double num = 36.0 + Random(seed, 0, 0L, 5) * 12.0; double num2 = time / num + Random(seed, 0, 0L, 6) + (double)index * 0.6180339887498949; num2 -= Math.Floor(num2); double num3 = 1.0 / 3.0; double num4 = 2.0 / num; if (num2 < num3) { return 1.0; } if (num2 < num3 + num4) { return 1.0 - Smooth((num2 - num3) / num4); } if (num2 > 1.0 - num4) { return Smooth((num2 - 1.0 + num4) / num4); } return 0.0; } private static double Smooth(double t) { return t * t * (3.0 - 2.0 * t); } } }