using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.VRMK;
using LabFusion.Entities;
using MelonLoader;
using MelonLoader.Preferences;
using RabbitDirector;
using UnityEngine;
using UnityEngine.Events;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(RabbitDirectorMod), "Rabbit Director", "1.0.1", "EQUALIZER", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace RabbitDirector;
public sealed class RabbitDirectorMod : MelonMod
{
private enum VoiceTopic
{
Behind,
Threat,
Chase,
Search
}
private const int VoiceLineCount = 30;
private static readonly int[] DefaultFavorites = new int[8] { 1, 7, 8, 15, 17, 24, 27, 30 };
private const float WheelDeadzone = 0.52f;
private const float WheelActivationSeconds = 0.25f;
private const float WheelHandDistance = 0.32f;
private const float WheelDirectionDistance = 0.18f;
private static readonly Dictionary<VoiceTopic, int[]> TopicLines = new Dictionary<VoiceTopic, int[]>
{
[VoiceTopic.Behind] = new int[9] { 2, 3, 6, 9, 13, 15, 18, 27, 29 },
[VoiceTopic.Threat] = new int[10] { 1, 4, 7, 11, 12, 22, 23, 25, 28, 30 },
[VoiceTopic.Chase] = new int[6] { 10, 14, 16, 19, 21, 26 },
[VoiceTopic.Search] = new int[5] { 5, 8, 17, 20, 24 }
};
private static readonly Dictionary<int, string> LineTexts = new Dictionary<int, string>
{
[1] = "Mr. and Mrs. Waterman, were very, very bad people.",
[2] = "Happy Halloween from the Waterman's",
[3] = "This year's harvest will be so pleasant!",
[4] = "A new year, more bunnies for the slaughter.",
[5] = "My victims are never forgotten.",
[6] = "This Year's haunt will be so delightful",
[7] = "I will rip, and I will cut, and I will punish you.",
[8] = "Such naughty bunnies, I will find you",
[9] = "Let's go trick-or-treating.",
[10] = "Ready or not, here I come",
[11] = "You will be punished.",
[12] = "You won't feel a thing.",
[13] = "Here's your treat.",
[14] = "You shouldn't run from me.",
[15] = "*laugh*",
[16] = "Oh, you're in trouble now!",
[17] = "It's fun when you hide, but now I seek.",
[18] = "Trick-or-treat",
[19] = "What a naughty bunny",
[20] = "You shouldn't be here.",
[21] = "You stay put",
[22] = "It's time to join the fair eye.",
[23] = "See, doesn't that feel better?",
[24] = "And you look like a scarecrow.",
[25] = "...And bunnies must be punished",
[26] = "Playtime is over",
[27] = "*laugh*",
[28] = "The boogieman claims his victims",
[29] = "Here's your trick.",
[30] = "You'll be with us forever"
};
private readonly MelonPreferences_Entry<int>[] _favoriteEntries = new MelonPreferences_Entry<int>[8];
private readonly FunctionElement[] _quickButtons = (FunctionElement[])(object)new FunctionElement[8];
private MelonPreferences_Category _preferences;
private Hand _maskHand;
private Transform _physicalMask;
private Renderer _physicalMaskRenderer;
private Transform _maskGrabPoint;
private Transform _maskHomeParent;
private Transform _wornMaskBone;
private Vector3 _maskHomePosition;
private Quaternion _maskHomeRotation;
private Vector3 _maskHomeScale;
private int _boundAvatarId;
private float _maskTakenAt;
private readonly Random _random = new Random();
private readonly Dictionary<VoiceTopic, int> _lastTopicLine = new Dictionary<VoiceTopic, int>();
private GameObject _wheelRoot;
private readonly Dictionary<VoiceTopic, TextMesh> _wheelLabels = new Dictionary<VoiceTopic, TextMesh>();
private TextMesh _wheelCenter;
private bool _wheelHeld;
private VoiceTopic? _wheelSelection;
private float _wheelActivationStartedAt = -1f;
private Transform _wheelLeftPalm;
private Transform _wheelRightPalm;
public override void OnInitializeMelon()
{
CreatePreferences();
CreateMenu();
((MelonBase)this).LoggerInstance.Msg("Rabbit Director ready: voice library, mask hand-follow and visibility controls.");
}
public override void OnUpdate()
{
UpdateVoiceWheel();
RefreshMaskReferences();
if ((Object)(object)_maskHand == (Object)null)
{
if (!TryTakeMask(Player.LeftHand))
{
TryTakeMask(Player.RightHand);
}
return;
}
BaseController controller = _maskHand.Controller;
if ((Object)(object)controller == (Object)null)
{
ReturnMask();
}
else if (Time.time > _maskTakenAt + 0.12f && controller.isBelowGripThreshold)
{
ReturnMask();
}
}
private void CreatePreferences()
{
_preferences = MelonPreferences.CreateCategory("RabbitDirector", "Rabbit Director");
for (int i = 0; i < _favoriteEntries.Length; i++)
{
_favoriteEntries[i] = _preferences.CreateEntry<int>($"Favorite_{i + 1}", DefaultFavorites[i], $"Favorite {i + 1}", (string)null, false, false, (ValueValidator)null, (string)null);
_favoriteEntries[i].Value = ClampLine(_favoriteEntries[i].Value);
}
}
private void CreateMenu()
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: 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_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0307: Unknown result type (might be due to invalid IL or missing references)
Color val = default(Color);
((Color)(ref val))..ctor(0.92f, 0.36f, 0.08f);
Color val2 = default(Color);
((Color)(ref val2))..ctor(0.95f, 0.87f, 0.68f);
Color val3 = default(Color);
((Color)(ref val3))..ctor(0.72f, 0.06f, 0.05f);
Page val4 = Page.Root.CreatePage("Rabbit Director", val, 0, true);
Page val5 = val4.CreatePage("Quick Voice Lines", val, 0, true);
Page val6 = val4.CreatePage("Voice Wheel Topics", val, 0, true);
Page val7 = val4.CreatePage("All 30 Voice Lines", val2, 8, true);
Page val8 = val4.CreatePage("Edit Favorites", Color.yellow, 0, true);
val4.CreateFunction("INVISIBLE", new Color(0.35f, 0.35f, 0.35f), (Action)delegate
{
TriggerNamedEvent("VisibilityControl", menuTap: false);
});
val4.CreateFunction("VISIBLE", Color.white, (Action)delegate
{
TriggerNamedEvent("VisibilityControl", menuTap: true);
});
val4.CreateFunction("RETURN MASK NOW", val2, (Action)ReturnMask);
val6.CreateFunction("BEHIND - random", val, (Action)delegate
{
PlayRandomTopic(VoiceTopic.Behind);
});
val6.CreateFunction("THREAT - random", val3, (Action)delegate
{
PlayRandomTopic(VoiceTopic.Threat);
});
val6.CreateFunction("CHASE - random", Color.yellow, (Action)delegate
{
PlayRandomTopic(VoiceTopic.Chase);
});
val6.CreateFunction("SEARCH - random", Color.cyan, (Action)delegate
{
PlayRandomTopic(VoiceTopic.Search);
});
val6.CreateFunction("VR WHEEL: hold left Y + right stick", val2, (Action)delegate
{
((MelonBase)this).LoggerInstance.Msg("Voice wheel: hold left Y, point the right stick at a topic, then release Y.");
});
for (int num = 0; num < _quickButtons.Length; num++)
{
int capturedSlot = num;
_quickButtons[num] = val5.CreateFunction(QuickButtonName(num), val, (Action)delegate
{
PlayLine(_favoriteEntries[capturedSlot].Value);
});
}
val5.CreateFunction("STOP VOICE", val3, (Action)StopVoice);
for (int num2 = 1; num2 <= 30; num2++)
{
int capturedLine = num2;
val7.CreateFunction(MenuLineName(num2), val2, (Action)delegate
{
PlayLine(capturedLine);
});
}
for (int num3 = 0; num3 < _favoriteEntries.Length; num3++)
{
int capturedSlot2 = num3;
val8.CreateInt($"Slot {num3 + 1}: {LineId(_favoriteEntries[num3].Value)}", Color.yellow, _favoriteEntries[num3].Value, 1, 1, 30, (Action<int>)delegate(int value)
{
SetFavorite(capturedSlot2, value);
});
}
val4.CreateFunction("STOP VOICE", val3, (Action)StopVoice);
val4.CreateFunction("Rescan Avatar Audio", Color.cyan, (Action)delegate
{
int count = FindAudioEvents().Count;
((MelonBase)this).LoggerInstance.Msg($"Rabbit Director found {count}/31 audio events on the avatar.");
});
}
private void SetFavorite(int slot, int value)
{
value = ClampLine(value);
_favoriteEntries[slot].Value = value;
((Element)_quickButtons[slot]).ElementName = QuickButtonName(slot);
MelonPreferences.Save();
}
private string QuickButtonName(int slot)
{
return $"{slot + 1}. {LineId(_favoriteEntries[slot].Value)}";
}
private static string MenuLineName(int line)
{
return LineId(line) + " - " + LineTexts[line];
}
private void PlayLine(int line)
{
TriggerEvent("AudioEvent_" + LineId(ClampLine(line)));
}
private void PlayRandomTopic(VoiceTopic topic)
{
int[] array = TopicLines[topic];
int value;
int num = (_lastTopicLine.TryGetValue(topic, out value) ? value : (-1));
int num2;
do
{
num2 = array[_random.Next(array.Length)];
}
while (array.Length > 1 && num2 == num);
_lastTopicLine[topic] = num2;
((MelonBase)this).LoggerInstance.Msg($"Voice wheel: {TopicName(topic)} -> {LineId(num2)} {LineTexts[num2]}");
PlayLine(num2);
}
private void UpdateVoiceWheel()
{
if (!_wheelHeld)
{
if (!TryGetWheelActivationPose(out var leftPalm, out var rightPalm))
{
_wheelActivationStartedAt = -1f;
return;
}
if (_wheelActivationStartedAt < 0f)
{
_wheelActivationStartedAt = Time.time;
}
if (!(Time.time < _wheelActivationStartedAt + 0.25f))
{
_wheelHeld = true;
_wheelLeftPalm = leftPalm;
_wheelRightPalm = rightPalm;
_wheelSelection = null;
ShowVoiceWheel(null);
}
}
else if ((Object)(object)_wheelLeftPalm == (Object)null || (Object)(object)_wheelRightPalm == (Object)null || (Object)(object)_wheelLeftPalm == (Object)(object)_wheelRightPalm)
{
CancelVoiceWheel();
}
else
{
Hand leftHand = Player.LeftHand;
BaseController val = ((leftHand != null) ? leftHand.Controller : null);
if ((Object)(object)val == (Object)null)
{
CancelVoiceWheel();
return;
}
if (val.isBelowGripThreshold)
{
FinishVoiceWheel();
return;
}
_wheelSelection = TopicFromHandPosition(_wheelLeftPalm, _wheelRightPalm);
ShowVoiceWheel(_wheelSelection);
}
}
private static bool TryGetWheelActivationPose(out Transform leftPalm, out Transform rightPalm)
{
//IL_00a0: 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_00fa: 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_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
leftPalm = null;
rightPalm = null;
Hand leftHand = Player.LeftHand;
Hand rightHand = Player.RightHand;
if ((Object)(object)leftHand == (Object)null || (Object)(object)rightHand == (Object)null || leftHand.HasAttachedObject() || rightHand.HasAttachedObject())
{
return false;
}
BaseController controller = leftHand.Controller;
leftPalm = (((Object)(object)leftHand.palmPositionTransform != (Object)null) ? leftHand.palmPositionTransform : ((Component)leftHand).transform);
rightPalm = (((Object)(object)rightHand.palmPositionTransform != (Object)null) ? rightHand.palmPositionTransform : ((Component)rightHand).transform);
if ((Object)(object)controller == (Object)null || controller.isBelowGripThreshold || (Object)(object)leftPalm == (Object)null || (Object)(object)rightPalm == (Object)null || Vector3.Distance(leftPalm.position, rightPalm.position) > 0.32f)
{
return false;
}
Camera val = Camera.main ?? ((IEnumerable<Camera>)Camera.allCameras).FirstOrDefault((Func<Camera, bool>)((Camera active) => ((Behaviour)active).enabled));
if ((Object)(object)val == (Object)null)
{
return false;
}
Vector3 val2 = (leftPalm.position + rightPalm.position) * 0.5f - ((Component)val).transform.position;
if (((Vector3)(ref val2)).sqrMagnitude > 0.09f)
{
return Vector3.Dot(((Component)val).transform.forward, ((Vector3)(ref val2)).normalized) > 0.2f;
}
return false;
}
private static VoiceTopic? TopicFromHandPosition(Transform leftPalm, Transform rightPalm)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
Camera val = Camera.main ?? ((IEnumerable<Camera>)Camera.allCameras).FirstOrDefault((Func<Camera, bool>)((Camera active) => ((Behaviour)active).enabled));
if ((Object)(object)val == (Object)null)
{
return null;
}
Vector3 val2 = rightPalm.position - leftPalm.position;
Vector2 val3 = default(Vector2);
((Vector2)(ref val3))..ctor(Vector3.Dot(val2, ((Component)val).transform.right) / 0.18f, Vector3.Dot(val2, ((Component)val).transform.up) / 0.18f);
if (((Vector2)(ref val3)).magnitude < 0.52f)
{
return null;
}
if (Mathf.Abs(val3.y) >= Mathf.Abs(val3.x))
{
return (!(val3.y >= 0f)) ? VoiceTopic.Chase : VoiceTopic.Behind;
}
return (val3.x >= 0f) ? VoiceTopic.Threat : VoiceTopic.Search;
}
private void FinishVoiceWheel()
{
HideVoiceWheel();
_wheelHeld = false;
_wheelActivationStartedAt = -1f;
_wheelLeftPalm = null;
_wheelRightPalm = null;
if (_wheelSelection.HasValue)
{
PlayRandomTopic(_wheelSelection.Value);
}
_wheelSelection = null;
}
private void CancelVoiceWheel()
{
HideVoiceWheel();
_wheelHeld = false;
_wheelSelection = null;
_wheelActivationStartedAt = -1f;
_wheelLeftPalm = null;
_wheelRightPalm = null;
}
private void ShowVoiceWheel(VoiceTopic? selected)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
EnsureVoiceWheel();
Camera val = Camera.main ?? ((IEnumerable<Camera>)Camera.allCameras).FirstOrDefault((Func<Camera, bool>)((Camera active) => ((Behaviour)active).enabled));
if ((Object)(object)val == (Object)null || (Object)(object)_wheelRoot == (Object)null)
{
return;
}
_wheelRoot.SetActive(true);
Transform transform = ((Component)val).transform;
Transform val2 = (((Object)(object)_wheelLeftPalm != (Object)null) ? _wheelLeftPalm : transform);
Vector3 val3 = transform.position - val2.position;
Vector3 normalized = ((Vector3)(ref val3)).normalized;
_wheelRoot.transform.position = val2.position + normalized * 0.08f;
_wheelRoot.transform.rotation = Quaternion.LookRotation(transform.forward, transform.up);
foreach (KeyValuePair<VoiceTopic, TextMesh> wheelLabel in _wheelLabels)
{
wheelLabel.Deconstruct(out var key, out var value);
VoiceTopic voiceTopic = key;
TextMesh obj = value;
VoiceTopic? voiceTopic2 = selected;
key = voiceTopic;
obj.color = ((voiceTopic2 == key) ? Color.white : TopicColor(voiceTopic));
}
_wheelCenter.text = (selected.HasValue ? (TopicName(selected.Value) + "\nrelease Y") : "VOICE\nchoose a direction");
}
private void HideVoiceWheel()
{
if ((Object)(object)_wheelRoot != (Object)null)
{
_wheelRoot.SetActive(false);
}
}
private void EnsureVoiceWheel()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_wheelRoot != (Object)null))
{
_wheelRoot = new GameObject("RabbitDirectorVoiceWheel")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)(object)_wheelRoot);
_wheelRoot.transform.localScale = Vector3.one * 0.04f;
_wheelCenter = CreateWheelText("Center", Vector3.zero, "VOICE\nMOVE RIGHT HAND", 0.025f);
_wheelLabels[VoiceTopic.Behind] = CreateWheelText("Behind", Vector3.up * 4.2f, "UP\nBEHIND", 0.032f);
_wheelLabels[VoiceTopic.Threat] = CreateWheelText("Threat", Vector3.right * 5.4f, "RIGHT\nTHREAT", 0.032f);
_wheelLabels[VoiceTopic.Chase] = CreateWheelText("Chase", Vector3.down * 4.2f, "DOWN\nCHASE", 0.032f);
_wheelLabels[VoiceTopic.Search] = CreateWheelText("Search", Vector3.left * 5.4f, "LEFT\nSEARCH", 0.032f);
HideVoiceWheel();
}
}
private TextMesh CreateWheelText(string objectName, Vector3 localPosition, string text, float size)
{
//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)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(objectName);
val.transform.SetParent(_wheelRoot.transform, false);
val.transform.localPosition = localPosition;
TextMesh obj = val.AddComponent<TextMesh>();
obj.text = text;
obj.anchor = (TextAnchor)4;
obj.alignment = (TextAlignment)1;
obj.characterSize = size;
obj.fontSize = 64;
obj.color = new Color(0.92f, 0.36f, 0.08f);
return obj;
}
private static Color TopicColor(VoiceTopic topic)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: 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_0043: 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_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
return (Color)(topic switch
{
VoiceTopic.Behind => new Color(0.78f, 0.32f, 0.95f),
VoiceTopic.Threat => new Color(0.86f, 0.08f, 0.08f),
VoiceTopic.Chase => new Color(0.95f, 0.75f, 0.12f),
VoiceTopic.Search => new Color(0.12f, 0.75f, 0.92f),
_ => Color.white,
});
}
private static string TopicName(VoiceTopic topic)
{
return topic switch
{
VoiceTopic.Behind => "BEHIND",
VoiceTopic.Threat => "THREAT",
VoiceTopic.Chase => "CHASE",
VoiceTopic.Search => "SEARCH",
_ => "VOICE",
};
}
private void StopVoice()
{
TriggerEvent("AudioEvent_STOP_ALL");
}
private void TriggerEvent(string objectName)
{
SimpleGripEvents val = ((IEnumerable<SimpleGripEvents>)FindAvatarEvents()).FirstOrDefault((Func<SimpleGripEvents, bool>)((SimpleGripEvents component) => ((Object)((Component)component).gameObject).name == objectName));
if ((Object)(object)val == (Object)null)
{
((MelonBase)this).LoggerInstance.Warning("'" + objectName + "' was not found. Equip PumpkinRabbit_TEST_MIN and try again.");
return;
}
UnityEvent onIndexDown = val.OnIndexDown;
if (onIndexDown != null)
{
onIndexDown.Invoke();
}
TryRelayFusionEvent(val, "TRIGGER_DOWN");
}
private void TriggerNamedEvent(string objectName, bool menuTap)
{
SimpleGripEvents val = ((IEnumerable<SimpleGripEvents>)FindAvatarEvents()).FirstOrDefault((Func<SimpleGripEvents, bool>)((SimpleGripEvents component) => ((Object)((Component)component).gameObject).name == objectName));
if ((Object)(object)val == (Object)null)
{
((MelonBase)this).LoggerInstance.Warning("'" + objectName + "' was not found on the equipped avatar.");
}
else if (menuTap)
{
UnityEvent onMenuTapDown = val.OnMenuTapDown;
if (onMenuTapDown != null)
{
onMenuTapDown.Invoke();
}
TryRelayFusionEvent(val, "MENU_TAP");
}
else
{
UnityEvent onIndexDown = val.OnIndexDown;
if (onIndexDown != null)
{
onIndexDown.Invoke();
}
TryRelayFusionEvent(val, "TRIGGER_DOWN");
}
}
private void RefreshMaskReferences()
{
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Player.RigManager == (Object)null)
{
ClearMaskReferences();
return;
}
Avatar val = null;
try
{
val = Player.Avatar;
}
catch
{
ClearMaskReferences();
return;
}
if ((Object)(object)val == (Object)null)
{
ClearMaskReferences();
return;
}
int instanceID = ((Object)val).GetInstanceID();
if (_boundAvatarId == instanceID && (Object)(object)_physicalMask != (Object)null && (Object)(object)_maskGrabPoint != (Object)null)
{
return;
}
ClearMaskReferences();
Transform val2 = FindDeep(((Component)val).transform, "PhysicalMaskAccessory");
if (!((Object)(object)val2 == (Object)null))
{
_physicalMask = FindDeep(val2, "PhysicalMask");
_maskGrabPoint = FindDeep(val2, "MaskGrabPoint");
_wornMaskBone = FindDeep(((Component)val).transform, "Mask");
Transform physicalMask = _physicalMask;
_physicalMaskRenderer = ((physicalMask != null) ? ((Component)physicalMask).GetComponent<Renderer>() : null);
if ((Object)(object)_physicalMask == (Object)null || (Object)(object)_maskGrabPoint == (Object)null || (Object)(object)_wornMaskBone == (Object)null || (Object)(object)_physicalMaskRenderer == (Object)null)
{
ClearMaskReferences();
return;
}
_boundAvatarId = instanceID;
_maskHomeParent = _physicalMask.parent;
_maskHomePosition = _physicalMask.localPosition;
_maskHomeRotation = _physicalMask.localRotation;
_maskHomeScale = _physicalMask.localScale;
_physicalMaskRenderer.enabled = false;
((MelonBase)this).LoggerInstance.Msg("Mask proximity control bound to Pumpkin Rabbit avatar.");
}
}
private bool TryTakeMask(Hand hand)
{
//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_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)hand == (Object)null || (Object)(object)_physicalMask == (Object)null || (Object)(object)_maskGrabPoint == (Object)null)
{
return false;
}
BaseController controller = hand.Controller;
Transform val = (((Object)(object)hand.palmPositionTransform != (Object)null) ? hand.palmPositionTransform : ((Component)hand).transform);
if ((Object)(object)controller == (Object)null || controller.isBelowGripThreshold || (Object)(object)val == (Object)null || hand.HasAttachedObject())
{
return false;
}
if (Vector3.Distance(val.position, _maskGrabPoint.position) > 0.18f)
{
return false;
}
_maskHand = hand;
_maskTakenAt = Time.time;
TriggerNamedEvent("PhysicalMaskAccessory", menuTap: false);
_wornMaskBone.localScale = Vector3.one * 0.1f;
_physicalMaskRenderer.enabled = true;
_physicalMask.SetParent(val, true);
((MelonBase)this).LoggerInstance.Msg($"Mask taken with {hand.handedness} hand; grab distance={Vector3.Distance(val.position, _maskGrabPoint.position):F3}m.");
return true;
}
private void ReturnMask()
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_physicalMaskRenderer != (Object)null)
{
_physicalMaskRenderer.enabled = false;
}
if ((Object)(object)_physicalMask != (Object)null && (Object)(object)_maskHomeParent != (Object)null)
{
_physicalMask.SetParent(_maskHomeParent, false);
_physicalMask.localPosition = _maskHomePosition;
_physicalMask.localRotation = _maskHomeRotation;
_physicalMask.localScale = _maskHomeScale;
}
bool num = (Object)(object)_maskHand != (Object)null;
_maskHand = null;
if (num)
{
if ((Object)(object)_wornMaskBone != (Object)null)
{
_wornMaskBone.localScale = Vector3.one;
}
TriggerNamedEvent("MaskReturnSyncEvent", menuTap: false);
((MelonBase)this).LoggerInstance.Msg("Mask returned after controller grip release.");
}
}
private void ClearMaskReferences()
{
_maskHand = null;
_physicalMask = null;
_physicalMaskRenderer = null;
_maskGrabPoint = null;
_maskHomeParent = null;
_wornMaskBone = null;
_boundAvatarId = 0;
_maskTakenAt = 0f;
}
private List<SimpleGripEvents> FindAudioEvents()
{
return (from component in FindAvatarEvents()
where ((Object)((Component)component).gameObject).name.StartsWith("AudioEvent_", StringComparison.Ordinal)
select component).ToList();
}
private List<SimpleGripEvents> FindAvatarEvents()
{
List<SimpleGripEvents> list = new List<SimpleGripEvents>();
if ((Object)(object)Player.Avatar == (Object)null)
{
return list;
}
foreach (SimpleGripEvents componentsInChild in ((Component)Player.Avatar).GetComponentsInChildren<SimpleGripEvents>(true))
{
if ((Object)(object)componentsInChild != (Object)null)
{
list.Add(componentsInChild);
}
}
return list;
}
private void TryRelayFusionEvent(SimpleGripEvents source, string eventName)
{
try
{
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly2) => assembly2.GetName().Name == "BonelabSupport");
if (assembly == null)
{
return;
}
Type type = assembly.GetType("MarrowFusion.Bonelab.Extenders.SimpleGripEventsExtender");
Type type2 = assembly.GetType("MarrowFusion.Bonelab.Patching.SimpleGripEventsPatches");
Type type3 = assembly.GetType("MarrowFusion.Bonelab.Messages.SimpleGripEventType");
if (type == null || type2 == null || type3 == null)
{
return;
}
object obj = type.GetField("Cache", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
if (obj == null)
{
return;
}
MethodInfo methodInfo = obj.GetType().GetMethods().First((MethodInfo method) => method.Name == "TryGet" && method.GetParameters().Length == 2);
object[] array = new object[2] { source, null };
if (!(bool)methodInfo.Invoke(obj, array))
{
return;
}
object obj2 = array[1];
NetworkEntity val = (NetworkEntity)((obj2 is NetworkEntity) ? obj2 : null);
if (val == null)
{
return;
}
object extender = val.GetExtender(type);
if (extender != null)
{
object obj3 = extender.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).First((MethodInfo method) => method.Name == "GetIndex" && method.GetParameters().Length == 1)
.Invoke(extender, new object[1] { source });
if (obj3 != null)
{
byte b = checked((byte)Convert.ToInt32(obj3));
object obj4 = Enum.Parse(type3, eventName);
type2.GetMethod("SendGripEvent", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, new object[3] { val.ID, b, obj4 });
}
}
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Local avatar event worked, but Fusion relay failed: " + ex.Message);
}
}
private static int ClampLine(int value)
{
return Math.Clamp(value, 1, 30);
}
private static string LineId(int line)
{
return $"PR_{line:000}";
}
private static Transform FindDeep(Transform parent, string objectName)
{
foreach (Transform componentsInChild in ((Component)parent).GetComponentsInChildren<Transform>(true))
{
if (((Object)componentsInChild).name == objectName)
{
return componentsInChild;
}
}
return null;
}
}