using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FishNet; using FishNet.Broadcast; using FishNet.Connection; using FishNet.Managing.Client; using FishNet.Managing.Server; using FishNet.Object; using FishNet.Serializing; using FishNet.Transporting; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Yakari")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Yakari")] [assembly: AssemblyDescription("Squeeze Bing Bong. He squeaks, then he answers.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Talking Bing Bong")] [assembly: AssemblyTitle("HowToFish.BingBong")] [assembly: AssemblyVersion("1.0.0.0")] namespace HowToFish.BingBong; internal sealed class BingBongBeak { private readonly Item _fish; private SkinnedMeshRenderer _source; private GameObject _root; private Transform _upper; private Transform _lower; private Quaternion _upperRest; private Quaternion _lowerRest; private Vector3 _pivot; private Vector3 _hingeAxisLocal = Vector3.up; private const int HingeSide = 1; private readonly List _meshes = new List(); private static Texture2D _paletteCache; private static Texture _paletteSource; internal bool Built => (Object)(object)_root != (Object)null; internal SkinnedMeshRenderer Source => _source; internal BingBongBeak(Item fish) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) _fish = fish; } internal bool Build(Transform rootBone) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0070: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Expected O, but got Unknown //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_047f: 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) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_0556: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_0567: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0575: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) Dispose(); if ((Object)(object)_fish == (Object)null || (Object)(object)rootBone == (Object)null) { return false; } SkinnedMeshRenderer componentInChildren = ((Component)_fish).GetComponentInChildren(false); if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.sharedMesh == (Object)null) { return false; } Mesh val = new Mesh(); componentInChildren.BakeMesh(val, true); if (val.vertexCount < 100) { Object.Destroy((Object)(object)val); return false; } Matrix4x4 val2 = ((Component)_fish).transform.worldToLocalMatrix * ((Component)componentInChildren).transform.localToWorldMatrix; Vector3[] vertices = val.vertices; Vector3[] normals = val.normals; for (int i = 0; i < vertices.Length; i++) { vertices[i] = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(vertices[i]); } if (normals != null && normals.Length == vertices.Length) { for (int j = 0; j < normals.Length; j++) { int num = j; Vector3 val3 = ((Matrix4x4)(ref val2)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val3)).normalized; } } Vector2[] uv = val.uv; int[] triangles = val.triangles; Texture2D val4 = Palette(((Renderer)componentInChildren).sharedMaterial); if ((Object)(object)val4 == (Object)null || uv == null || uv.Length != vertices.Length) { Object.Destroy((Object)(object)val); return false; } List list = new List(); List list2 = new List(); List list3 = new List(); for (int k = 0; k + 2 < triangles.Length; k += 3) { int num2 = triangles[k]; int num3 = triangles[k + 1]; int num4 = triangles[k + 2]; if (IsOrange(val4, uv[num2]) && IsOrange(val4, uv[num3]) && IsOrange(val4, uv[num4])) { list.Add(k); list3.Add((vertices[num2].z + vertices[num3].z + vertices[num4].z) / 3f); } else { list2.Add(k); } } if (list.Count < 50 || list.Count > 2000) { ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogWarning((object)("BingBong: beak classification found " + list.Count + " triangles - not splitting.")); } Object.Destroy((Object)(object)val); return false; } List list4 = new List(list3); list4.Sort(); float num5 = list4[list4.Count / 5]; float num6 = list4[list4.Count * 4 / 5]; for (int l = 0; l < 12; l++) { float num7 = 0f; float num8 = 0f; int num9 = 0; int num10 = 0; foreach (float item in list4) { if (Mathf.Abs(item - num5) <= Mathf.Abs(item - num6)) { num7 += item; num9++; } else { num8 += item; num10++; } } if (num9 > 0) { num5 = num7 / (float)num9; } if (num10 > 0) { num6 = num8 / (float)num10; } } float num11 = (num5 + num6) * 0.5f; List list5 = new List(); List list6 = new List(); float num12 = float.MaxValue; float num13 = float.MinValue; float num14 = 0f; int num15 = 0; for (int m = 0; m < list.Count; m++) { int num16 = list[m]; ((list3[m] >= num11) ? list5 : list6).Add(num16); for (int n = 0; n < 3; n++) { Vector3 val5 = vertices[triangles[num16 + n]]; if (val5.x < num12) { num12 = val5.x; } if (val5.x > num13) { num13 = val5.x; } num14 += val5.y; num15++; } } float num17 = (num13 - num12) * 0.12f; float num18 = num13 - num17; Vector3 pivot = default(Vector3); ((Vector3)(ref pivot))..ctor(num18, num14 / (float)Mathf.Max(1, num15), num11); _source = componentInChildren; _root = new GameObject("YakariBingBongBeak"); _root.transform.SetParent(rootBone, false); Matrix4x4 val6 = rootBone.worldToLocalMatrix * ((Component)_fish).transform.localToWorldMatrix; _root.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val6)).GetColumn(3)); _root.transform.localRotation = ((Matrix4x4)(ref val6)).rotation; _root.transform.localScale = ((Matrix4x4)(ref val6)).lossyScale; Material material = ((Renderer)componentInChildren).material; MakePart("Body", vertices, normals, uv, val, list2, triangles, Vector3.zero, material, _root.transform); _upper = MakePart("BeakUpper", vertices, normals, uv, val, list5, triangles, pivot, material, _root.transform).transform; _lower = MakePart("BeakLower", vertices, normals, uv, val, list6, triangles, pivot, material, _root.transform).transform; _upperRest = _upper.localRotation; _lowerRest = _lower.localRotation; _pivot = pivot; _hingeAxisLocal = Vector3.up; ((Renderer)componentInChildren).enabled = false; Object.Destroy((Object)(object)val); ManualLogSource logSrc2 = Plugin.LogSrc; if (logSrc2 != null) { logSrc2.LogInfo((object)("BingBong: beak split - " + list5.Count + " upper / " + list6.Count + " lower tris, seam z=" + num11.ToString("0.000") + ", joint x=" + num18.ToString("0.000") + " (beak x " + num12.ToString("0.000") + ".." + num13.ToString("0.000") + ")")); } return true; } private GameObject MakePart(string name, Vector3[] v, Vector3[] n, Vector2[] uv0, Mesh src, List triStarts, int[] tris, Vector3 pivot, Material mat, Transform parent) { //IL_018e: 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_01a6: Expected O, but got Unknown //IL_00e5: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Expected O, but got Unknown //IL_0133: 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) Dictionary dictionary = new Dictionary(); List list = new List(triStarts.Count * 3); List list2 = new List(); List list3 = new List(); List> list4 = new List>(); List> list5 = new List>(); for (int i = 0; i < 8; i++) { List list6 = new List(); src.GetUVs(i, list6); list5.Add((list6.Count == v.Length) ? list6 : null); list4.Add(new List()); } Color[] colors = src.colors; bool flag = colors != null && colors.Length == v.Length; List list7 = new List(); foreach (int triStart in triStarts) { for (int j = 0; j < 3; j++) { int num = tris[triStart + j]; if (!dictionary.TryGetValue(num, out var value)) { value = (dictionary[num] = list2.Count); list2.Add(v[num] - pivot); if (n != null && n.Length == v.Length) { list3.Add(n[num]); } for (int k = 0; k < 8; k++) { if (list5[k] != null) { list4[k].Add(list5[k][num]); } } if (flag) { list7.Add(colors[num]); } } list.Add(value); } } Mesh val = new Mesh { name = "YakariBingBong_" + name }; val.SetVertices(list2); if (list3.Count == list2.Count) { val.SetNormals(list3); } for (int l = 0; l < 8; l++) { if (list5[l] != null) { val.SetUVs(l, list4[l]); } } if (flag) { val.SetColors(list7); } val.SetTriangles(list, 0); if (list3.Count != list2.Count) { val.RecalculateNormals(); } val.RecalculateBounds(); _meshes.Add(val); GameObject val2 = new GameObject(name); val2.transform.SetParent(parent, false); val2.transform.localPosition = pivot; val2.AddComponent().sharedMesh = val; MeshRenderer obj = val2.AddComponent(); ((Renderer)obj).sharedMaterial = mat; ((Renderer)obj).shadowCastingMode = ((Renderer)_source).shadowCastingMode; ((Renderer)obj).receiveShadows = ((Renderer)_source).receiveShadows; return val2; } internal void SetOpen(float open01, float maxAngle, bool flip) { //IL_0043: 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_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_006d: 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_0077: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_upper == (Object)null) && !((Object)(object)_lower == (Object)null)) { float num = Mathf.Clamp01(open01) * maxAngle * (flip ? (-1f) : 1f) * -1f; _upper.localRotation = _upperRest * Quaternion.AngleAxis(0f - num, _hingeAxisLocal); _lower.localRotation = _lowerRest * Quaternion.AngleAxis(num, _hingeAxisLocal); } } internal bool SourceChanged() { SkinnedMeshRenderer val = (((Object)(object)_fish != (Object)null) ? ((Component)_fish).GetComponentInChildren(false) : null); if ((Object)(object)_root != (Object)null && (Object)(object)val != (Object)null) { return (Object)(object)val != (Object)(object)_source; } return false; } internal void Dispose() { if ((Object)(object)_source != (Object)null) { ((Renderer)_source).enabled = true; } _source = null; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _upper = null; _lower = null; foreach (Mesh mesh in _meshes) { if ((Object)(object)mesh != (Object)null) { Object.Destroy((Object)(object)mesh); } } _meshes.Clear(); } private static Texture2D Palette(Material mat) { //IL_0085: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00d2: Expected O, but got Unknown //IL_00d9: Expected O, but got Unknown if ((Object)(object)mat == (Object)null || !mat.HasProperty("_Colors")) { return null; } Texture texture = mat.GetTexture("_Colors"); if ((Object)(object)texture == (Object)null) { return null; } if ((Object)(object)_paletteCache != (Object)null && (Object)(object)_paletteSource == (Object)(object)texture) { return _paletteCache; } RenderTexture temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; try { Graphics.Blit(texture, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(texture.width, texture.height, (TextureFormat)4, false); val.ReadPixels(new Rect(0f, 0f, (float)texture.width, (float)texture.height), 0, 0); val.Apply(); if ((Object)(object)_paletteCache != (Object)null) { Object.Destroy((Object)(object)_paletteCache); } _paletteCache = val; _paletteSource = texture; return val; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static bool IsOrange(Texture2D palette, Vector2 uv) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) int num = Mathf.Clamp((int)(uv.x * (float)((Texture)palette).width), 0, ((Texture)palette).width - 1); int num2 = Mathf.Clamp((int)(uv.y * (float)((Texture)palette).height), 0, ((Texture)palette).height - 1); float num3 = default(float); float num4 = default(float); float num5 = default(float); Color.RGBToHSV(palette.GetPixel(num, num2), ref num3, ref num4, ref num5); if (num3 >= 0.04f && num3 <= 0.13f && num4 > 0.5f) { return num5 > 0.5f; } return false; } internal static void ReleasePalette() { if ((Object)(object)_paletteCache != (Object)null) { Object.Destroy((Object)(object)_paletteCache); } _paletteCache = null; _paletteSource = null; } } internal static class BingBongBossBar { private static GameObject _go; private static CanvasGroup _group; private static TextMeshProUGUI _name; private static Image _fill; private static Image _fillLerped; private static RectTransform _move; private static RectTransform _rot; private static Image _timer; private static CanvasGroup _countdown; private static TextMeshProUGUI _countdownText; private static float _fightEndsAt = -1f; private static float _fightTotal = 1f; private static bool _countingDown; private static Vector3 _startPos; private static Vector3 _vel; private static Vector3 _angVel; private static float _lastFill = 1f; private static Item _fish; private static bool _visible; private static readonly List _ownedMats = new List(); private static readonly int RotMultID = Shader.PropertyToID("_Rotation_Multiplier"); private const float ShakeForce = 750f; private const float LerpForce = 1200f; private const float HpDamping = 12f; private const float ShakeAngForce = 10f; private const float AngLerpForce = 120f; private const float HpAngDamping = 20f; private static bool Build() { //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Expected O, but got Unknown //IL_0569: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_go != (Object)null) { return true; } FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerUI), "_instance"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(PlayerUI), "_bossUI"); PlayerUI val = (PlayerUI)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null); BossUI val2 = (BossUI)(((Object)(object)val != (Object)null && fieldInfo2 != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val2 == (Object)null) { ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogWarning((object)"BingBong: vanilla BossUI not found - no boss bar."); } return false; } string[] obj = new string[9] { "_bossNameText", "_bossHpToMove", "_bossHpToRotate", "_bossHealth", "_bossHealthLerped", "_timeLeftImage", "_countdownGroup", "_timeCountdownText", "_bossCanvasLerped" }; Dictionary parts = new Dictionary(); string[] array = obj; foreach (string text in array) { object? obj2 = AccessTools.Field(typeof(BossUI), text)?.GetValue(val2); Component val3 = (Component)((obj2 is Component) ? obj2 : null); if ((Object)(object)val3 != (Object)null) { parts[text] = val3; } } if (!parts.ContainsKey("_bossHealth") || !parts.ContainsKey("_bossNameText")) { ManualLogSource logSrc2 = Plugin.LogSrc; if (logSrc2 != null) { logSrc2.LogWarning((object)"BingBong: boss bar parts missing on the vanilla widget - no boss bar."); } return false; } Transform panel = CommonAncestor(parts.Values); if ((Object)(object)panel == (Object)null) { ManualLogSource logSrc3 = Plugin.LogSrc; if (logSrc3 != null) { logSrc3.LogWarning((object)"BingBong: no common panel for the boss bar parts."); } return false; } _go = Object.Instantiate(((Component)panel).gameObject, panel.parent, true); ((Object)_go).name = "YakariBingBongBossBar"; LeanTween.cancel(_go, true); MonoBehaviour[] componentsInChildren = _go.GetComponentsInChildren(true); foreach (MonoBehaviour val4 in componentsInChildren) { if (!((Object)(object)val4 == (Object)null)) { string text2 = ((object)val4).GetType().Namespace ?? ""; if (!(val4 is Graphic) && !(val4 is TMP_Text) && !(val4 is LayoutGroup) && !(val4 is ContentSizeFitter) && !(val4 is Mask) && !(val4 is RectMask2D) && !(val4 is Shadow) && !(val4 is Outline) && !text2.StartsWith("UnityEngine.UI") && !text2.StartsWith("TMPro")) { Object.Destroy((Object)(object)val4); } } } Component obj3 = Copy("_bossNameText"); _name = (TextMeshProUGUI)(object)((obj3 is TextMeshProUGUI) ? obj3 : null); Component obj4 = Copy("_bossHpToMove"); _move = (RectTransform)(object)((obj4 is RectTransform) ? obj4 : null); Component obj5 = Copy("_bossHpToRotate"); _rot = (RectTransform)(object)((obj5 is RectTransform) ? obj5 : null); Component obj6 = Copy("_bossHealth"); _fill = (Image)(object)((obj6 is Image) ? obj6 : null); Component obj7 = Copy("_bossHealthLerped"); _fillLerped = (Image)(object)((obj7 is Image) ? obj7 : null); Component obj8 = Copy("_timeLeftImage"); _timer = (Image)(object)((obj8 is Image) ? obj8 : null); Component obj9 = Copy("_countdownGroup"); _countdown = (CanvasGroup)(object)((obj9 is CanvasGroup) ? obj9 : null); Component obj10 = Copy("_timeCountdownText"); _countdownText = (TextMeshProUGUI)(object)((obj10 is TextMeshProUGUI) ? obj10 : null); Component obj11 = Copy("_bossCanvasLerped"); CanvasGroup val5 = (CanvasGroup)(object)((obj11 is CanvasGroup) ? obj11 : null); if ((Object)(object)val5 != (Object)null) { LeanTween.cancel(((Component)val5).gameObject); val5.alpha = 1f; } _group = _go.GetComponent(); if ((Object)(object)_group == (Object)null) { _group = _go.AddComponent(); } _ = (Object)(object)val5 == (Object)(object)_group; if ((Object)(object)_name == (Object)null || (Object)(object)_move == (Object)null || (Object)(object)_rot == (Object)null || (Object)(object)_fill == (Object)null || (Object)(object)_fillLerped == (Object)null) { ManualLogSource logSrc4 = Plugin.LogSrc; if (logSrc4 != null) { logSrc4.LogWarning((object)"BingBong: could not resolve every boss bar part in the panel copy - no boss bar."); } Object.Destroy((Object)(object)_go); _go = null; return false; } ManualLogSource logSrc5 = Plugin.LogSrc; if (logSrc5 != null) { logSrc5.LogInfo((object)("BingBong: boss bar cloned from panel '" + ((Object)panel).name + "' (timer " + (((Object)(object)_timer != (Object)null) ? "yes" : "no") + ").")); } Image[] componentsInChildren2 = _go.GetComponentsInChildren(true); foreach (Image val6 in componentsInChildren2) { if ((Object)(object)((Graphic)val6).material != (Object)null && ((Graphic)val6).material.HasProperty(RotMultID)) { Material val7 = new Material(((Graphic)val6).material); val7.SetFloat(RotMultID, 0f); ((Graphic)val6).material = val7; _ownedMats.Add(val7); } } if ((Object)(object)_timer != (Object)null) { _timer.fillAmount = 1f; } if ((Object)(object)_countdown != (Object)null) { _countdown.alpha = 0f; ((Component)_countdown).gameObject.SetActive(false); } _startPos = ((Transform)_move).localPosition; _group.alpha = 0f; _go.SetActive(false); return true; Component Copy(string f) { if (!parts.TryGetValue(f, out var value)) { return null; } Transform obj12 = FindMatching(_go.transform, panel, value.transform); if (obj12 == null) { return null; } return ((Component)obj12).GetComponent(((object)value).GetType()); } } private static Transform CommonAncestor(IEnumerable comps) { Transform val = null; foreach (Component comp in comps) { if ((Object)(object)comp == (Object)null) { continue; } if ((Object)(object)val == (Object)null) { val = comp.transform; continue; } while ((Object)(object)val != (Object)null && !comp.transform.IsChildOf(val)) { val = val.parent; } if (!((Object)(object)val == (Object)null)) { continue; } return null; } return val; } private static Transform FindMatching(Transform copyRoot, Transform origRoot, Transform origNode) { List list = new List(); Transform val = origNode; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)origRoot) { list.Insert(0, val.GetSiblingIndex()); val = val.parent; } Transform val2 = copyRoot; foreach (int item in list) { if (item >= val2.childCount) { return null; } val2 = val2.GetChild(item); } return val2; } internal static void RepairVanilla() { FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerUI), "_instance"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(PlayerUI), "_bossUI"); PlayerUI val = (PlayerUI)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null); BossUI val2 = (BossUI)(((Object)(object)val != (Object)null && fieldInfo2 != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val2 == (Object)null) { return; } object? value = AccessTools.Field(typeof(BossUI), "_timeLeftImage").GetValue(val2); Image val3 = (Image)((value is Image) ? value : null); object? value2 = AccessTools.Field(typeof(BossUI), "_countdownGroup").GetValue(val2); CanvasGroup val4 = (CanvasGroup)((value2 is CanvasGroup) ? value2 : null); int num = 0; if ((Object)(object)val3 != (Object)null) { Transform val5 = ((Component)val3).transform; while ((Object)(object)val5 != (Object)null && (Object)(object)val5 != (Object)(object)((Component)val2).transform.parent) { if (!((Component)val5).gameObject.activeSelf && (Object)(object)val5 != (Object)(object)((Component)val2).transform) { ((Component)val5).gameObject.SetActive(true); num++; } val5 = val5.parent; } } if ((Object)(object)val4 != (Object)null && !((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(true); num++; } if (num > 0) { ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogInfo((object)("BingBong: restored " + num + " vanilla boss-timer object(s) an earlier build had hidden.")); } } } internal static void Show(Item fish, string name, float fightSeconds) { //IL_00a0: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00f6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)fish == (Object)null) && Build()) { _fightTotal = Mathf.Max(1f, fightSeconds); _fightEndsAt = ((fightSeconds > 0f) ? (Time.time + fightSeconds) : (-1f)); _countingDown = false; if ((Object)(object)_timer != (Object)null) { _timer.fillAmount = 1f; } if ((Object)(object)_countdown != (Object)null) { _countdown.alpha = 0f; ((Component)_countdown).gameObject.SetActive(false); } _fish = fish; ((TMP_Text)_name).text = name; ((Graphic)_fill).color = GameInfo.RedColor; _fill.fillAmount = 1f; _fillLerped.fillAmount = 1f; _lastFill = 1f; _vel = (_angVel = Vector3.zero); ((Transform)_move).localPosition = _startPos; ((Transform)_rot).localRotation = Quaternion.identity; _go.SetActive(true); Fade(1f); _visible = true; } } internal static void Hide() { if (!((Object)(object)_go == (Object)null) && _visible) { _visible = false; _fish = null; Fade(0f); } } private static void Fade(float to) { LeanTween.cancel(((Component)_group).gameObject); LeanTween.value(((Component)_group).gameObject, _group.alpha, to, 1f).setEase((LeanTweenType)2).setOnUpdate((Action)delegate(float a) { if ((Object)(object)_group != (Object)null) { _group.alpha = a; } }) .setOnComplete((Action)delegate { if (to == 0f && (Object)(object)_go != (Object)null && !_visible) { _go.SetActive(false); } }); } internal static void Tick() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_go == (Object)null || !_visible) { return; } if ((Object)(object)_fish == (Object)null || ((NetworkBehaviour)_fish).IsDeinitializing || (Object)(object)BossManager.Boss != (Object)null) { Hide(); return; } Creature component = ((Component)_fish).GetComponent(); if ((Object)(object)component == (Object)null) { Hide(); return; } UpdateTimer(); if (component.Hp <= 0) { RunSpring(); return; } float num = Mathf.Clamp01((float)component.Hp / (float)Mathf.Max(1, component.MaxHp)); if (num < _lastFill) { float num2 = Mathf.Clamp(_lastFill - num, 0.025f, 1f); Vector3 insideUnitSphere = Random.insideUnitSphere; _vel = ((Vector3)(ref insideUnitSphere)).normalized * num2 * ((Random.Range(0, 2) == 1) ? 1f : (-1f)) * 750f; float num3 = ((Random.Range(0, 2) == 1) ? 1f : (-1f)); _angVel += new Vector3(0f, 0f, num3 * num2 * 10f); _fill.fillAmount = num; LeanTween.cancel(((Component)_fillLerped).gameObject); LeanTween.value(((Component)_fillLerped).gameObject, _fillLerped.fillAmount, num, 0.5f).setDelay(0.25f).setEase((LeanTweenType)9) .setOnUpdate((Action)delegate(float f) { if ((Object)(object)_fillLerped != (Object)null) { _fillLerped.fillAmount = f; } }); } else if (num > _lastFill) { _fill.fillAmount = num; _fillLerped.fillAmount = num; } _lastFill = num; RunSpring(); } private static void UpdateTimer() { if (_fightEndsAt < 0f) { return; } float num = Mathf.Max(0f, _fightEndsAt - Time.time); if ((Object)(object)_timer != (Object)null) { _timer.fillAmount = num / _fightTotal; } if ((Object)(object)_countdown == (Object)null || (Object)(object)_countdownText == (Object)null) { return; } if (num >= 10f) { _countdown.alpha = 0f; return; } if (!_countingDown) { _countingDown = true; ((Component)_countdown).gameObject.SetActive(true); LeanTween.cancel(((Component)_countdown).gameObject); LeanTween.value(((Component)_countdown).gameObject, 0f, 1f, 1f).setEase((LeanTweenType)2).setOnUpdate((Action)delegate(float a) { if ((Object)(object)_countdown != (Object)null) { _countdown.alpha = a; } }); } ((TMP_Text)_countdownText).text = num.ToString("#0"); } private static void RunSpring() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_004e: 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_0063: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (_startPos - ((Transform)_move).localPosition) * 1200f; _vel += val * Time.deltaTime; _vel -= _vel * (12f * Time.deltaTime); RectTransform move = _move; ((Transform)move).localPosition = ((Transform)move).localPosition + _vel * Time.deltaTime; Quaternion localRotation = ((Transform)_rot).localRotation; DazedUtils.SimulateSpringRotation(ref localRotation, ref _angVel, Quaternion.identity, 120f, 20f); ((Transform)_rot).localRotation = localRotation; } internal static void DestroyAll() { if ((Object)(object)_go != (Object)null) { LeanTween.cancel(_go); Object.Destroy((Object)(object)_go); } foreach (Material ownedMat in _ownedMats) { if ((Object)(object)ownedMat != (Object)null) { Object.Destroy((Object)(object)ownedMat); } } _ownedMats.Clear(); _go = null; _group = null; _name = null; _fill = null; _fillLerped = null; _move = null; _rot = null; _fish = null; _visible = false; } } internal struct SqueezeMsg : IBroadcast { public byte Version; public int PlayerObjectId; public int FishObjectId; public byte Kind; public byte LineIndex; } internal static class BingBongNet { internal const byte ProtocolVersion = 2; private static bool _registered; private static bool _disabled; private static bool _warnedVersion; private static bool _warnedSendError; internal static void EnsureRegistered() { if (_registered || _disabled || (Object)(object)InstanceFinder.NetworkManager == (Object)null || (Object)(object)InstanceFinder.ServerManager == (Object)null || (Object)(object)InstanceFinder.ClientManager == (Object)null) { return; } try { PurgeStaleHandlers(InstanceFinder.ServerManager); PurgeStaleHandlers(InstanceFinder.ClientManager); GenericWriter.SetWrite((Action)WriteMsg); GenericReader.SetRead((Func)ReadMsg); InstanceFinder.ServerManager.RegisterBroadcast((Action)OnServer, true); InstanceFinder.ClientManager.RegisterBroadcast((Action)OnClient); _registered = true; ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogInfo((object)("BingBongNet registered (protocol v" + (byte)2 + ").")); } } catch (Exception ex) { _disabled = true; ManualLogSource logSrc2 = Plugin.LogSrc; if (logSrc2 != null) { logSrc2.LogWarning((object)("BingBongNet disabled - register failed: " + ex.Message)); } } } internal static void Unregister() { if (!_registered) { return; } _registered = false; try { ServerManager serverManager = InstanceFinder.ServerManager; if (serverManager != null) { serverManager.UnregisterBroadcast((Action)OnServer); } ClientManager clientManager = InstanceFinder.ClientManager; if (clientManager != null) { clientManager.UnregisterBroadcast((Action)OnClient); } PurgeStaleHandlers(InstanceFinder.ServerManager); PurgeStaleHandlers(InstanceFinder.ClientManager); } catch (Exception ex) { ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogWarning((object)("BingBongNet unregister: " + ex.Message)); } } } private static void PurgeStaleHandlers(object manager) { if (manager == null || !(manager.GetType().GetField("_broadcastHandlers", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(manager) is IDictionary dictionary)) { return; } List list = new List(); foreach (DictionaryEntry item in dictionary) { Type type = item.Value?.GetType(); if (!(type == null) && type.IsGenericType) { Type[] genericArguments = type.GetGenericArguments(); if (genericArguments.Length == 1 && genericArguments[0].FullName == typeof(SqueezeMsg).FullName) { list.Add(item.Key); } } } foreach (object item2 in list) { dictionary.Remove(item2); } if (list.Count > 0) { ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogInfo((object)("BingBongNet purged " + list.Count + " stale handler(s) from " + manager.GetType().Name + " (hot reload leftovers).")); } } } private static void WriteMsg(Writer w, SqueezeMsg m) { w.WriteUInt8Unpacked(m.Version); w.WriteInt32(m.PlayerObjectId); w.WriteInt32(m.FishObjectId); w.WriteUInt8Unpacked(m.Kind); w.WriteUInt8Unpacked(m.LineIndex); } private static SqueezeMsg ReadMsg(Reader r) { return new SqueezeMsg { Version = r.ReadUInt8Unpacked(), PlayerObjectId = r.ReadInt32(), FishObjectId = r.ReadInt32(), Kind = r.ReadUInt8Unpacked(), LineIndex = r.ReadUInt8Unpacked() }; } internal static void SendSqueeze() { Send(0, 255); } internal static void SendSpeak(int lineIndex, Plugin.Pool pool, Item fish) { int kind = pool switch { Plugin.Pool.PanicAngry => 18, Plugin.Pool.Hundred => 17, Plugin.Pool.Idle => 16, Plugin.Pool.Panic => 15, Plugin.Pool.Relief => 14, Plugin.Pool.FightOpen => 11, Plugin.Pool.Warn => 10, Plugin.Pool.Fight => 9, Plugin.Pool.Hurt => 8, Plugin.Pool.Angry => 4, _ => 1, }; int fishObjectId = (((Object)(object)fish != (Object)null && (Object)(object)fish.Holder == (Object)null) ? ((NetworkBehaviour)fish).ObjectId : 0); Send((byte)kind, lineIndex, fishObjectId); } internal static void SendFight(Item fish) { if ((Object)(object)fish != (Object)null) { Send(6, 255, ((NetworkBehaviour)fish).ObjectId); } } internal static void SendStage(Item fish, bool fighting) { if ((Object)(object)fish != (Object)null) { Send(7, fighting ? 1 : 0, ((NetworkBehaviour)fish).ObjectId); } } internal static void SendRage(bool on) { Send((byte)(on ? 2 : 3), 255); } internal static void SendProvoke(Item fish, float points) { if (!((Object)(object)fish == (Object)null)) { Send(5, Mathf.Clamp(Mathf.RoundToInt(points * 10f), 1, 254), ((NetworkBehaviour)fish).ObjectId); } } private static void Send(byte kind, int lineIndex, int fishObjectId = 0) { try { if (_disabled) { return; } EnsureRegistered(); if (!_registered) { return; } Player localPlayer = Player.LocalPlayer; if (!((Object)(object)localPlayer == (Object)null)) { SqueezeMsg squeezeMsg = new SqueezeMsg { Version = 2, PlayerObjectId = ((NetworkBehaviour)localPlayer).ObjectId, FishObjectId = fishObjectId, Kind = kind, LineIndex = (byte)((lineIndex >= 0 && lineIndex < 255) ? ((uint)lineIndex) : 255u) }; if (InstanceFinder.IsServerStarted) { InstanceFinder.ServerManager.BroadcastExcept(InstanceFinder.ClientManager.Connection, squeezeMsg, true, (Channel)0); } else if (InstanceFinder.IsClientStarted) { InstanceFinder.ClientManager.Broadcast(squeezeMsg, (Channel)0); } } } catch (Exception ex) { if (!_warnedSendError) { _warnedSendError = true; ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogWarning((object)("Squeeze sync disabled until next reload - send failed: " + ex.Message)); } } _disabled = true; } } private static Item FindFish(int objectId) { if (objectId == 0) { return null; } Item val = Plugin.Instance?.FindShownFish(objectId); if ((Object)(object)val != (Object)null) { return val; } foreach (Creature deadCreature in Creature.DeadCreatures) { if ((Object)(object)deadCreature != (Object)null && ((NetworkBehaviour)deadCreature).ObjectId == objectId) { return (Item)(object)deadCreature; } } return null; } private static void OnServer(NetworkConnection sender, SqueezeMsg msg, Channel ch) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (msg.Kind == 6) { Player provoker = null; foreach (Player player in PlayerManager.Players) { if ((Object)(object)player != (Object)null && ((NetworkBehaviour)player).ObjectId == msg.PlayerObjectId) { provoker = player; break; } } Plugin.Instance?.HostRevive(FindFish(msg.FishObjectId), provoker); } else { InstanceFinder.ServerManager.BroadcastExcept(sender, msg, true, ch); } } private static void OnClient(SqueezeMsg msg, Channel ch) { if (msg.Version != 2) { if (!_warnedVersion) { _warnedVersion = true; ManualLogSource logSrc = Plugin.LogSrc; if (logSrc != null) { logSrc.LogWarning((object)("Received squeeze protocol v" + msg.Version + " but ours is v" + (byte)2 + " - both players need the same BingBong version.")); } } return; } Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer != (Object)null && msg.PlayerObjectId == ((NetworkBehaviour)localPlayer).ObjectId) { return; } Player val = null; foreach (Player player in PlayerManager.Players) { if ((Object)(object)player != (Object)null && ((NetworkBehaviour)player).ObjectId == msg.PlayerObjectId) { val = player; break; } } if ((Object)(object)val == (Object)null) { return; } int lineIdx = ((msg.LineIndex == byte.MaxValue) ? (-1) : msg.LineIndex); switch (msg.Kind) { case 5: Plugin.Instance?.RemoteProvoke(val, FindFish(msg.FishObjectId), (float)(int)msg.LineIndex / 10f); break; case 7: { Item val2 = FindFish(msg.FishObjectId); if ((Object)(object)val2 != (Object)null && msg.LineIndex == 1) { Plugin.Instance?.ApplyStageFight(Plugin.Instance.ShowFor(val2)); } break; } case 0: Plugin.Instance?.RemoteSqueeze(val); break; case 1: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Normal); break; case 4: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Angry); break; case 8: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Hurt); break; case 9: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Fight); break; case 10: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Warn); break; case 11: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.FightOpen); break; case 14: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Relief); break; case 15: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Panic); break; case 16: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Idle); break; case 17: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.Hundred); break; case 18: Plugin.Instance?.RemoteSpeak(val, FindFish(msg.FishObjectId), lineIdx, Plugin.Pool.PanicAngry); break; case 2: Plugin.Instance?.RemoteRage(val, on: true); break; case 3: Plugin.Instance?.RemoteRage(val, on: false); break; case 6: case 12: case 13: break; } } } [BepInPlugin("howtofish.bingbong", "BingBong", "1.0.0")] public class Plugin : BaseUnityPlugin { internal enum Pool : byte { Normal, Angry, Hurt, Fight, Sorry, Warn, FightOpen, Relief, Panic, Idle, Hundred, PanicAngry } private class FishShow { public Item Fish; public Transform Root; public Vector3 RestScale; public bool SpringActive; public float S; public float V; public AudioSource SqueakSource; public AudioSource VoiceSource; public float SpeakAt = -1f; public AudioClip TalkClip; public float[] TalkEnv; public Pool TalkPool; public bool Talking; public float Open; public Transform ShakeBone; public Quaternion ShakeRest; public Transform LeanTarget; public WorldText Caption; public BingBongBeak Beak; public float BeakOpen; public float CookLean = 1f; public float Cook; public float BasePitch = 1f; public float WobbleSeed; public float DropoutUntil = -1f; public float NextDropoutRoll; public float Shrivel = 1f; public AudioLowPassFilter LowPass; public AudioDistortionFilter Distortion; public float Heat; public bool Raging; public GameObject EnableOnShiny; public GameObject DisableOnShiny; public Vector3 JerkTarget; public Vector3 Jerk; public Vector3 JerkVel; public bool AttackArmed = true; public float Provoke; public float LastProvoke = -1f; public bool Fighting; public float FightEndsAt = -1f; public float NextChatter; public float NextIdle; public bool BirdHeld; public readonly List FightBag = new List(); public int LastFightIdx = -1; public float SorryUntil = -1f; } private enum ProvokeStage { Calm, Hurt, Angry, Fight } public const string Guid = "howtofish.bingbong"; public const string Name = "BingBong"; public const string Version = "1.0.0"; internal static Plugin Instance; internal static ManualLogSource LogSrc; private static readonly string AssetDir = ResolveAssetDir(); private ConfigEntry _clipFile; private ConfigEntry _volume; private ConfigEntry _settleDelay; private ConfigEntry _squeakFile; private ConfigEntry _squeakVolume; private ConfigEntry _leanAmount; private ConfigEntry _squashAmount; private ConfigEntry _springK; private ConfigEntry _springDamp; private ConfigEntry _cooldown; private ConfigEntry _syncEnabled; private ConfigEntry _captionEnabled; private ConfigEntry _captionSize; private ConfigEntry _captionHeight; private ConfigEntry _captionWrap; private ConfigEntry _cookEnabled; private ConfigEntry _cookMinPitch; private ConfigEntry _cookMinVolume; private ConfigEntry _cookSqueakMinPitch; private ConfigEntry _cookDeadAt; private ConfigEntry _cookWobble; private ConfigEntry _cookDropouts; private ConfigEntry _cookLowPass; private ConfigEntry _cookDistortion; private ConfigEntry _cookShrivel; private ConfigEntry _cookGlitchText; private ConfigEntry _rageEnabled; private ConfigEntry _rageSqueezes; private ConfigEntry _rageDecay; private ConfigEntry _rageCaptionColor; private ConfigEntry _thrashAngle; private ConfigEntry _thrashJitter; private ConfigEntry _thrashPump; private ConfigEntry _provokeEnabled; private ConfigEntry _provokeAngryAt; private ConfigEntry _provokeFightAt; private ConfigEntry _provokeDecay; private ConfigEntry _provokeSpamWeight; private ConfigEntry _groundThrashScale; private ConfigEntry _chatterInterval; private ConfigEntry _sorrySeconds; private ConfigEntry _lungeSpeed; private ConfigEntry _idleInterval; private ConfigEntry _idleVolume; private ConfigEntry _hundredEvery; private ConfigEntry _squeezeCount; private ConfigEntry _fightMusic; private ConfigEntry _beakEnabled; private ConfigEntry _beakAngle; private ConfigEntry _beakFlip; private ConfigEntry _beakGain; private ConfigEntry _beakFloor; private ConfigEntry _beakRelease; private ConfigEntry _beakFlutterHz; private ConfigEntry _beakFlutter; private ConfigEntry _bossBar; private ConfigEntry _bossBarName; private ConfigEntry _fightSeconds; private static int _fightsWithMusic; private Harmony _harmony; private bool _inputHooked; private float _lastSqueeze; private AudioClip _clip; private float[] _envelope; private AudioClip _squeak; private readonly List _lines = new List(); private readonly List _lineEnvs = new List(); private readonly List _lineCaptions = new List(); private readonly List _angry = new List(); private readonly List _angryEnvs = new List(); private readonly List _angryCaptions = new List(); private readonly List _hurt = new List(); private readonly List _hurtEnvs = new List(); private readonly List _hurtCaptions = new List(); private readonly List _fight = new List(); private readonly List _fightEnvs = new List(); private readonly List _fightCaptions = new List(); private readonly List _sorry = new List(); private readonly List _sorryEnvs = new List(); private readonly List _sorryCaptions = new List(); private readonly List _warn = new List(); private readonly List _warnEnvs = new List(); private readonly List _warnCaptions = new List(); private readonly List _open = new List(); private readonly List _openEnvs = new List(); private readonly List _openCaptions = new List(); private readonly List _relief = new List(); private readonly List _reliefEnvs = new List(); private readonly List _reliefCaptions = new List(); private readonly List _panic = new List(); private readonly List _panicEnvs = new List(); private readonly List _panicCaptions = new List(); private readonly List _idle = new List(); private readonly List _idleEnvs = new List(); private readonly List _idleCaptions = new List(); private readonly List _hundred = new List(); private readonly List _hundredEnvs = new List(); private readonly List _hundredCaptions = new List(); private readonly List _panicAngry = new List(); private readonly List _panicAngryEnvs = new List(); private readonly List _panicAngryCaptions = new List(); private readonly Dictionary _shows = new Dictionary(); private static readonly List _deadKeys = new List(); private bool _warnedVanillaHost; private static string ResolveAssetDir() { try { string location = Assembly.GetExecutingAssembly().Location; if (!string.IsNullOrEmpty(location)) { string directoryName = Path.GetDirectoryName(location); string text = Path.Combine(directoryName, "BingBong"); if (Directory.Exists(text)) { return text; } if (Directory.Exists(Path.Combine(directoryName, "lines"))) { return directoryName; } } } catch { } return Path.Combine(Paths.PluginPath, "BingBong"); } private List Clips(Pool p) { return p switch { Pool.Angry => _angry, Pool.Hurt => _hurt, Pool.Fight => _fight, Pool.Sorry => _sorry, Pool.Warn => _warn, Pool.FightOpen => _open, Pool.Relief => _relief, Pool.Panic => _panic, Pool.Idle => _idle, Pool.Hundred => _hundred, Pool.PanicAngry => _panicAngry, _ => _lines, }; } private List Envs(Pool p) { return p switch { Pool.Angry => _angryEnvs, Pool.Hurt => _hurtEnvs, Pool.Fight => _fightEnvs, Pool.Sorry => _sorryEnvs, Pool.Warn => _warnEnvs, Pool.FightOpen => _openEnvs, Pool.Relief => _reliefEnvs, Pool.Panic => _panicEnvs, Pool.Idle => _idleEnvs, Pool.Hundred => _hundredEnvs, Pool.PanicAngry => _panicAngryEnvs, _ => _lineEnvs, }; } private List Caps(Pool p) { return p switch { Pool.Angry => _angryCaptions, Pool.Hurt => _hurtCaptions, Pool.Fight => _fightCaptions, Pool.Sorry => _sorryCaptions, Pool.Warn => _warnCaptions, Pool.FightOpen => _openCaptions, Pool.Relief => _reliefCaptions, Pool.Panic => _panicCaptions, Pool.Idle => _idleCaptions, Pool.Hundred => _hundredCaptions, Pool.PanicAngry => _panicAngryCaptions, _ => _lineCaptions, }; } private void Awake() { //IL_084b: Unknown result type (might be due to invalid IL or missing references) //IL_0855: Expected O, but got Unknown Instance = this; LogSrc = ((BaseUnityPlugin)this).Logger; _clipFile = ((BaseUnityPlugin)this).Config.Bind("Voice", "ClipFile", "bingbong-1.50.mp3", "Fallback voice clip in BepInEx/plugins/BingBong/ (used only if lines/ is missing)."); _volume = ((BaseUnityPlugin)this).Config.Bind("Voice", "Volume", 1f, "Voice volume (0..1)."); _settleDelay = ((BaseUnityPlugin)this).Config.Bind("Voice", "VoiceSettleDelay", 0.22f, "Seconds of NO squeezing before he answers. Spamming keeps resetting this, so you get pure squeaks while mashing and one clean answer when you stop."); _squeakFile = ((BaseUnityPlugin)this).Config.Bind("Voice", "SqueakFile", "bingbong-squeak.mp3", "Squeaky-toy SFX played the instant he is squeezed (Marsh's cut of Pixabay squeaky-toy-1)."); _squeakVolume = ((BaseUnityPlugin)this).Config.Bind("Voice", "SqueakVolume", 1f, "Squeak volume (0..1)."); _leanAmount = ((BaseUnityPlugin)this).Config.Bind("Voice", "TalkLeanAmount", 16f, "How far (degrees) he leans into the listener on loud syllables. 0 disables."); _squashAmount = ((BaseUnityPlugin)this).Config.Bind("Squeeze", "SquashAmount", 0.45f, "Squish depth: 0.45 = pressed to 55% on the grip axis, bulging outward to keep volume."); _springK = ((BaseUnityPlugin)this).Config.Bind("Squeeze", "SpringStiffness", 260f, "Spring stiffness. Higher = snappier pop back."); _springDamp = ((BaseUnityPlugin)this).Config.Bind("Squeeze", "SpringDamping", 11f, "Damping. Lower = more rubbery wobbles before settling."); _cooldown = ((BaseUnityPlugin)this).Config.Bind("Squeeze", "Cooldown", 0.06f, "Min seconds between squeezes - low so the squeak stays spammable."); _syncEnabled = ((BaseUnityPlugin)this).Config.Bind("Multiplayer", "EnableSync", true, "Broadcast squeezes so other modded players see and hear them."); _captionEnabled = ((BaseUnityPlugin)this).Config.Bind("Caption", "Enabled", true, "Float the words he is saying over his head while he talks."); _captionSize = ((BaseUnityPlugin)this).Config.Bind("Caption", "Size", 0.065f, "Caption font size (game WorldText units)."); _captionWrap = ((BaseUnityPlugin)this).Config.Bind("Caption", "WrapAfter", 12, "Captions longer than this many characters break onto a second row at the nearest space."); _captionHeight = ((BaseUnityPlugin)this).Config.Bind("Caption", "Height", 0.15f, "How far above the top of his body the caption sits, in metres."); _cookEnabled = ((BaseUnityPlugin)this).Config.Bind("Cooking", "Enabled", true, "Cooking him lowers his pitch and volume; burnt, he can only wheeze."); _cookMinPitch = ((BaseUnityPlugin)this).Config.Bind("Cooking", "VoiceMinPitch", 0.5f, "Voice pitch when fully burnt (1 = normal). Lower pitch also slows the line - dying-battery toy. At cookness 1.0 (the x1.5 point) he is already ~60% of the way there."); _cookMinVolume = ((BaseUnityPlugin)this).Config.Bind("Cooking", "VoiceMinVolume", 0.3f, "Voice volume multiplier when fully burnt."); _cookSqueakMinPitch = ((BaseUnityPlugin)this).Config.Bind("Cooking", "SqueakMinPitch", 0.55f, "Squeak pitch when fully burnt - the rubber melts too."); _cookDeadAt = ((BaseUnityPlugin)this).Config.Bind("Cooking", "DeadAt", 1.95f, "Cookness at which he stops talking altogether. 2 = fully black; 1.95 = visibly charcoal."); _cookWobble = ((BaseUnityPlugin)this).Config.Bind("Cooking", "WobbleDepth", 0.14f, "Wow & flutter: how far his pitch drifts and wobbles when fully burnt (0.14 = +/-14%). The dying-battery sound."); _cookDropouts = ((BaseUnityPlugin)this).Config.Bind("Cooking", "DropoutsPerSecond", 7f, "Frying-contact cut-outs per second when fully burnt (each 20-60 ms). Scales with cookness."); _cookLowPass = ((BaseUnityPlugin)this).Config.Bind("Cooking", "LowPassAtBurnt", 900f, "Low-pass cutoff (Hz) when fully burnt - the speaker cone melting. 22000 = off."); _cookDistortion = ((BaseUnityPlugin)this).Config.Bind("Cooking", "DistortionAtBurnt", 0.6f, "Distortion level (0..1) when fully burnt - fried speaker crunch."); _cookShrivel = ((BaseUnityPlugin)this).Config.Bind("Cooking", "Shrivel", 0.08f, "Uniform melt-shrink when fully burnt (0.08 = 8% smaller). Uniform on purpose - squashing one axis of a held item reads as a glitch."); _cookGlitchText = ((BaseUnityPlugin)this).Config.Bind("Cooking", "GlitchCaption", true, "Stutter and drop letters in the caption as he cooks."); _rageEnabled = ((BaseUnityPlugin)this).Config.Bind("Rage", "Enabled", true, "Over-squeezing turns him into the angry red version until he is dropped in water."); _rageSqueezes = ((BaseUnityPlugin)this).Config.Bind("Rage", "SqueezesToSnap", 12f, "Heat needed to snap. Each squeeze adds 1; heat decays HeatDecayPerSecond."); _rageDecay = ((BaseUnityPlugin)this).Config.Bind("Rage", "HeatDecayPerSecond", 1.5f, "How fast squeeze-heat bleeds off. Spam faster than this and he snaps."); _rageCaptionColor = ((BaseUnityPlugin)this).Config.Bind("Rage", "CaptionColor", "#FF3B3B", "Caption colour while angry (hex)."); _thrashAngle = ((BaseUnityPlugin)this).Config.Bind("Rage", "ThrashAngle", 38f, "How far (degrees) each shout throws him in a random direction while red. He overshoots and jitters back."); _thrashJitter = ((BaseUnityPlugin)this).Config.Bind("Rage", "ThrashJitter", 9f, "Continuous uncontrolled wobble (degrees) while he is shouting, on top of the throws."); _thrashPump = ((BaseUnityPlugin)this).Config.Bind("Rage", "ThrashPump", 14f, "Body puff on each shout - a kick into the squish spring (a click is 28)."); _provokeEnabled = ((BaseUnityPlugin)this).Config.Bind("Provoke", "Enabled", true, "Hitting a dead Bing Bong on the ground provokes him."); _provokeAngryAt = ((BaseUnityPlugin)this).Config.Bind("Provoke", "AngryAt", 3f, "Provocation points before he turns red. Each hit = 1 point."); _provokeFightAt = ((BaseUnityPlugin)this).Config.Bind("Provoke", "FightAt", 6f, "Provocation points before he comes alive and attacks (needs a modded host)."); _provokeDecay = ((BaseUnityPlugin)this).Config.Bind("Provoke", "DecayPerSecond", 0.12f, "How fast provocation cools off when you leave him alone."); _provokeSpamWeight = ((BaseUnityPlugin)this).Config.Bind("Provoke", "SpamSqueezeWeight", 1f, "Provocation points per squeeze while he is already red (Trigger B)."); _chatterInterval = ((BaseUnityPlugin)this).Config.Bind("Provoke", "FightChatterSeconds", 7f, "While he hunts you he throws a threat now and then: base seconds between lines, jittered 0.7x-1.8x (about 5-12 s), never before the previous line has finished, and every line plays once before any repeats."); _sorrySeconds = ((BaseUnityPlugin)this).Config.Bind("Provoke", "SorrySeconds", 2f, "Cooldown after you kill him: he says sorry and cannot be provoked."); _lungeSpeed = ((BaseUnityPlugin)this).Config.Bind("Provoke", "LungeSpeed", 9f, "Squeezed into a fight: he leaps out of your hands at your face at this speed (m/s)."); _idleInterval = ((BaseUnityPlugin)this).Config.Bind("Charm", "IdleMumbleSeconds", 100f, "A green Bing Bong left on the ground mumbles something sleepy about this often (+/-40%). 0 = never."); _idleVolume = ((BaseUnityPlugin)this).Config.Bind("Charm", "IdleVolume", 0.45f, "How quiet the sleepy mumbles are."); _hundredEvery = ((BaseUnityPlugin)this).Config.Bind("Charm", "HundredEvery", 100, "Every N answers you have squeezed out of any Bing Bong, he says something about it instead."); _squeezeCount = ((BaseUnityPlugin)this).Config.Bind("Stats", "AnswersSqueezed", 0, "How many answers you have squeezed out of Bing Bongs on this install. He is counting."); _beakEnabled = ((BaseUnityPlugin)this).Config.Bind("Beak", "Enabled", true, "Split his beak into two wedges that open and close like scissors while he talks."); _beakAngle = ((BaseUnityPlugin)this).Config.Bind("Beak", "MaxAngle", 22f, "How wide the beak opens (degrees per wedge)."); _beakFlip = ((BaseUnityPlugin)this).Config.Bind("Beak", "Flip", false, "If the wedges close instead of open, flip the direction."); _beakGain = ((BaseUnityPlugin)this).Config.Bind("Beak", "Gain", 2.2f, "Sensitivity to the voice. Higher = snaps open on quieter syllables."); _beakFloor = ((BaseUnityPlugin)this).Config.Bind("Beak", "Floor", 0.1f, "Loudness below this keeps the beak shut (0..1)."); _beakRelease = ((BaseUnityPlugin)this).Config.Bind("Beak", "Release", 0.07f, "Seconds to fall shut after a syllable. Opening is instant."); _beakFlutterHz = ((BaseUnityPlugin)this).Config.Bind("Beak", "FlutterHz", 24f, "The chatter: how fast the open beak vibrates."); _beakFlutter = ((BaseUnityPlugin)this).Config.Bind("Beak", "Flutter", 0.45f, "How much of the opening the chatter modulates (0 = none, 1 = slams shut each cycle)."); _bossBar = ((BaseUnityPlugin)this).Config.Bind("Music", "BossBar", true, "Show the vanilla-style boss health bar while he hunts you."); _bossBarName = ((BaseUnityPlugin)this).Config.Bind("Music", "BossBarName", "Angry Bing Bong", "The name on his boss bar."); _fightSeconds = ((BaseUnityPlugin)this).Config.Bind("Music", "FightSeconds", 75f, "How long he hunts you before he gives up and goes poof, like a boss leaving. 0 = no limit."); _fightMusic = ((BaseUnityPlugin)this).Config.Bind("Music", "FightMusic", "Mini", "Music while he hunts you: Mini (the mini-boss track), Boss (the big boss track), or None. Never plays over a real boss fight."); _groundThrashScale = ((BaseUnityPlugin)this).Config.Bind("Provoke", "GroundThrashScale", 0.4f, "On the ground he shakes lighter than in the hand: thrash multiplier when not held."); _harmony = new Harmony("howtofish.bingbong"); _harmony.PatchAll(typeof(Plugin).Assembly); ((MonoBehaviour)this).StartCoroutine(LoadClips()); BingBongBossBar.RepairVanilla(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong 1.0: spam-squeak, deferred voice, angry character (water-obsessed), FishNet sync."); } internal static bool IsBingBong(Item item) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).GetComponent() != (Object)null) { return ((Object)item).name.StartsWith("BingBong"); } return false; } internal static bool IsBingBongHeld() { Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.Holding != (Object)null) { return IsBingBong(localPlayer.Holding.HeldItem); } return false; } private void Update() { //IL_016a: Unknown result type (might be due to invalid IL or missing references) BingBongHint.Tick(); if (!_inputHooked && (Object)(object)GameInfo.Input != (Object)null) { GameInfo.Input.actions["PlayerLeftClick"].performed += OnLeftClick; _inputHooked = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: PlayerLeftClick hooked."); } if (_syncEnabled.Value) { BingBongNet.EnsureRegistered(); } BingBongBossBar.Tick(); foreach (FishShow value in _shows.Values) { UpdateSpring(value); UpdateIdle(value); if (value.SpeakAt > 0f && Time.time >= value.SpeakAt) { SpeakNow(value); } if (value.Heat > 0f) { value.Heat = Mathf.Max(0f, value.Heat - _rageDecay.Value * Time.deltaTime); } if (value.Provoke > 0f) { value.Provoke = Mathf.Max(0f, value.Provoke - _provokeDecay.Value * Time.deltaTime); } if (!value.Fighting && (Object)(object)value.Fish != (Object)null && (value.Raging || value.Heat > 0f || value.Provoke > 0f) && WaterManager.IsUnderWater(((Component)value.Fish).transform.position)) { bool raging = value.Raging; EndRage(value); value.Provoke = 0f; value.Heat = 0f; if (raging) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: dunked - back to normal."); DunkMoment(value); } } if (value.Raging && (Object)(object)value.EnableOnShiny != (Object)null && !value.EnableOnShiny.activeSelf) { SetDripLook(value, drip: true); } if (value.Fighting && InstanceFinder.IsServerStarted && value.FightEndsAt > 0f && Time.time >= value.FightEndsAt && (Object)(object)value.Fish != (Object)null && !((NetworkBehaviour)value.Fish).IsDeinitializing) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: time's up - he gives up and goes poof."); value.FightEndsAt = -1f; value.Fish.DestroyItem((byte)0, byte.MaxValue); } if (value.Fighting && InstanceFinder.IsServerStarted && (Object)(object)value.Fish != (Object)null && IsDead(value.Fish)) { Creature component = ((Component)value.Fish).GetComponent(); if ((Object)(object)component != (Object)null && !component.IsDead) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: fully cooked mid-fight - he drops dead."); component.ServerChangeHp(component.MaxHp); } } if (!value.Fighting || !InstanceFinder.IsServerStarted || !(Time.time >= value.NextChatter) || _fight.Count <= 0) { continue; } if (value.Talking) { value.NextChatter = Time.time + 0.5f; continue; } value.NextChatter = Time.time + _chatterInterval.Value * Random.Range(0.7f, 1.8f); int num = NextFromBag(value); PlayLine(value, num, Pool.Fight); if (_syncEnabled.Value) { BingBongNet.SendSpeak(num, Pool.Fight, value.Fish); } } } private void LateUpdate() { _deadKeys.Clear(); foreach (KeyValuePair show in _shows) { if ((Object)(object)show.Key == (Object)null || (Object)(object)show.Value.Root == (Object)null) { _deadKeys.Add(show.Key); continue; } UpdateLean(show.Value); UpdateBeak(show.Value); UpdateCookFx(show.Value); UpdateShrivel(show.Value); UpdateCaption(show.Value); } foreach (Item deadKey in _deadKeys) { DisposeShow(deadKey); } } private void OnLeftClick(CallbackContext ctx) { Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.BlockInputs || (Object)(object)localPlayer.Holding == (Object)null) { return; } Item heldItem = localPlayer.Holding.HeldItem; if (!IsBingBong(heldItem) || Time.unscaledTime - _lastSqueeze < _cooldown.Value) { return; } _lastSqueeze = Time.unscaledTime; Squeeze(heldItem, localPlayer.CamObject); if (_syncEnabled.Value) { BingBongNet.SendSqueeze(); } FishShow show = GetShow(heldItem); if (IsDead(heldItem)) { return; } if (_rageEnabled.Value && !show.Raging) { show.Heat += 1f; if (show.Heat >= _rageSqueezes.Value) { StartRage(show); if (_syncEnabled.Value) { BingBongNet.SendRage(on: true); } } } else if (show.Raging && _provokeEnabled.Value) { LocalProvoke(show, _provokeSpamWeight.Value, localPlayer.CamObject, react: false); } } internal void OnCorpseHit(Item fish, Player hitter) { if (_provokeEnabled.Value && !((Object)(object)hitter == (Object)null) && ((NetworkBehaviour)hitter).Owner.IsLocalClient) { FishShow show = GetShow(fish); LocalProvoke(show, 1f, FaceOf(hitter)); } } private void LocalProvoke(FishShow show, float points, Transform provoker, bool react = true) { bool num = ApplyProvoke(show, points, provoker); if (_syncEnabled.Value) { BingBongNet.SendProvoke(show.Fish, points); } if (!num && react) { Pool pool = ((!show.Raging) ? ((_hurt.Count > 0) ? Pool.Hurt : Pool.Normal) : ((_warn.Count > 0) ? Pool.Warn : Pool.Hurt)); int count = Clips(pool).Count; int num2 = ((count > 0) ? Random.Range(0, count) : (-1)); if (show.Talking) { StopTalking(show); } show.SpeakAt = -1f; PlayLine(show, num2, pool); if (_syncEnabled.Value) { BingBongNet.SendSpeak(num2, pool, show.Fish); } } } internal void RemoteProvoke(Player provoker, Item fish, float points) { if (!((Object)(object)fish == (Object)null) && IsBingBong(fish)) { ApplyProvoke(GetShow(fish), points, ((Object)(object)provoker != (Object)null) ? FaceOf(provoker) : null); } } private bool ApplyProvoke(FishShow show, float points, Transform provoker) { if ((Object)(object)show.Fish == (Object)null || show.Fighting) { return false; } if (IsDead(show.Fish)) { return false; } if (Time.time < show.SorryUntil) { return false; } ProvokeStage provokeStage = StageOf(show); show.Provoke += points; show.LastProvoke = Time.time; if ((Object)(object)provoker != (Object)null) { show.LeanTarget = provoker; } ProvokeStage provokeStage2 = StageOf(show); if (provokeStage2 != provokeStage) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("BingBong: provoke " + show.Provoke.ToString("0.0") + " -> " + provokeStage2)); } if (provokeStage2 >= ProvokeStage.Angry && !show.Raging) { StartRage(show); } if ((Object)(object)_squeak != (Object)null && (Object)(object)show.SqueakSource != (Object)null) { show.SqueakSource.PlayOneShot(_squeak, _squeakVolume.Value * MasterVolume() * Mathf.Lerp(1f, _cookSqueakMinPitch.Value, Cook01(show.Fish))); } if (provokeStage2 == ProvokeStage.Fight && provokeStage != ProvokeStage.Fight) { RequestFight(show); return true; } return false; } private ProvokeStage StageOf(FishShow show) { if (show.Provoke >= _provokeFightAt.Value) { return ProvokeStage.Fight; } if (show.Provoke >= _provokeAngryAt.Value) { return ProvokeStage.Angry; } if (show.Provoke > 0f) { return ProvokeStage.Hurt; } return ProvokeStage.Calm; } private void DunkMoment(FishShow show) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)show.Fish == (Object)null) { return; } Vector3 position = ((Component)show.Fish).transform.position; position.y = WaterManager.GetWaterHeight(position); VFXManager.Play("WaterSplash", position, Vector3.zero); AudioManager.PlayRandomClipAt("ItemHitWaterMedium_V", 1, 3, position, true, (AudioDistance)1, 1.2f, 0.1f); if (_relief.Count != 0) { if (show.Talking) { StopTalking(show); } ((MonoBehaviour)this).StartCoroutine(SpeakLater(show, 0.6f, Pool.Relief, ((NetworkBehaviour)show.Fish).ObjectId % _relief.Count)); } } private IEnumerator SpeakLater(FishShow show, float delay, Pool pool, int idx) { yield return (object)new WaitForSeconds(delay); if (!((Object)(object)show.Fish == (Object)null) && !show.Talking) { PlayLine(show, idx, pool); } } internal void OnBirdTookHim(Item fish) { if (!InstanceFinder.IsServerStarted || (Object)(object)fish == (Object)null || IsDead(fish)) { return; } FishShow show = GetShow(fish); Pool pool = ((show.Raging && _panicAngry.Count > 0) ? Pool.PanicAngry : Pool.Panic); if (Clips(pool).Count != 0) { int num = Random.Range(0, Clips(pool).Count); if (show.Talking) { StopTalking(show); } PlayLine(show, num, pool); if (_syncEnabled.Value) { BingBongNet.SendSpeak(num, pool, fish); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: a seagull took him."); } } private void UpdateIdle(FishShow show) { if (!InstanceFinder.IsServerStarted || _idle.Count == 0 || _idleInterval.Value <= 0f) { return; } Item fish = show.Fish; if ((Object)(object)fish == (Object)null || (Object)(object)fish.Holder != (Object)null || fish.IsInInventory || (Object)(object)fish.BirdHolder != (Object)null) { return; } if (show.Raging || show.Fighting || show.Talking || IsDead(fish)) { show.NextIdle = 0f; return; } Creature component = ((Component)fish).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsDead) { return; } if (show.NextIdle <= 0f) { show.NextIdle = Time.time + _idleInterval.Value * Random.Range(0.6f, 1.4f); } else if (!(Time.time < show.NextIdle)) { show.NextIdle = Time.time + _idleInterval.Value * Random.Range(0.6f, 1.4f); int num = Random.Range(0, _idle.Count); PlayLine(show, num, Pool.Idle); if (_syncEnabled.Value) { BingBongNet.SendSpeak(num, Pool.Idle, fish); } } } private bool FightTrack(out string clip, out string intro, out string outro, out float delay) { clip = (intro = (outro = "")); delay = 5f; string text = (_fightMusic.Value ?? "").Trim().ToLowerInvariant(); if (text == "boss") { clip = "BossFight1"; intro = "BossFightIntro"; outro = "BossFightOutro"; delay = 5f; return true; } if (text == "mini") { clip = "BossFightMini"; intro = "BossFightMini_Intro6s"; outro = "BossFightMini_Outro"; delay = 6f; return true; } return false; } private void FightMusicStart() { _fightsWithMusic++; if (_fightsWithMusic == 1 && !((Object)(object)BossManager.Boss != (Object)null) && FightTrack(out var clip, out var intro, out var _, out var delay)) { MusicManager.PlayMusic(clip, intro, delay, true); } } private void FightMusicStop() { _fightsWithMusic = Mathf.Max(0, _fightsWithMusic - 1); if (_fightsWithMusic == 0 && FightTrack(out var clip, out var _, out var outro, out var _)) { MusicManager.StopMusic(clip, outro); } } private int NextFromBag(FishShow show) { if (show.FightBag.Count == 0) { for (int i = 0; i < _fight.Count; i++) { show.FightBag.Add(i); } for (int num = show.FightBag.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); int value = show.FightBag[num]; show.FightBag[num] = show.FightBag[index]; show.FightBag[index] = value; } int index2 = show.FightBag.Count - 1; if (show.FightBag.Count > 1 && show.FightBag[index2] == show.LastFightIdx) { int value2 = show.FightBag[index2]; show.FightBag[index2] = show.FightBag[0]; show.FightBag[0] = value2; } } int num2 = show.FightBag[show.FightBag.Count - 1]; show.FightBag.RemoveAt(show.FightBag.Count - 1); show.LastFightIdx = num2; return num2; } private void RequestFight(FishShow show) { //IL_00af: 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_00a7: 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_00c1: 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_00ca: Unknown result type (might be due to invalid IL or missing references) if (!show.Raging) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("BingBong: fight requested on a GREEN fish - refused (Provoke " + show.Provoke.ToString("0.0") + ").")); show.Provoke = Mathf.Min(show.Provoke, _provokeAngryAt.Value - 0.01f); return; } Player localPlayer = Player.LocalPlayer; Item fish = show.Fish; if ((Object)(object)fish != (Object)null && (Object)(object)fish.Holder != (Object)null && ((NetworkBehaviour)fish.Holder).Owner.IsLocalClient) { Transform val = (((Object)(object)localPlayer != (Object)null) ? localPlayer.CamObject : null); Vector3 val2 = (((Object)(object)val != (Object)null) ? (val.forward * 0.5f) : Vector3.zero); fish.Drop(true, val2, default(Vector3)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: wriggled out of the hand - here it comes."); } if (InstanceFinder.IsServerStarted) { HostRevive(show.Fish, localPlayer); } else if (_syncEnabled.Value) { BingBongNet.SendFight(show.Fish); if (!_warnedVanillaHost) { _warnedVanillaHost = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: asked the host to revive him. If the host has no mod, nothing will happen."); } } } internal void HostRevive(Item fish, Player provoker) { //IL_0056: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (!InstanceFinder.IsServerStarted || (Object)(object)fish == (Object)null) { return; } Creature component = ((Component)fish).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsDead || ((NetworkBehaviour)fish).IsDeinitializing) { return; } Vector3 val; if ((Object)(object)fish.Holder != (Object)null && ((NetworkBehaviour)fish.Holder).Owner.IsLocalClient) { val = default(Vector3); Vector3 val2 = val; val = default(Vector3); fish.Drop(true, val2, val); } component._hp.Value = component.MaxHp; if ((Object)(object)CreatureManager.Instance != (Object)null) { CreatureManager.Instance.AddAliveCreature(component); } ReviveFixups(component); SetField(component, typeof(AttackingFish), "_target", provoker); if ((Object)(object)fish.RigidbodySync != (Object)null) { RigidbodySync rigidbodySync = fish.RigidbodySync; val = default(Vector3); rigidbodySync.StartSimulateLocal(val, default(Quaternion)); } Rigidbody component2 = ((Component)fish).GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)provoker != (Object)null && (Object)(object)provoker.Body != (Object)null && (Object)(object)provoker.Body.Head != (Object)null) { val = provoker.Body.Head.position - component2.worldCenterOfMass; Vector3 normalized = ((Vector3)(ref val)).normalized; component2.isKinematic = false; component2.linearVelocity = normalized * _lungeSpeed.Value + Vector3.up * 1.5f; } FishShow show = GetShow(fish); ApplyStageFight(show); show.FightBag.Clear(); show.NextChatter = Time.time + _chatterInterval.Value * 0.8f; if (_open.Count > 0) { int num = Random.Range(0, _open.Count); if (show.Talking) { StopTalking(show); } PlayLine(show, num, Pool.FightOpen); if (_syncEnabled.Value) { BingBongNet.SendSpeak(num, Pool.FightOpen, fish); } } if (_syncEnabled.Value) { BingBongNet.SendStage(fish, fighting: true); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("BingBong: REVIVED '" + ((Object)fish).name + "' with " + component.MaxHp + " hp - he is hunting " + (((Object)(object)provoker != (Object)null) ? ((Object)provoker).name : "nearest"))); } internal void ApplyStageFight(object showObj) { if (showObj is FishShow fishShow && !((Object)(object)fishShow.Fish == (Object)null)) { fishShow.Fighting = true; fishShow.Provoke = 0f; if (!fishShow.Raging) { StartRage(fishShow); } FightMusicStart(); fishShow.FightEndsAt = ((_fightSeconds.Value > 0f) ? (Time.time + _fightSeconds.Value) : (-1f)); if (_bossBar.Value) { BingBongBossBar.Show(fishShow.Fish, _bossBarName.Value, _fightSeconds.Value); } Creature component = ((Component)fishShow.Fish).GetComponent(); if ((Object)(object)component != (Object)null) { ReviveFixups(component); } if (fishShow.Talking) { StopTalking(fishShow); } } } private static void ReviveFixups(Creature cr) { SetField(cr, typeof(Item), "_canPickUp", false); SetField(cr, typeof(Creature), "_localIsDead", false); (typeof(Creature).GetField("_deadCreatures", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as HashSet)?.Remove(cr); typeof(Creature).GetMethod("SetSleepThreshold", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(cr, new object[1] { false }); } private static void SetField(object target, Type declaring, string name, object value) { FieldInfo field = declaring.GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); if (field != null && declaring.IsInstanceOfType(target)) { field.SetValue(target, value); } } internal void OnFishDeath(Item fish) { if (_shows.TryGetValue(fish, out var value) && value.Fighting) { value.Fighting = false; value.Provoke = 0f; value.Heat = 0f; EndRage(value); FightMusicStop(); BingBongBossBar.Hide(); if (value.Talking) { StopTalking(value); } value.SorryUntil = Time.time + _sorrySeconds.Value; if (IsDead(fish)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: burnt out - no apology, nothing left in him."); return; } ((MonoBehaviour)this).StartCoroutine(SaySorry(value)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BingBong: he surrenders."); } } private IEnumerator SaySorry(FishShow show) { yield return (object)new WaitForSeconds(0.45f); if (!((Object)(object)show.Fish == (Object)null) && _sorry.Count != 0) { PlayLine(show, ((NetworkBehaviour)show.Fish).ObjectId % _sorry.Count, Pool.Sorry); } } private void StartRage(FishShow show) { if (!show.Raging && !((Object)(object)show.Fish == (Object)null) && !IsDead(show.Fish)) { show.Raging = true; show.Heat = 0f; SetDripLook(show, drip: true); if (show.Talking) { StopTalking(show); } } } private void EndRage(FishShow show) { if (show.Raging) { show.Raging = false; Creature val = (((Object)(object)show.Fish != (Object)null) ? ((Component)show.Fish).GetComponent() : null); SetDripLook(show, (Object)(object)val != (Object)null && val.IsDrip); } } private void SetDripLook(FishShow show, bool drip) { if ((Object)(object)show.EnableOnShiny == (Object)null || (Object)(object)show.DisableOnShiny == (Object)null) { Creature val = (((Object)(object)show.Fish != (Object)null) ? ((Component)show.Fish).GetComponent() : null); if ((Object)(object)val == (Object)null) { return; } ref GameObject enableOnShiny = ref show.EnableOnShiny; object? obj = typeof(Creature).GetField("_enableOnShiny", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val); enableOnShiny = (GameObject)((obj is GameObject) ? obj : null); ref GameObject disableOnShiny = ref show.DisableOnShiny; object? obj2 = typeof(Creature).GetField("_disableOnShiny", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val); disableOnShiny = (GameObject)((obj2 is GameObject) ? obj2 : null); if ((Object)(object)show.EnableOnShiny == (Object)null || (Object)(object)show.DisableOnShiny == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"BingBong: shiny toggles not found - no shape-shift."); return; } } show.EnableOnShiny.SetActive(drip); show.DisableOnShiny.SetActive(!drip); } internal void RemoteRage(Player squeezer, bool on) { Item val = ResolveFish(squeezer); if (!((Object)(object)val == (Object)null)) { FishShow show = GetShow(val); if (on) { StartRage(show); } else { EndRage(show); } } } internal void RemoteSqueeze(Player squeezer) { Item val = ResolveFish(squeezer); if (!((Object)(object)val == (Object)null)) { Squeeze(val, FaceOf(squeezer)); } } internal void RemoteSpeak(Player squeezer, Item fishById, int lineIdx, Pool pool) { Item val = (((Object)(object)fishById != (Object)null) ? fishById : ResolveFish(squeezer)); if (!((Object)(object)val == (Object)null)) { FishShow show = GetShow(val); show.LeanTarget = FaceOf(squeezer); show.SpeakAt = -1f; if (show.Talking) { StopTalking(show); } if (Clips(pool).Count == 0) { pool = Pool.Normal; } PlayLine(show, lineIdx, pool); } } internal Item FindShownFish(int objectId) { foreach (KeyValuePair show in _shows) { if ((Object)(object)show.Key != (Object)null && ((NetworkBehaviour)show.Key).ObjectId == objectId) { return show.Key; } } return null; } internal object ShowFor(Item fish) { return GetShow(fish); } private static Item ResolveFish(Player squeezer) { if ((Object)(object)squeezer == (Object)null || (Object)(object)squeezer.Holding == (Object)null) { return null; } Item heldItem = squeezer.Holding.HeldItem; if (!IsBingBong(heldItem)) { return null; } return heldItem; } private static Transform FaceOf(Player p) { if (!((Object)(object)p.Body != (Object)null) || !((Object)(object)p.Body.Head != (Object)null)) { return ((Component)p).transform; } return p.Body.Head; } private FishShow GetShow(Item fish) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if (_shows.TryGetValue(fish, out var value)) { return value; } FishShow fishShow = new FishShow { Fish = fish, Root = ((Component)fish).transform, RestScale = ((Component)fish).transform.localScale }; GameObject val = new GameObject("YakariBingBongVoice"); val.transform.SetParent(((Component)fish).transform, false); val.transform.localPosition = Vector3.zero; GameObject val2 = new GameObject("Voice"); val2.transform.SetParent(val.transform, false); fishShow.SqueakSource = val.AddComponent(); fishShow.VoiceSource = val2.AddComponent(); AudioSource[] array = (AudioSource[])(object)new AudioSource[2] { fishShow.SqueakSource, fishShow.VoiceSource }; foreach (AudioSource obj in array) { obj.playOnAwake = false; obj.spatialBlend = 1f; CopyGameSourceSettings(obj); } fishShow.LowPass = val2.AddComponent(); fishShow.LowPass.cutoffFrequency = 22000f; fishShow.Distortion = val2.AddComponent(); fishShow.Distortion.distortionLevel = 0f; fishShow.WobbleSeed = Random.value * 100f; _shows[fish] = fishShow; TryBuildBeak(fishShow); Creature component = ((Component)fish).GetComponent(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("BingBong: PROBE type=" + (((Object)(object)component != (Object)null) ? ((object)component).GetType().FullName : "null") + " maxHp=" + (((Object)(object)component != (Object)null) ? component.MaxHp.ToString() : "?") + " hp=" + (((Object)(object)component != (Object)null) ? component.Hp.ToString() : "?") + " dead=" + ((Object)(object)component != (Object)null && component.IsDead) + " comps=" + string.Join(",", Array.ConvertAll(((Component)fish).GetComponents(), (Component c) => ((object)c).GetType().Name)))); return fishShow; } private void Squeeze(Item fish, Transform leanTarget) { FishShow show = GetShow(fish); show.LeanTarget = leanTarget; show.SpringActive = true; show.V += 28f; if ((Object)(object)_squeak != (Object)null && (Object)(object)show.SqueakSource != (Object)null) { float num = Cook01(fish); show.SqueakSource.pitch = Mathf.Lerp(1f, _cookSqueakMinPitch.Value, num); show.SqueakSource.PlayOneShot(_squeak, _squeakVolume.Value * MasterVolume() * Mathf.Lerp(1f, 0.5f, num)); } if (show.Talking) { StopTalking(show); } show.SpeakAt = Time.time + _settleDelay.Value; } private void SpeakNow(FishShow show) { show.SpeakAt = -1f; if ((Object)(object)show.Fish == (Object)null || (Object)(object)show.VoiceSource == (Object)null) { return; } Pool pool = ((show.Raging && _angry.Count > 0) ? Pool.Angry : Pool.Normal); if (pool == Pool.Normal) { _squeezeCount.Value += 1; if (_hundred.Count > 0 && _hundredEvery.Value > 0 && _squeezeCount.Value % _hundredEvery.Value == 0) { pool = Pool.Hundred; ((BaseUnityPlugin)this).Logger.LogInfo((object)("BingBong: answer #" + _squeezeCount.Value + " - he has something to say about that.")); } } int count = Clips(pool).Count; int num = ((count > 0) ? Random.Range(0, count) : (-1)); PlayLine(show, num, pool); if (_syncEnabled.Value) { BingBongNet.SendSpeak(num, pool, show.Fish); } } private void PlayLine(FishShow show, int lineIdx, Pool pool = Pool.Normal) { List list = Clips(pool); List list2 = Envs(pool); if (lineIdx >= 0 && lineIdx < list.Count) { show.TalkClip = list[lineIdx]; show.TalkEnv = list2[lineIdx]; } else { show.TalkClip = _clip; show.TalkEnv = _envelope; } show.TalkPool = pool; if ((Object)(object)show.TalkClip == (Object)null || (Object)(object)show.VoiceSource == (Object)null) { return; } float num = Cook01(show.Fish); if (!IsDead(show.Fish)) { show.Cook = num; show.BasePitch = Mathf.Lerp(1f, _cookMinPitch.Value, num); bool flag = show.Raging && show.TalkPool != Pool.Angry; if (flag) { show.BasePitch *= 0.85f; } show.VoiceSource.clip = show.TalkClip; show.VoiceSource.pitch = show.BasePitch; show.VoiceSource.mute = false; show.VoiceSource.volume = _volume.Value * MasterVolume() * Mathf.Lerp(1f, _cookMinVolume.Value, num) * (flag ? 1.25f : 1f) * ((pool == Pool.Idle) ? _idleVolume.Value : 1f); if ((Object)(object)show.LowPass != (Object)null) { show.LowPass.cutoffFrequency = Mathf.Exp(Mathf.Lerp(Mathf.Log(22000f), Mathf.Log(Mathf.Max(200f, _cookLowPass.Value)), num)); } if ((Object)(object)show.Distortion != (Object)null) { show.Distortion.distortionLevel = Mathf.Lerp(0f, _cookDistortion.Value, num); } show.DropoutUntil = -1f; show.NextDropoutRoll = Time.time; show.VoiceSource.Play(); show.Talking = true; show.CookLean = (1f - num * 0.7f) * (show.Raging ? 1.5f : 1f); BeginLean(show); ShowCaption(show, lineIdx); } } private void UpdateCookFx(FishShow show) { if (!show.Talking || (Object)(object)show.VoiceSource == (Object)null || show.Cook <= 0f) { return; } float cook = show.Cook; float time = Time.time; float num = _cookWobble.Value * cook; float num2 = Mathf.Sin(time * 1.7f + show.WobbleSeed); float num3 = Mathf.PerlinNoise(time * 9f, show.WobbleSeed) * 2f - 1f; show.VoiceSource.pitch = show.BasePitch * (1f + num * (0.65f * num2 + 0.35f * num3)); if (time < show.DropoutUntil) { show.VoiceSource.mute = true; return; } show.VoiceSource.mute = false; if (time >= show.NextDropoutRoll) { show.NextDropoutRoll = time + 0.05f; float num4 = _cookDropouts.Value * cook * cook; if (Random.value < num4 * 0.05f) { show.DropoutUntil = time + Random.Range(0.02f, 0.06f); } } } private void UpdateShrivel(FishShow show) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)show.Root == (Object)null)) { float num = 1f - _cookShrivel.Value * Cook01(show.Fish); show.Shrivel = Mathf.Lerp(show.Shrivel, num, Time.deltaTime * 3f); if (!show.SpringActive && Mathf.Abs(show.Shrivel - 1f) > 0.0005f) { show.Root.localScale = show.RestScale * show.Shrivel; } } } private float Cook01(Item fish) { if (!_cookEnabled.Value || (Object)(object)fish == (Object)null) { return 0f; } float num = Mathf.Clamp(fish.Cookness, 0f, 2f); if (!(num <= 1f)) { return 0.6f + (num - 1f) * 0.4f; } return num * 0.6f; } private bool IsDead(Item fish) { if (_cookEnabled.Value && (Object)(object)fish != (Object)null) { return fish.Cookness >= _cookDeadAt.Value; } return false; } private void StopTalking(FishShow show) { if ((Object)(object)show.VoiceSource != (Object)null) { show.VoiceSource.Stop(); show.VoiceSource.mute = false; } show.Talking = false; EndLean(show); HideCaption(show); } private void ShowCaption(FishShow show, int lineIdx) { //IL_00cd: 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) HideCaption(show); if (!_captionEnabled.Value || (Object)(object)GameInfo.CurCamera == (Object)null || (Object)(object)GameInfo.WorldTextPrefab == (Object)null) { return; } List list = Caps(show.TalkPool); string text = ((lineIdx >= 0 && lineIdx < list.Count) ? list[lineIdx] : "Bing bong!"); if (!string.IsNullOrEmpty(text)) { if (_cookGlitchText.Value) { text = Glitch(text, Cook01(show.Fish)); } if (show.Raging) { text = "" + text.ToUpperInvariant() + ""; } show.Caption = Object.Instantiate(GameInfo.WorldTextPrefab, CaptionAnchor(show), Quaternion.identity); show.Caption.SetText(Wrap(text, _captionWrap.Value), _captionSize.Value); show.Caption.ScaleAnimation(true); } } private static string Glitch(string text, float cook) { if (cook < 0.15f || string.IsNullOrEmpty(text)) { return text; } string[] array = text.Split(' '); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < array.Length; i++) { string text2 = array[i]; if (text2.Length > 2 && Random.value < cook * 0.7f) { text2 = text2[0] + "-" + text2; } if (cook > 0.5f) { StringBuilder stringBuilder2 = new StringBuilder(); string text3 = text2; foreach (char c in text3) { stringBuilder2.Append((char.IsLetter(c) && Random.value < (cook - 0.5f) * 0.6f) ? '-' : c); } text2 = stringBuilder2.ToString(); } if (i > 0) { stringBuilder.Append(' '); } stringBuilder.Append(text2); } if (cook > 0.35f && Random.value < cook) { stringBuilder.Append("..."); } return stringBuilder.ToString(); } private static string Wrap(string text, int maxChars) { if (maxChars <= 0 || text.Length <= maxChars) { return text; } int num = text.Length / 2; int num2 = -1; for (int i = 0; i < text.Length; i++) { if (text[i] == ' ' && (num2 < 0 || Mathf.Abs(i - num) < Mathf.Abs(num2 - num))) { num2 = i; } } if (num2 >= 0) { return text.Substring(0, num2) + "\n" + text.Substring(num2 + 1); } return text; } private void HideCaption(FishShow show) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)show.Caption == (Object)null)) { GameObject gameObject = ((Component)show.Caption).gameObject; show.Caption = null; LeanTween.cancel(gameObject); LeanTween.scale(gameObject, Vector3.zero, 0.12f).setEase((LeanTweenType)26).setDestroyOnComplete(true); } } private void UpdateCaption(FishShow show) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)show.Caption == (Object)null)) { if (!show.Talking) { HideCaption(show); } else { ((Component)show.Caption).transform.position = CaptionAnchor(show); } } } private Vector3 CaptionAnchor(FishShow show) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Bounds val = default(Bounds); Renderer[] componentsInChildren = ((Component)show.Fish).GetComponentsInChildren(); foreach (Renderer val2 in componentsInChildren) { if (val2.enabled && ((Component)val2).gameObject.activeInHierarchy) { if (!flag) { val = val2.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(val2.bounds); } } } if (!flag) { return ((Component)show.Fish).transform.position + Vector3.up * 0.3f; } return new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).max.y + _captionHeight.Value, ((Bounds)(ref val)).center.z); } private void UpdateSpring(FishShow show) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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_013b: 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_00c4: Unknown result type (might be due to invalid IL or missing references) if (show.SpringActive && !((Object)(object)show.Root == (Object)null)) { float num = Mathf.Min(Time.deltaTime, 1f / 30f); float num2 = (0f - _springK.Value) * show.S - _springDamp.Value * show.V; show.V += num2 * num; show.S += show.V * num; show.S = Mathf.Clamp(show.S, -0.3f, 0.9f); if (Mathf.Abs(show.S) < 0.002f && Mathf.Abs(show.V) < 0.02f) { show.Root.localScale = show.RestScale * show.Shrivel; show.SpringActive = false; show.S = 0f; show.V = 0f; } else { float num3 = 1f - show.S * _squashAmount.Value; float num4 = 1f / Mathf.Sqrt(Mathf.Max(0.2f, num3)); show.Root.localScale = Vector3.Scale(show.RestScale * show.Shrivel, new Vector3(num3, num4, num4)); } } } private void BeginLean(FishShow show) { //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) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (_leanAmount.Value <= 0f || show.TalkEnv == null) { return; } SkinnedMeshRenderer componentInChildren = ((Component)show.Fish).GetComponentInChildren(false); if ((Object)(object)componentInChildren == (Object)null) { return; } Transform val = componentInChildren.rootBone; if ((Object)(object)val == (Object)null && componentInChildren.bones != null && componentInChildren.bones.Length != 0) { val = componentInChildren.bones[0]; } if ((Object)(object)val == (Object)null) { return; } if (!show.Talking || (Object)(object)show.ShakeBone != (Object)(object)val) { if ((Object)(object)show.ShakeBone != (Object)null) { show.ShakeBone.localRotation = show.ShakeRest; } show.ShakeBone = val; show.ShakeRest = val.localRotation; } show.Open = 0f; } private void UpdateLean(FishShow show) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!show.Talking || (Object)(object)show.ShakeBone == (Object)null) { return; } AudioSource voiceSource = show.VoiceSource; if ((Object)(object)voiceSource == (Object)null || !voiceSource.isPlaying || show.TalkEnv == null) { show.Talking = false; EndLean(show); return; } int num = Mathf.Clamp((int)(voiceSource.time / Mathf.Max(0.001f, show.TalkClip.length) * (float)show.TalkEnv.Length), 0, show.TalkEnv.Length - 1); show.Open = Mathf.Lerp(show.Open, show.TalkEnv[num], Time.deltaTime * 14f); Transform val = show.LeanTarget; if ((Object)(object)val == (Object)null) { Player localPlayer = Player.LocalPlayer; val = (((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.CamObject != (Object)null) ? localPlayer.CamObject : (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null)); if ((Object)(object)val == (Object)null) { return; } } Vector3 val2 = val.position - show.ShakeBone.position; val2.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f)) { Vector3 val3 = Vector3.Cross(Vector3.up, ((Vector3)(ref val2)).normalized); Quaternion val4 = Quaternion.AngleAxis(show.Open * _leanAmount.Value * show.CookLean, val3); Quaternion val5 = (show.Raging ? UpdateThrash(show) : Quaternion.identity); show.ShakeBone.rotation = val5 * val4 * show.ShakeBone.parent.rotation * show.ShakeRest; } } private Quaternion UpdateThrash(FishShow show) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: 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_020f: 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_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: 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_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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(Time.deltaTime, 1f / 30f); if (show.Open < 0.35f) { show.AttackArmed = true; } if (show.AttackArmed && show.Open > 0.55f) { show.AttackArmed = false; Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 normalized = ((Vector2)(ref insideUnitCircle)).normalized; float num2 = Random.Range(-0.6f, 0.6f); show.JerkTarget = new Vector3(normalized.y, num2, normalized.x) * _thrashAngle.Value * Mathf.Clamp01(show.Open + 0.3f); show.SpringActive = true; show.V -= _thrashPump.Value; } show.JerkTarget = Vector3.Lerp(show.JerkTarget, Vector3.zero, num * 6f); Vector3 val = -420f * (show.Jerk - show.JerkTarget) - 13f * show.JerkVel; show.JerkVel += val * num; show.Jerk += show.JerkVel * num; float num3 = Time.time * 12f; Vector3 val2 = new Vector3(Mathf.PerlinNoise(num3, show.WobbleSeed) - 0.5f, Mathf.PerlinNoise(num3, show.WobbleSeed + 7f) - 0.5f, Mathf.PerlinNoise(num3, show.WobbleSeed + 13f) - 0.5f) * (2f * _thrashJitter.Value * show.Open); Vector3 val3 = show.Jerk + val2; if ((Object)(object)show.Fish != (Object)null && (Object)(object)show.Fish.Holder == (Object)null) { val3 *= _groundThrashScale.Value; } return Quaternion.AngleAxis(val3.x, Vector3.right) * Quaternion.AngleAxis(val3.y, Vector3.up) * Quaternion.AngleAxis(val3.z, Vector3.forward); } private void TryBuildBeak(FishShow show) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (_beakEnabled.Value && !((Object)(object)show.Fish == (Object)null) && EnsureShakeBone(show)) { show.ShakeBone.localRotation = show.ShakeRest; show.Beak = new BingBongBeak(show.Fish); if (!show.Beak.Build(show.ShakeBone)) { show.Beak = null; } } } private void UpdateBeak(FishShow show) { if ((Object)(object)show.Fish == (Object)null) { return; } if (show.Beak != null && show.Beak.SourceChanged()) { show.Beak.Dispose(); TryBuildBeak(show); } if (show.Beak != null && show.Beak.Built) { float num = 0f; float num2 = 0f; AudioSource voiceSource = show.VoiceSource; if (show.Talking && (Object)(object)voiceSource != (Object)null && voiceSource.isPlaying && show.TalkEnv != null && (Object)(object)show.TalkClip != (Object)null) { num2 = voiceSource.time; int num3 = Mathf.Clamp((int)(num2 / Mathf.Max(0.001f, show.TalkClip.length) * (float)show.TalkEnv.Length), 0, show.TalkEnv.Length - 1); float num4 = Mathf.Clamp(_beakFloor.Value, 0f, 0.9f); num = Mathf.Clamp01((show.TalkEnv[num3] - num4) / (1f - num4) * _beakGain.Value); } if (num >= show.BeakOpen) { show.BeakOpen = num; } else { show.BeakOpen = Mathf.MoveTowards(show.BeakOpen, num, Time.deltaTime / Mathf.Max(0.01f, _beakRelease.Value)); } float num5 = show.BeakOpen; if (num5 > 0.05f && _beakFlutter.Value > 0f) { float num6 = 0.5f + 0.5f * Mathf.Sin(num2 * _beakFlutterHz.Value * (MathF.PI * 2f)); num5 *= 1f - _beakFlutter.Value * num6; } show.Beak.SetOpen(num5, _beakAngle.Value, _beakFlip.Value); } } private bool EnsureShakeBone(FishShow show) { //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) if ((Object)(object)show.ShakeBone != (Object)null) { return true; } SkinnedMeshRenderer componentInChildren = ((Component)show.Fish).GetComponentInChildren(false); if ((Object)(object)componentInChildren == (Object)null) { return false; } Transform val = componentInChildren.rootBone; if ((Object)(object)val == (Object)null && componentInChildren.bones != null && componentInChildren.bones.Length != 0) { val = componentInChildren.bones[0]; } if ((Object)(object)val == (Object)null) { return false; } show.ShakeBone = val; show.ShakeRest = val.localRotation; return true; } private static void EndLean(FishShow show) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)show.ShakeBone != (Object)null) { show.ShakeBone.localRotation = show.ShakeRest; } show.Jerk = (show.JerkTarget = (show.JerkVel = Vector3.zero)); show.AttackArmed = true; } private void DisposeShow(Item key) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (_shows.TryGetValue(key, out var value)) { if ((Object)(object)value.Root != (Object)null) { value.Root.localScale = value.RestScale; } if (value.Beak != null) { value.Beak.Dispose(); value.Beak = null; } EndLean(value); if (value.Fighting) { value.Fighting = false; FightMusicStop(); BingBongBossBar.Hide(); } EndRage(value); if ((Object)(object)value.Caption != (Object)null) { LeanTween.cancel(((Component)value.Caption).gameObject); Object.Destroy((Object)(object)((Component)value.Caption).gameObject); value.Caption = null; } if ((Object)(object)value.SqueakSource != (Object)null) { Object.Destroy((Object)(object)((Component)value.SqueakSource).gameObject); } _shows.Remove(key); } } private IEnumerator LoadClips() { yield return LoadOne(_clipFile.Value, delegate(AudioClip c) { _clip = c; _envelope = BuildEnvelope(c); }); yield return LoadOne(_squeakFile.Value, delegate(AudioClip c) { _squeak = c; }); yield return LoadPool("lines", _lines, _lineEnvs, _lineCaptions); yield return LoadPool("lines-angry", _angry, _angryEnvs, _angryCaptions); yield return LoadPool("lines-hurt", _hurt, _hurtEnvs, _hurtCaptions); yield return LoadPool("lines-fight", _fight, _fightEnvs, _fightCaptions); yield return LoadPool("lines-sorry", _sorry, _sorryEnvs, _sorryCaptions); yield return LoadPool("lines-warn", _warn, _warnEnvs, _warnCaptions); yield return LoadPool("lines-fight-open", _open, _openEnvs, _openCaptions); yield return LoadPool("lines-relief", _relief, _reliefEnvs, _reliefCaptions); yield return LoadPool("lines-panic", _panic, _panicEnvs, _panicCaptions); yield return LoadPool("lines-idle", _idle, _idleEnvs, _idleCaptions); yield return LoadPool("lines-hundred", _hundred, _hundredEnvs, _hundredCaptions); yield return LoadPool("lines-panic-angry", _panicAngry, _panicAngryEnvs, _panicAngryCaptions); ((BaseUnityPlugin)this).Logger.LogInfo((object)("BingBong: pools - answers " + _lines.Count + ", angry " + _angry.Count + ", hurt " + _hurt.Count + ", warn " + _warn.Count + ", open " + _open.Count + ", fight " + _fight.Count + ", sorry " + _sorry.Count + ", relief " + _relief.Count + ", panic " + _panic.Count + "/" + _panicAngry.Count + " angry, idle " + _idle.Count + ", hundred " + _hundred.Count + ".")); } private IEnumerator LoadPool(string sub, List clips, List envs, List caps) { string text = Path.Combine(AssetDir, sub); if (!Directory.Exists(text)) { yield break; } Dictionary captions = new Dictionary(StringComparer.OrdinalIgnoreCase); string path = Path.Combine(text, "captions.txt"); if (File.Exists(path)) { string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); int num = text2.IndexOf('='); if (text2.Length != 0 && text2[0] != '#' && num > 0) { captions[text2.Substring(0, num).Trim()] = text2.Substring(num + 1).Trim(); } } } string[] files = Directory.GetFiles(text, "line*.wav"); Array.Sort(files, (IComparer?)StringComparer.OrdinalIgnoreCase); string[] array2 = files; foreach (string path2 in array2) { string key = Path.GetFileNameWithoutExtension(path2); yield return LoadOne(Path.Combine(sub, Path.GetFileName(path2)), delegate(AudioClip c) { clips.Add(c); envs.Add(BuildEnvelope(c)); caps.Add(captions.TryGetValue(key, out var value) ? value : ""); }); } int num2 = 0; foreach (string cap in caps) { if (cap == "") { num2++; } } if (num2 > 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("BingBong: " + num2 + " line(s) in " + sub + " have no caption.")); } } private IEnumerator LoadOne(string file, Action assign) { string text = Path.Combine(AssetDir, file); string text2 = Path.ChangeExtension(text, ".wav"); if (text.EndsWith(".mp3") && File.Exists(text2)) { text = text2; } if (!File.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)("BingBong: clip not found: " + text)); yield break; } AudioType val = (AudioType)(text.EndsWith(".wav") ? 20 : 13); UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(new Uri(text).AbsoluteUri, val); try { yield return req.SendWebRequest(); if ((int)req.result != 1) { ((BaseUnityPlugin)this).Logger.LogError((object)("BingBong: clip load failed (" + file + "): " + req.error)); yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(req); ((Object)content).name = "YakariBingBong_" + file; assign(content); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"BingBong: loaded '{file}' ({content.length:0.00}s)"); } finally { ((IDisposable)req)?.Dispose(); } } private float[] BuildEnvelope(AudioClip clip) { float[] array = new float[clip.samples * clip.channels]; if (!clip.GetData(array, 0)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"BingBong: GetData failed - no lean sync."); return null; } int num = Mathf.Max(1, (int)((float)clip.frequency * 0.033f) * clip.channels); int num2 = Mathf.Max(1, array.Length / num); float[] array2 = new float[num2]; float num3 = 0.0001f; for (int i = 0; i < num2; i++) { float num4 = 0f; int num5 = Mathf.Min(array.Length, (i + 1) * num); for (int j = i * num; j < num5; j++) { float num6 = Mathf.Abs(array[j]); if (num6 > num4) { num4 = num6; } } array2[i] = num4; if (num4 > num3) { num3 = num4; } } for (int k = 0; k < num2; k++) { array2[k] = Mathf.Pow(Mathf.Clamp01(array2[k] / num3), 0.6f); } return array2; } private static bool CopyGameSourceSettings(AudioSource dst) { //IL_005e: 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_00fb: 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_010b: Unknown result type (might be due to invalid IL or missing references) FieldInfo field = typeof(AudioManager).GetField("_worldSources", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); List list = ((field != null) ? (field.GetValue(null) as List) : null); AudioSource val = ((list != null && list.Count > 0) ? list[0] : null); if ((Object)(object)val != (Object)null) { dst.outputAudioMixerGroup = val.outputAudioMixerGroup; dst.rolloffMode = val.rolloffMode; dst.dopplerLevel = val.dopplerLevel; dst.spread = val.spread; dst.spatialBlend = val.spatialBlend; } object? obj = typeof(AudioManager).GetField("_instance", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null); AudioManager val2 = (AudioManager)((obj is AudioManager) ? obj : null); if ((Object)(object)val2 == (Object)null) { return (Object)(object)val != (Object)null; } if (typeof(AudioManager).GetField("_shortMinMax", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(val2) is Vector2 val3) { dst.minDistance = val3.x; dst.maxDistance = val3.y; } if (typeof(AudioManager).GetField("_shortPriority", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(val2) is int priority) { dst.priority = priority; } return true; } private static float MasterVolume() { object? obj = typeof(AudioManager).GetField("_instance", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null); AudioManager val = (AudioManager)((obj is AudioManager) ? obj : null); object obj2 = ((!((Object)(object)val != (Object)null)) ? null : typeof(AudioManager).GetField("_volume", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(val)); if (obj2 is float) { return (float)obj2; } return 0.5f; } private void OnDestroy() { if (_inputHooked && (Object)(object)GameInfo.Input != (Object)null) { GameInfo.Input.actions["PlayerLeftClick"].performed -= OnLeftClick; } BingBongNet.Unregister(); BingBongBossBar.DestroyAll(); BingBongBeak.ReleasePalette(); if (_fightsWithMusic > 0) { _fightsWithMusic = 0; if (FightTrack(out var clip, out var _, out var outro, out var _)) { MusicManager.StopMusic(clip, outro); } } _deadKeys.Clear(); foreach (Item key in _shows.Keys) { _deadKeys.Add(key); } foreach (Item deadKey in _deadKeys) { DisposeShow(deadKey); } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; if ((Object)(object)_clip != (Object)null) { Object.Destroy((Object)(object)_clip); _clip = null; } if ((Object)(object)_squeak != (Object)null) { Object.Destroy((Object)(object)_squeak); _squeak = null; } foreach (AudioClip line in _lines) { if ((Object)(object)line != (Object)null) { Object.Destroy((Object)(object)line); } } foreach (AudioClip item in _angry) { if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)item); } } foreach (AudioClip item2 in _hurt) { if ((Object)(object)item2 != (Object)null) { Object.Destroy((Object)(object)item2); } } foreach (AudioClip item3 in _fight) { if ((Object)(object)item3 != (Object)null) { Object.Destroy((Object)(object)item3); } } foreach (AudioClip item4 in _sorry) { if ((Object)(object)item4 != (Object)null) { Object.Destroy((Object)(object)item4); } } foreach (AudioClip item5 in _warn) { if ((Object)(object)item5 != (Object)null) { Object.Destroy((Object)(object)item5); } } foreach (AudioClip item6 in _open) { if ((Object)(object)item6 != (Object)null) { Object.Destroy((Object)(object)item6); } } foreach (AudioClip item7 in _relief) { if ((Object)(object)item7 != (Object)null) { Object.Destroy((Object)(object)item7); } } foreach (AudioClip item8 in _panic) { if ((Object)(object)item8 != (Object)null) { Object.Destroy((Object)(object)item8); } } foreach (AudioClip item9 in _idle) { if ((Object)(object)item9 != (Object)null) { Object.Destroy((Object)(object)item9); } } foreach (AudioClip item10 in _hundred) { if ((Object)(object)item10 != (Object)null) { Object.Destroy((Object)(object)item10); } } foreach (AudioClip item11 in _panicAngry) { if ((Object)(object)item11 != (Object)null) { Object.Destroy((Object)(object)item11); } } _panicAngry.Clear(); _panicAngryEnvs.Clear(); _panicAngryCaptions.Clear(); _warn.Clear(); _warnEnvs.Clear(); _warnCaptions.Clear(); _open.Clear(); _openEnvs.Clear(); _openCaptions.Clear(); _relief.Clear(); _reliefEnvs.Clear(); _reliefCaptions.Clear(); _panic.Clear(); _panicEnvs.Clear(); _panicCaptions.Clear(); _idle.Clear(); _idleEnvs.Clear(); _idleCaptions.Clear(); _hundred.Clear(); _hundredEnvs.Clear(); _hundredCaptions.Clear(); _lines.Clear(); _lineEnvs.Clear(); _lineCaptions.Clear(); _angry.Clear(); _angryEnvs.Clear(); _angryCaptions.Clear(); _hurt.Clear(); _hurtEnvs.Clear(); _hurtCaptions.Clear(); _fight.Clear(); _fightEnvs.Clear(); _fightCaptions.Clear(); _sorry.Clear(); _sorryEnvs.Clear(); _sorryCaptions.Clear(); Instance = null; LogSrc = null; } } [HarmonyPatch(typeof(ItemUI), "ShowSpecificItemInfo", new Type[] { typeof(Item) })] internal static class BingBongHint { private const string Lmb = ""; internal const string Text = "Ask & Squeeze ()"; private static TextMeshProUGUI _text; private static bool Prefix(ItemUI __instance, Item item) { //IL_008f: 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) if (!Plugin.IsBingBong(item)) { return true; } Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.Holding == (Object)null || (Object)(object)localPlayer.Holding.HeldItem != (Object)(object)item) { return false; } object? obj = AccessTools.Field(typeof(ItemUI), "_itemInfoText")?.GetValue(__instance); _text = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null); if ((Object)(object)_text == (Object)null) { return true; } ((TMP_Text)_text).text = "Ask & Squeeze ()"; ((TMP_Text)_text).transform.localScale = Vector3.zero; LeanTween.cancel(((Component)_text).gameObject); LeanTween.scale(((Component)_text).gameObject, Vector3.one, 0.25f).setEase((LeanTweenType)27); return false; } internal static void Tick() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_text == (Object)null) && !(((TMP_Text)_text).text != "Ask & Squeeze ()") && !Plugin.IsBingBongHeld()) { ((TMP_Text)_text).text = ""; ((TMP_Text)_text).transform.localScale = Vector3.zero; } } } [HarmonyPatch(typeof(PlayerEating), "StartEating")] internal static class BlockEatingBingBong { private static bool Prefix() { return !Plugin.IsBingBongHeld(); } } [HarmonyPatch(typeof(Item), "TryCaughtByBird")] internal static class SeagullTookBingBong { private static void Postfix(Item __instance, bool __result) { if (__result && !((Object)(object)__instance == (Object)null) && Plugin.IsBingBong(__instance)) { Plugin.Instance?.OnBirdTookHim(__instance); } } } [HarmonyPatch(typeof(Creature), "OnDeath")] internal static class FightOverOnDeath { private static void Postfix(Creature __instance) { if (!((Object)(object)__instance == (Object)null) && Plugin.IsBingBong((Item)(object)__instance)) { Plugin.Instance?.OnFishDeath((Item)(object)__instance); } } } [HarmonyPatch(typeof(Creature), "LocalHit")] internal static class ProvokeOnCorpseHit { private static void Postfix(Creature __instance, Player player) { if (!((Object)(object)__instance == (Object)null) && __instance.IsDead && !((NetworkBehaviour)__instance).IsDeinitializing && Plugin.IsBingBong((Item)(object)__instance)) { Plugin.Instance?.OnCorpseHit((Item)(object)__instance, player); } } }