Decompiled source of TalkingBingBong v1.0.0
plugins/BingBong/HowToFish.BingBong.dll
Decompiled 17 hours ago
The result has been truncated due to the large size, download it to view full contents!
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<Mesh> _meshes = new List<Mesh>(); 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<SkinnedMeshRenderer>(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<int> list = new List<int>(); List<int> list2 = new List<int>(); List<float> list3 = new List<float>(); 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<float> list4 = new List<float>(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<int> list5 = new List<int>(); List<int> list6 = new List<int>(); 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<int> 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<int, int> dictionary = new Dictionary<int, int>(); List<int> list = new List<int>(triStarts.Count * 3); List<Vector3> list2 = new List<Vector3>(); List<Vector3> list3 = new List<Vector3>(); List<List<Vector4>> list4 = new List<List<Vector4>>(); List<List<Vector4>> list5 = new List<List<Vector4>>(); for (int i = 0; i < 8; i++) { List<Vector4> list6 = new List<Vector4>(); src.GetUVs(i, list6); list5.Add((list6.Count == v.Length) ? list6 : null); list4.Add(new List<Vector4>()); } Color[] colors = src.colors; bool flag = colors != null && colors.Length == v.Length; List<Color> list7 = new List<Color>(); 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<MeshFilter>().sharedMesh = val; MeshRenderer obj = val2.AddComponent<MeshRenderer>(); ((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<SkinnedMeshRenderer>(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<Material> _ownedMats = new List<Material>(); 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<string, Component> parts = new Dictionary<string, Component>(); 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<GameObject>(((Component)panel).gameObject, panel.parent, true); ((Object)_go).name = "YakariBingBongBossBar"; LeanTween.cancel(_go, true); MonoBehaviour[] componentsInChildren = _go.GetComponentsInChildren<MonoBehaviour>(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<CanvasGroup>(); if ((Object)(object)_group == (Object)null) { _group = _go.AddComponent<CanvasGroup>(); } _ = (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<Image>(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<Component> 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<int> list = new List<int>(); 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<float>)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<Creature>(); 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<float>)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<float>)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<SqueezeMsg>.SetWrite((Action<Writer, SqueezeMsg>)WriteMsg); GenericReader<SqueezeMsg>.SetRead((Func<Reader, SqueezeMsg>)ReadMsg); InstanceFinder.ServerManager.RegisterBroadcast<SqueezeMsg>((Action<NetworkConnection, SqueezeMsg, Channel>)OnServer, true); InstanceFinder.ClientManager.RegisterBroadcast<SqueezeMsg>((Action<SqueezeMsg, Channel>)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<SqueezeMsg>((Action<NetworkConnection, SqueezeMsg, Channel>)OnServer); } ClientManager clientManager = InstanceFinder.ClientManager; if (clientManager != null) { clientManager.UnregisterBroadcast<SqueezeMsg>((Action<SqueezeMsg, Channel>)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<object> list = new List<object>(); 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<SqueezeMsg>(InstanceFinder.ClientManager.Connection, squeezeMsg, true, (Channel)0); } else if (InstanceFinder.IsClientStarted) { InstanceFinder.ClientManager.Broadcast<SqueezeMsg>(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<SqueezeMsg>(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<int> FightBag = new List<int>(); 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<string> _clipFile; private ConfigEntry<float> _volume; private ConfigEntry<float> _settleDelay; private ConfigEntry<string> _squeakFile; private ConfigEntry<float> _squeakVolume; private ConfigEntry<float> _leanAmount; private ConfigEntry<float> _squashAmount; private ConfigEntry<float> _springK; private ConfigEntry<float> _springDamp; private ConfigEntry<float> _cooldown; private ConfigEntry<bool> _syncEnabled; private ConfigEntry<bool> _captionEnabled; private ConfigEntry<float> _captionSize; private ConfigEntry<float> _captionHeight; private ConfigEntry<int> _captionWrap; private ConfigEntry<bool> _cookEnabled; private ConfigEntry<float> _cookMinPitch; private ConfigEntry<float> _cookMinVolume; private ConfigEntry<float> _cookSqueakMinPitch; private ConfigEntry<float> _cookDeadAt; private ConfigEntry<float> _cookWobble; private ConfigEntry<float> _cookDropouts; private ConfigEntry<float> _cookLowPass; private ConfigEntry<float> _cookDistortion; private ConfigEntry<float> _cookShrivel; private ConfigEntry<bool> _cookGlitchText; private ConfigEntry<bool> _rageEnabled; private ConfigEntry<float> _rageSqueezes; private ConfigEntry<float> _rageDecay; private ConfigEntry<string> _rageCaptionColor; private ConfigEntry<float> _thrashAngle; private ConfigEntry<float> _thrashJitter; private ConfigEntry<float> _thrashPump; private ConfigEntry<bool> _provokeEnabled; private ConfigEntry<float> _provokeAngryAt; private ConfigEntry<float> _provokeFightAt; private ConfigEntry<float> _provokeDecay; private ConfigEntry<float> _provokeSpamWeight; private ConfigEntry<float> _groundThrashScale; private ConfigEntry<float> _chatterInterval; private ConfigEntry<float> _sorrySeconds; private ConfigEntry<float> _lungeSpeed; private ConfigEntry<float> _idleInterval; private ConfigEntry<float> _idleVolume; private ConfigEntry<int> _hundredEvery; private ConfigEntry<int> _squeezeCount; private ConfigEntry<string> _fightMusic; private ConfigEntry<bool> _beakEnabled; private ConfigEntry<float> _beakAngle; private ConfigEntry<bool> _beakFlip; private ConfigEntry<float> _beakGain; private ConfigEntry<float> _beakFloor; private ConfigEntry<float> _beakRelease; private ConfigEntry<float> _beakFlutterHz; private ConfigEntry<float> _beakFlutter; private ConfigEntry<bool> _bossBar; private ConfigEntry<string> _bossBarName; private ConfigEntry<float> _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<AudioClip> _lines = new List<AudioClip>(); private readonly List<float[]> _lineEnvs = new List<float[]>(); private readonly List<string> _lineCaptions = new List<string>(); private readonly List<AudioClip> _angry = new List<AudioClip>(); private readonly List<float[]> _angryEnvs = new List<float[]>(); private readonly List<string> _angryCaptions = new List<string>(); private readonly List<AudioClip> _hurt = new List<AudioClip>(); private readonly List<float[]> _hurtEnvs = new List<float[]>(); private readonly List<string> _hurtCaptions = new List<string>(); private readonly List<AudioClip> _fight = new List<AudioClip>(); private readonly List<float[]> _fightEnvs = new List<float[]>(); private readonly List<string> _fightCaptions = new List<string>(); private readonly List<AudioClip> _sorry = new List<AudioClip>(); private readonly List<float[]> _sorryEnvs = new List<float[]>(); private readonly List<string> _sorryCaptions = new List<string>(); private readonly List<AudioClip> _warn = new List<AudioClip>(); private readonly List<float[]> _warnEnvs = new List<float[]>(); private readonly List<string> _warnCaptions = new List<string>(); private readonly List<AudioClip> _open = new List<AudioClip>(); private readonly List<float[]> _openEnvs = new List<float[]>(); private readonly List<string> _openCaptions = new List<string>(); private readonly List<AudioClip> _relief = new List<AudioClip>(); private readonly List<float[]> _reliefEnvs = new List<float[]>(); private readonly List<string> _reliefCaptions = new List<string>(); private readonly List<AudioClip> _panic = new List<AudioClip>(); private readonly List<float[]> _panicEnvs = new List<float[]>(); private readonly List<string> _panicCaptions = new List<string>(); private readonly List<AudioClip> _idle = new List<AudioClip>(); private readonly List<float[]> _idleEnvs = new List<float[]>(); private readonly List<string> _idleCaptions = new List<string>(); private readonly List<AudioClip> _hundred = new List<AudioClip>(); private readonly List<float[]> _hundredEnvs = new List<float[]>(); private readonly List<string> _hundredCaptions = new List<string>(); private readonly List<AudioClip> _panicAngry = new List<AudioClip>(); private readonly List<float[]> _panicAngryEnvs = new List<float[]>(); private readonly List<string> _panicAngryCaptions = new List<string>(); private readonly Dictionary<Item, FishShow> _shows = new Dictionary<Item, FishShow>(); private static readonly List<Item> _deadKeys = new List<Item>(); 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<AudioClip> 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<float[]> 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<string> 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<string>("Voice", "ClipFile", "bingbong-1.50.mp3", "Fallback voice clip in BepInEx/plugins/BingBong/ (used only if lines/ is missing)."); _volume = ((BaseUnityPlugin)this).Config.Bind<float>("Voice", "Volume", 1f, "Voice volume (0..1)."); _settleDelay = ((BaseUnityPlugin)this).Config.Bind<float>("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<string>("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<float>("Voice", "SqueakVolume", 1f, "Squeak volume (0..1)."); _leanAmount = ((BaseUnityPlugin)this).Config.Bind<float>("Voice", "TalkLeanAmount", 16f, "How far (degrees) he leans into the listener on loud syllables. 0 disables."); _squashAmount = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("Squeeze", "SpringStiffness", 260f, "Spring stiffness. Higher = snappier pop back."); _springDamp = ((BaseUnityPlugin)this).Config.Bind<float>("Squeeze", "SpringDamping", 11f, "Damping. Lower = more rubbery wobbles before settling."); _cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Squeeze", "Cooldown", 0.06f, "Min seconds between squeezes - low so the squeak stays spammable."); _syncEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Multiplayer", "EnableSync", true, "Broadcast squeezes so other modded players see and hear them."); _captionEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Caption", "Enabled", true, "Float the words he is saying over his head while he talks."); _captionSize = ((BaseUnityPlugin)this).Config.Bind<float>("Caption", "Size", 0.065f, "Caption font size (game WorldText units)."); _captionWrap = ((BaseUnityPlugin)this).Config.Bind<int>("Caption", "WrapAfter", 12, "Captions longer than this many characters break onto a second row at the nearest space."); _captionHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Caption", "Height", 0.15f, "How far above the top of his body the caption sits, in metres."); _cookEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Cooking", "Enabled", true, "Cooking him lowers his pitch and volume; burnt, he can only wheeze."); _cookMinPitch = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("Cooking", "VoiceMinVolume", 0.3f, "Voice volume multiplier when fully burnt."); _cookSqueakMinPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Cooking", "SqueakMinPitch", 0.55f, "Squeak pitch when fully burnt - the rubber melts too."); _cookDeadAt = ((BaseUnityPlugin)this).Config.Bind<float>("Cooking", "DeadAt", 1.95f, "Cookness at which he stops talking altogether. 2 = fully black; 1.95 = visibly charcoal."); _cookWobble = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("Cooking", "DropoutsPerSecond", 7f, "Frying-contact cut-outs per second when fully burnt (each 20-60 ms). Scales with cookness."); _cookLowPass = ((BaseUnityPlugin)this).Config.Bind<float>("Cooking", "LowPassAtBurnt", 900f, "Low-pass cutoff (Hz) when fully burnt - the speaker cone melting. 22000 = off."); _cookDistortion = ((BaseUnityPlugin)this).Config.Bind<float>("Cooking", "DistortionAtBurnt", 0.6f, "Distortion level (0..1) when fully burnt - fried speaker crunch."); _cookShrivel = ((BaseUnityPlugin)this).Config.Bind<float>("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<bool>("Cooking", "GlitchCaption", true, "Stutter and drop letters in the caption as he cooks."); _rageEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Rage", "Enabled", true, "Over-squeezing turns him into the angry red version until he is dropped in water."); _rageSqueezes = ((BaseUnityPlugin)this).Config.Bind<float>("Rage", "SqueezesToSnap", 12f, "Heat needed to snap. Each squeeze adds 1; heat decays HeatDecayPerSecond."); _rageDecay = ((BaseUnityPlugin)this).Config.Bind<float>("Rage", "HeatDecayPerSecond", 1.5f, "How fast squeeze-heat bleeds off. Spam faster than this and he snaps."); _rageCaptionColor = ((BaseUnityPlugin)this).Config.Bind<string>("Rage", "CaptionColor", "#FF3B3B", "Caption colour while angry (hex)."); _thrashAngle = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("Rage", "ThrashJitter", 9f, "Continuous uncontrolled wobble (degrees) while he is shouting, on top of the throws."); _thrashPump = ((BaseUnityPlugin)this).Config.Bind<float>("Rage", "ThrashPump", 14f, "Body puff on each shout - a kick into the squish spring (a click is 28)."); _provokeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Provoke", "Enabled", true, "Hitting a dead Bing Bong on the ground provokes him."); _provokeAngryAt = ((BaseUnityPlugin)this).Config.Bind<float>("Provoke", "AngryAt", 3f, "Provocation points before he turns red. Each hit = 1 point."); _provokeFightAt = ((BaseUnityPlugin)this).Config.Bind<float>("Provoke", "FightAt", 6f, "Provocation points before he comes alive and attacks (needs a modded host)."); _provokeDecay = ((BaseUnityPlugin)this).Config.Bind<float>("Provoke", "DecayPerSecond", 0.12f, "How fast provocation cools off when you leave him alone."); _provokeSpamWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Provoke", "SpamSqueezeWeight", 1f, "Provocation points per squeeze while he is already red (Trigger B)."); _chatterInterval = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("Provoke", "SorrySeconds", 2f, "Cooldown after you kill him: he says sorry and cannot be provoked."); _lungeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("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<float>("Charm", "IdleVolume", 0.45f, "How quiet the sleepy mumbles are."); _hundredEvery = ((BaseUnityPlugin)this).Config.Bind<int>("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<int>("Stats", "AnswersSqueezed", 0, "How many answers you have squeezed out of Bing Bongs on this install. He is counting."); _beakEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Beak", "Enabled", true, "Split his beak into two wedges that open and close like scissors while he talks."); _beakAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Beak", "MaxAngle", 22f, "How wide the beak opens (degrees per wedge)."); _beakFlip = ((BaseUnityPlugin)this).Config.Bind<bool>("Beak", "Flip", false, "If the wedges close instead of open, flip the direction."); _beakGain = ((BaseUnityPlugin)this).Config.Bind<float>("Beak", "Gain", 2.2f, "Sensitivity to the voice. Higher = snaps open on quieter syllables."); _beakFloor = ((BaseUnityPlugin)this).Config.Bind<float>("Beak", "Floor", 0.1f, "Loudness below this keeps the beak shut (0..1)."); _beakRelease = ((BaseUnityPlugin)this).Config.Bind<float>("Beak", "Release", 0.07f, "Seconds to fall shut after a syllable. Opening is instant."); _beakFlutterHz = ((BaseUnityPlugin)this).Config.Bind<float>("Beak", "FlutterHz", 24f, "The chatter: how fast the open beak vibrates."); _beakFlutter = ((BaseUnityPlugin)this).Config.Bind<float>("Beak", "Flutter", 0.45f, "How much of the opening the chatter modulates (0 = none, 1 = slams shut each cycle)."); _bossBar = ((BaseUnityPlugin)this).Config.Bind<bool>("Music", "BossBar", true, "Show the vanilla-style boss health bar while he hunts you."); _bossBarName = ((BaseUnityPlugin)this).Config.Bind<string>("Music", "BossBarName", "Angry Bing Bong", "The name on his boss bar."); _fightSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("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<string>("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<float>("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<Creature>() != (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<Creature>(); 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<Item, FishShow> 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<Creature>(); 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<Creature>(); 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<Rigidbody>(); 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<Creature>(); 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<Creature>)?.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<Creature>() : 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<Creature>() : 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<Item, FishShow> 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<AudioSource>(); fishShow.VoiceSource = val2.AddComponent<AudioSource>(); 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<AudioLowPassFilter>(); fishShow.LowPass.cutoffFrequency = 22000f; fishShow.Distortion = val2.AddComponent<AudioDistortionFilter>(); fishShow.Distortion.distortionLevel = 0f; fishShow.WobbleSeed = Random.value * 100f; _shows[fish] = fishShow; TryBuildBeak(fishShow); Creature component = ((Component)fish).GetComponent<Creature>(); ((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>(), (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<AudioClip> list = Clips(pool); List<float[]> 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<string> 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 = "<color=" + _rageCaptionColor.Value + ">" + text.ToUpperInvariant() + "</color>"; } show.Caption = Object.Instantiate<WorldText>(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