diff --git a/CCK.Debugger/Config.cs b/CCK.Debugger/Config.cs index ed6a73e..e62e223 100644 --- a/CCK.Debugger/Config.cs +++ b/CCK.Debugger/Config.cs @@ -1,6 +1,4 @@ -using ABI_RC.Core.InteractionSystem; -using Kafe.CCK.Debugger.Components; -using Kafe.CCK.Debugger.Properties; +using Kafe.CCK.Debugger.Components; using MelonLoader; namespace Kafe.CCK.Debugger; @@ -27,33 +25,4 @@ public static void InitializeMelonPrefs() { Core.PinToQuickMenu(); }); } - - public static void InitializeBTKUI() { - BTKUILib.QuickMenuAPI.OnMenuRegenerate += LoadBTKUILib; - } - - private static void LoadBTKUILib(CVR_MenuManager manager) { - BTKUILib.QuickMenuAPI.OnMenuRegenerate -= LoadBTKUILib; - - var miscPage = BTKUILib.QuickMenuAPI.MiscTabPage; - var miscCategory = miscPage.AddCategory(AssemblyInfoParams.Name); - - var pinButtonBTKUI = miscCategory.AddButton("Pin To Quick Menu", "", - "Pins the Menu back to quick menu. Useful if you lost your menu :)"); - - pinButtonBTKUI.OnPress += Core.PinToQuickMenu; - - var hideMenuToggle = miscCategory.AddToggle("Hide the Menu", - "Whether to completely hide the CCK Debugger Menu or not.", - MeIsHidden.Value); - - hideMenuToggle.OnValueUpdated += b => { - if (b != MeIsHidden.Value) MeIsHidden.Value = b; - }; - - MeIsHidden.OnEntryValueChanged.Subscribe((oldValue, newValue) => { - if (newValue != hideMenuToggle.ToggleValue) hideMenuToggle.ToggleValue = newValue; - }); - } - } diff --git a/CCK.Debugger/Integrations/BTKUILibIntegration.cs b/CCK.Debugger/Integrations/BTKUILibIntegration.cs new file mode 100644 index 0000000..7e6bdd2 --- /dev/null +++ b/CCK.Debugger/Integrations/BTKUILibIntegration.cs @@ -0,0 +1,37 @@ +using ABI_RC.Core.InteractionSystem; +using Kafe.CCK.Debugger.Components; +using Kafe.CCK.Debugger.Properties; + +namespace Kafe.CCK.Debugger.Integrations; + +public static class BTKUILibIntegration { + + public static void InitializeBTKUI() { + BTKUILib.QuickMenuAPI.OnMenuRegenerate += LoadBTKUILib; + } + + private static void LoadBTKUILib(CVR_MenuManager manager) { + BTKUILib.QuickMenuAPI.OnMenuRegenerate -= LoadBTKUILib; + + var miscPage = BTKUILib.QuickMenuAPI.MiscTabPage; + var miscCategory = miscPage.AddCategory(AssemblyInfoParams.Name); + + var pinButtonBTKUI = miscCategory.AddButton("Pin To Quick Menu", "", + "Pins the Menu back to quick menu. Useful if you lost your menu :)"); + + pinButtonBTKUI.OnPress += Core.PinToQuickMenu; + + var hideMenuToggle = miscCategory.AddToggle("Hide the Menu", + "Whether to completely hide the CCK Debugger Menu or not.", + Config.MeIsHidden.Value); + + hideMenuToggle.OnValueUpdated += b => { + if (b != Config.MeIsHidden.Value) Config.MeIsHidden.Value = b; + }; + + Config.MeIsHidden.OnEntryValueChanged.Subscribe((oldValue, newValue) => { + if (newValue != hideMenuToggle.ToggleValue) hideMenuToggle.ToggleValue = newValue; + }); + } + +} diff --git a/CCK.Debugger/Main.cs b/CCK.Debugger/Main.cs index 88b76e3..6de5d24 100644 --- a/CCK.Debugger/Main.cs +++ b/CCK.Debugger/Main.cs @@ -8,6 +8,7 @@ using HarmonyLib; using Kafe.CCK.Debugger.Components; using Kafe.CCK.Debugger.Components.GameObjectVisualizers; +using Kafe.CCK.Debugger.Properties; using MelonLoader; using UnityEngine; @@ -74,9 +75,9 @@ public override void OnInitializeMelon() { } // Check for BTKUILib - if (RegisteredMelons.Any(m => m.Info.Name == "BTKUILib")) { + if (RegisteredMelons.Any(m => m.Info.Name == AssemblyInfoParams.BTKUILibName)) { MelonLogger.Msg($"Detected BTKUILib mod, we're adding the integration!"); - Config.InitializeBTKUI(); + Integrations.BTKUILibIntegration.InitializeBTKUI(); } else { MelonLogger.Warning("We optionally support BTKUILib, it allows to restore the menu to the quick menu. Consider installing the BTKUILib Mod."); diff --git a/CCK.Debugger/Properties/AssemblyInfo.cs b/CCK.Debugger/Properties/AssemblyInfo.cs index 209304d..2c3f450 100644 --- a/CCK.Debugger/Properties/AssemblyInfo.cs +++ b/CCK.Debugger/Properties/AssemblyInfo.cs @@ -22,11 +22,13 @@ [assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] [assembly: MelonColor(ConsoleColor.Green)] [assembly: MelonAuthorColor(ConsoleColor.DarkYellow)] -[assembly: MelonOptionalDependencies("BTKUILib")] +[assembly: MelonOptionalDependencies(AssemblyInfoParams.BTKUILibName)] +//[assembly: MelonAdditionalCredits(AssemblyInfoParams.AstroDoge)] Needs ML 6.1 namespace Kafe.CCK.Debugger.Properties; internal static class AssemblyInfoParams { public const string Version = "2.0.2"; public const string Author = "kafeijao"; public const string Name = "CCK.Debugger"; + public const string BTKUILibName = "BTKUILib"; } diff --git a/ChatBox/HistoryBehavior.cs b/ChatBox/HistoryBehavior.cs index cf3f8af..17b0710 100644 --- a/ChatBox/HistoryBehavior.cs +++ b/ChatBox/HistoryBehavior.cs @@ -28,6 +28,9 @@ public class HistoryBehavior : MonoBehaviour { public static readonly Color ColorPink = new Color(.9882f, .2f, .5f); public static readonly Color ColorGreen = new Color(.2f, 1f, .2f); + public static readonly Color ColorBackground = new Color(0f, 0f, 0f, 0.749f); + public static readonly Color ColorBTKUIMenuBackground = new Color(41f / 255f, 41f / 255f, 41f / 255f, 1f); + private const float TimestampFontSizeModifier = 1.125f; private const float UsernameFontSizeModifier = 1.5625f; @@ -47,6 +50,7 @@ public class HistoryBehavior : MonoBehaviour { // Main Sub-Components private GameObject _togglesView; + private Image _togglesViewBackground; private GameObject _header; private TextMeshProUGUI _titleText; private GameObject _scrollView; @@ -54,6 +58,7 @@ public class HistoryBehavior : MonoBehaviour { // Power Toggle private Toggle _powerToggle; + private Image _powerBackground; private Image _powerImage; // Message Button @@ -132,6 +137,7 @@ internal void ParentTo(MenuTarget targetType) { menuControllerTransform.SetParent(_quickMenuGo.transform, true); if (ModConfig.MeHistoryWindowOnCenter.Value) { menuControllerTransform.localPosition = new Vector3(-0.05f, -0.055f, -0.001f); + ModConfig.MeHistoryWindowOpened.Value = true; } else { menuControllerTransform.localPosition = new Vector3(0.86f, -0.095f, 0f); @@ -171,6 +177,11 @@ internal void ParentTo(MenuTarget targetType) { } private void UpdateButtonStates() { + var attachedToBTKUI = _currentMenuParent == MenuTarget.QuickMenu && ModConfig.MeHistoryWindowOnCenter.Value; + _powerImage.enabled = !attachedToBTKUI; + _powerToggle.enabled = !attachedToBTKUI; + _powerBackground.color = attachedToBTKUI ? ColorBTKUIMenuBackground : ColorBackground; + _togglesViewBackground.color = attachedToBTKUI ? ColorBTKUIMenuBackground : ColorBackground; _powerToggle.SetIsOnWithoutNotify(ModConfig.MeHistoryWindowOpened.Value); _powerImage.color = _powerToggle.isOn ? ColorPink : Color.white; @@ -247,6 +258,7 @@ private void Awake() { // Grab Main Sub-Components _togglesView = _rootRectTransform.Find("TogglesView").gameObject; + _togglesViewBackground = _togglesView.GetComponent(); _header = _rootRectTransform.Find("Header").gameObject; _titleText = _rootRectTransform.Find("Header/Title").GetComponent(); _scrollView = _rootRectTransform.Find("Scroll View").gameObject; @@ -258,6 +270,7 @@ private void Awake() { // Power Toggle _powerToggle = _rootRectTransform.Find("PowerToggle").GetComponent(); + _powerBackground = _powerToggle.transform.Find("Background").GetComponent(); _powerImage = _rootRectTransform.Find("PowerToggle/Checkmark").GetComponent(); _powerToggle.onValueChanged.AddListener(ToggleHistoryWindow); ModConfig.MeHistoryWindowOpened.OnEntryValueChanged.Subscribe((oldValue, newValue) => { diff --git a/ChatBox/ModNetwork.cs b/ChatBox/ModNetwork.cs index 50091ac..aa66366 100644 --- a/ChatBox/ModNetwork.cs +++ b/ChatBox/ModNetwork.cs @@ -44,6 +44,7 @@ internal static void SendTyping(API.MessageSource source, bool isTyping, bool no } internal static void SendMessage(API.MessageSource source, string modName, string msg, bool notification, bool displayInChatBox, bool displayInHistory) { + if (string.IsNullOrEmpty(msg)) return; if (modName.Length > ModNameCharactersMaxCount) { MelonLogger.Warning($"Mod Name can have a maximum of {ModNameCharactersMaxCount} characters."); return; diff --git a/RealisticFlight/ActionDetector.cs b/RealisticFlight/ActionDetector.cs index add1730..da3f353 100644 --- a/RealisticFlight/ActionDetector.cs +++ b/RealisticFlight/ActionDetector.cs @@ -27,6 +27,7 @@ public class ActionDetector : MonoBehaviour { private const float ArmAngleMinThreshold = 55f; private const float ArmAngleMinBreakThreshold = 30f; + private const float ArmAngleMaxBreakThreshold = 150f; private const float ArmsAlignmentMinAngle = 135f; private const float WristTwistThreshold = 0.30f; @@ -34,6 +35,7 @@ public class ActionDetector : MonoBehaviour { private Transform _head; private Transform _neck; private Transform _hips; + private Transform _spine; public static Action Flapped; public static Action Gliding; @@ -229,6 +231,7 @@ private void Start() { _head = animator.GetBoneTransform(HumanBodyBones.Head); _neck = animator.GetBoneTransform(HumanBodyBones.Neck); _hips = animator.GetBoneTransform(HumanBodyBones.Hips); + _spine = animator.GetBoneTransform(HumanBodyBones.Spine); var lArmTransform = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm); var lElbowTransform = animator.GetBoneTransform(HumanBodyBones.LeftLowerArm); @@ -302,8 +305,8 @@ private void ProcessHandFlap(HandInfo handInfo) { switch (handInfo.FlapState) { case FlapState.Idle: - // Check if our hands are above our head - if (handInfo.HandTransform.position.y > _head.position.y) { + // Check if our hands are above our head, or we're gliding + if (handInfo.HandTransform.position.y > _head.position.y || (_isGliding && handInfo.HandTransform.position.y > _spine.position.y)) { handInfo.FlapState = FlapState.StartingFlap; } @@ -311,7 +314,7 @@ private void ProcessHandFlap(HandInfo handInfo) { case FlapState.StartingFlap: // Check if our hands stop being above our head, which means we start the flap - if (handInfo.HandTransform.position.y <= _head.position.y) { + if (handInfo.HandTransform.position.y <= _head.position.y || (_isGliding && handInfo.HandTransform.position.y > _spine.position.y)) { handInfo.FlapStartedTime = Time.time; var handPosition = handInfo.HandTransform.position; handInfo.InitialPositionFromAvatar = PlayerSetup.Instance._avatar.transform.InverseTransformPoint(handPosition); @@ -337,7 +340,7 @@ private void ProcessHandFlap(HandInfo handInfo) { handInfo.DistanceFlapped += Vector3.Distance(handInfo.PreviousPosition, currentHandPosition); handInfo.PreviousPosition = currentHandPosition; // Check if our hands are under our Hips - if (handInfo.HandTransform.position.y < _hips.position.y) { + if (handInfo.HandTransform.position.y < _hips.position.y || (_isGliding && handInfo.HandTransform.position.y < _spine.position.y)) { handInfo.FlapState = FlapState.Flapped; // Calculate the flap velocity by using the accumulated flapped distance across the time it took handInfo.FlapVelocity = handInfo.DistanceFlapped / (Time.time - handInfo.FlapStartedTime); @@ -357,6 +360,8 @@ private void ProcessHandFlap(HandInfo handInfo) { } } + private bool _isGliding; + private void ProcessHandsGlide(HandInfo leftHandInfo, HandInfo rightHandInfo) { // Update Human Pose @@ -387,15 +392,12 @@ private void ProcessHandsGlide(HandInfo leftHandInfo, HandInfo rightHandInfo) { float x; if (ModConfig.MeGlidingRotationLikeAirfoils.Value) { - x = leftWristTwist - rightWristTwist; + x = rightWristTwist - leftWristTwist; x *= ModConfig.MeRotationAirfoilsSensitivity.Value; } else { var leftArmNormalized = Mathf.Lerp(-1, 1, Mathf.InverseLerp(ArmAngleMinThreshold, ArmAngleMaxThreshold, Mathf.Clamp(leftArmDownUp, ArmAngleMinThreshold, ArmAngleMaxThreshold))); - // Calculate normalized arm down up. - // var leftArmNormalized = leftArmDownUp / ArmDownUpThreshold; // values range from -1 to +1 var rightArmNormalized = Mathf.Lerp(1, -1, Mathf.InverseLerp(ArmAngleMinThreshold, ArmAngleMaxThreshold, Mathf.Clamp(rightArmDownUp, ArmAngleMinThreshold, ArmAngleMaxThreshold))); - // var rightArmNormalized = -rightArmDownUp / ArmDownUpThreshold; // values range from -1 to +1, inverted for right arm x = (leftArmNormalized + rightArmNormalized) / 2f * 0.5f; } @@ -409,25 +411,33 @@ private void ProcessHandsGlide(HandInfo leftHandInfo, HandInfo rightHandInfo) { && leftWristTwist is <= WristTwistThreshold and >= -WristTwistThreshold && rightWristTwist is <= WristTwistThreshold and >= -WristTwistThreshold; - if (!isGrounded && armsStretched && armsAligned && armsAngled) { - Gliding?.Invoke(true, glidingVector); - if (_leftHandInfo.GlideState != GlideState.Gliding || _rightHandInfo.GlideState != GlideState.Gliding) { - _leftHandInfo.GlideState = GlideState.Gliding; - _rightHandInfo.GlideState = GlideState.Gliding; - } + var isProperGliding = armsStretched && armsAligned && armsAngled; + + // Handle the arms up/down settings + var isJankyGliding = false; + var bothArmsDown = leftArmDownUp < ArmAngleMinBreakThreshold && rightArmDownUp < ArmAngleMinBreakThreshold; + var bothArmsUp = leftArmDownUp > ArmAngleMaxBreakThreshold && rightArmDownUp > ArmAngleMaxBreakThreshold; + if (ModConfig.MeBothArmsDownToStopGliding.Value && ModConfig.MeBothArmsUpToStopGliding.Value) { + isJankyGliding = _isGliding && !bothArmsDown && !bothArmsUp; } - // Is currently gliding, to stop both arms need to go down - else if (ModConfig.MeBothArmsDownToStoGliding.Value && !isGrounded - && _leftHandInfo.GlideState == GlideState.Gliding && _rightHandInfo.GlideState == GlideState.Gliding - && (leftArmDownUp > ArmAngleMinBreakThreshold || rightArmDownUp > ArmAngleMinBreakThreshold)) { + else if (ModConfig.MeBothArmsDownToStopGliding.Value) { + isJankyGliding = _isGliding && !bothArmsDown; + } + else if (ModConfig.MeBothArmsUpToStopGliding.Value) { + isJankyGliding = _isGliding && !bothArmsUp; + } + + if (!isGrounded && (isProperGliding || isJankyGliding)) { Gliding?.Invoke(true, glidingVector); + _isGliding = true; + _leftHandInfo.GlideState = GlideState.Gliding; + _rightHandInfo.GlideState = GlideState.Gliding; } else { Gliding?.Invoke(false, glidingVector); - if (_leftHandInfo.GlideState != GlideState.Idle || _rightHandInfo.GlideState != GlideState.Idle) { - _leftHandInfo.GlideState = GlideState.Idle; - _rightHandInfo.GlideState = GlideState.Idle; - } + _isGliding = false; + _leftHandInfo.GlideState = GlideState.Idle; + _rightHandInfo.GlideState = GlideState.Idle; } #if DEBUG diff --git a/RealisticFlight/FlightController.cs b/RealisticFlight/FlightController.cs index 9b1f233..2ac8deb 100644 --- a/RealisticFlight/FlightController.cs +++ b/RealisticFlight/FlightController.cs @@ -39,19 +39,28 @@ private void Flap(float leftVelocity, Vector3 leftFlapDirection, float rightVelo globalRightFlapDirection.x *= ModConfig.MeFlapMultiplierHorizontal.Value; globalRightFlapDirection.z *= ModConfig.MeFlapMultiplierHorizontal.Value; - // Use gravity to take off the floor, use half a jump height as a baseline - MovementSystem.Instance._appliedGravity.y = Mathf.Sqrt(movementSystem.jumpHeight * movementSystem.gravity); - MovementSystem.Instance._gravityVelocity = 0f; - // Set the inherited velocity to be this opposite movement direction var leftVelocityVector = globalLeftFlapDirection * leftVelocity; var rightVelocityVector = globalRightFlapDirection * rightVelocity; var totalVelocityVector = leftVelocityVector + rightVelocityVector; - var flapMultiplier = ModConfig.MeUseAvatarOverrides.Value - ? ConfigJson.GetCurrentAvatarFlapModifier() - : ModConfig.MeFlapMultiplier.Value; - movementSystem._inheritVelocity += totalVelocityVector * flapMultiplier * (MetaPort.Instance.isUsingVr ? 2.5f : 1f); + var flapMultiplier = ConfigJson.GetCurrentAvatarFlapModifier(); + + var velocityToAdd = totalVelocityVector * flapMultiplier * (MetaPort.Instance.isUsingVr ? 2.5f : 1f); + + // If we're not gliding make it go up + if (!_previousGlide) { + // Use gravity to take off the floor, use half a jump height as a baseline + MovementSystem.Instance._appliedGravity.y = Mathf.Sqrt(movementSystem.jumpHeight * movementSystem.gravity); + MovementSystem.Instance._gravityVelocity = 0f; + } + // If it's already gliding, add to the last velocity + else { + var localVelocity = PlayerSetup.Instance._avatar.transform.InverseTransformDirection(velocityToAdd); + _lastVelocity += localVelocity.z; + } + + movementSystem._inheritVelocity += velocityToAdd; // Handle the parameter IsGliding if (_triggerJustFlappedCoroutine != null) StopCoroutine(_triggerJustFlappedCoroutine); diff --git a/RealisticFlight/Integrations/BTKUILibIntegration.cs b/RealisticFlight/Integrations/BTKUILibIntegration.cs index 89fcbb9..f77a2f5 100644 --- a/RealisticFlight/Integrations/BTKUILibIntegration.cs +++ b/RealisticFlight/Integrations/BTKUILibIntegration.cs @@ -23,7 +23,8 @@ private static void LoadBTKUILib(CVR_MenuManager manager) { AddMelonToggle(miscCategory, ModConfig.MeCustomFlightInDesktop, "Enabled in Desktop"); AddMelonToggle(miscCategory, ModConfig.MeCustomFlightInVR, "Enabled in VR"); - AddMelonToggle(miscCategory, ModConfig.MeBothArmsDownToStoGliding, "Arms down to stop Gliding"); + AddMelonToggle(miscCategory, ModConfig.MeBothArmsDownToStopGliding, "Arms down to stop Gliding"); + AddMelonToggle(miscCategory, ModConfig.MeBothArmsUpToStopGliding, "Arms up to stop Gliding"); var advancedPage = miscCategory.AddPage("Advanced Settings", icon, "Advanced settings for realistic flight.", nameof(RealisticFlight)); var general = advancedPage.AddCategory("General"); diff --git a/RealisticFlight/ModConfig.cs b/RealisticFlight/ModConfig.cs index dbe90bd..1a080b1 100644 --- a/RealisticFlight/ModConfig.cs +++ b/RealisticFlight/ModConfig.cs @@ -33,7 +33,8 @@ public static class ModConfig { internal static MelonPreferences_Entry MeUseAvatarOverrides; - internal static MelonPreferences_Entry MeBothArmsDownToStoGliding; + internal static MelonPreferences_Entry MeBothArmsDownToStopGliding; + internal static MelonPreferences_Entry MeBothArmsUpToStopGliding; public static void InitializeMelonPrefs() { @@ -61,9 +62,12 @@ public static void InitializeMelonPrefs() { MeRotationAirfoilsSensitivity = _melonCategory.CreateEntry("RotationAirfoilsSensitivity", 1f, description: "Rotation sensitivity of the Airfoils, 1 should be the default."); - MeBothArmsDownToStoGliding = _melonCategory.CreateEntry("BothArmsDownToStoGliding", false, + MeBothArmsDownToStopGliding = _melonCategory.CreateEntry("BothArmsDownToStopGliding", false, description: "Whether you need to put both arms down to stop flying or not. Might make it harder to unintentional gliding disable."); + MeBothArmsUpToStopGliding = _melonCategory.CreateEntry("BothArmsUpToStopGliding", false, + description: "Whether you need to put both arms up to stop flying or not. Might make it harder to unintentional gliding disable."); + // Max Applied Velocity Settings MeMaxAppliedVelocity = _melonCategory.CreateEntry("MaxAppliedVelocity", 10000f, description: "Maximum value of the magnitude of the velocity a player can have. Game defaults to 10000.",