From 1865df1692d21c7917abb275837efc0881e20ec1 Mon Sep 17 00:00:00 2001 From: killzoms Date: Sun, 13 Aug 2023 09:01:40 -0400 Subject: [PATCH 01/19] overhaul movment --- .../Processors/PlayerMovementProcessor.cs | 11 +-- .../Processors/VehicleDockingProcessor.cs | 4 +- .../Processors/VehicleUndockingProcessor.cs | 4 +- .../PlayerPositionInitialSyncProcessor.cs | 11 +-- NitroxClient/GameLogic/LocalPlayer.cs | 2 +- NitroxClient/GameLogic/RemotePlayer.cs | 45 +++++++----- NitroxClient/GameLogic/Vehicles.cs | 9 ++- .../{GameLogic => Helpers}/MovementHelper.cs | 6 +- .../MonoBehaviours/AnimationController.cs | 8 +-- .../MonoBehaviours/MovementController.cs | 69 +++++++++++++++++++ .../MonoBehaviours/MultiplayerExosuit.cs | 3 +- .../MultiplayerVehicleControl.cs | 37 ++++------ .../PlayerMovementBroadcaster.cs | 34 +++------ .../GameLogic/ExoSuitMovementData.cs | 6 +- .../Helper/VehicleMovementFactory.cs | 6 +- .../GameLogic/BasicVehicleMovementData.cs | 6 +- .../GameLogic/VehicleMovementData.cs | 22 +++--- .../DataStructures/Unity/NitroxTransform.cs | 24 +++++-- NitroxModel/Packets/Movement.cs | 3 +- NitroxModel/Packets/PlayerMovement.cs | 6 +- NitroxModel/Packets/VehicleMovement.cs | 4 +- .../Dynamic/FMOD_CustomEmitter_Start_Patch.cs | 4 +- .../VehicleMovementPacketProcessor.cs | 3 +- 23 files changed, 182 insertions(+), 145 deletions(-) rename NitroxClient/{GameLogic => Helpers}/MovementHelper.cs (94%) create mode 100644 NitroxClient/MonoBehaviours/MovementController.cs diff --git a/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs index 896f965556..6dc6082d8c 100644 --- a/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; @@ -26,14 +26,7 @@ public override void Process(PlayerMovement movement) return; } - Multiplayer.Main.StartCoroutine(QueueForFixedUpdate(remotePlayer.Value, movement)); - } - - private IEnumerator QueueForFixedUpdate(RemotePlayer player, PlayerMovement movement) - { - yield return Yielders.WaitForFixedUpdate; - player.UpdatePosition(movement.Position.ToUnity(), - movement.Velocity.ToUnity(), + remotePlayer.Value.UpdatePosition(movement.Position.ToUnity(), movement.BodyRotation.ToUnity(), movement.AimingRotation.ToUnity()); } diff --git a/NitroxClient/Communication/Packets/Processors/VehicleDockingProcessor.cs b/NitroxClient/Communication/Packets/Processors/VehicleDockingProcessor.cs index 5031f2f62b..9134402c0e 100644 --- a/NitroxClient/Communication/Packets/Processors/VehicleDockingProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/VehicleDockingProcessor.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using NitroxClient.Communication.Abstract; using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxClient.GameLogic; @@ -32,7 +32,7 @@ public override void Process(VehicleDocking packet) using (PacketSuppressor.Suppress()) { Log.Debug($"Set vehicle docked for {vehicleDockingBay.gameObject.name}"); - vehicle.GetComponent().SetPositionVelocityRotation(vehicle.transform.position, Vector3.zero, vehicle.transform.rotation, Vector3.zero); + vehicle.GetComponent().SetPositionRotation(vehicle.transform.position, vehicle.transform.rotation); vehicle.GetComponent().Exit(); } vehicle.StartCoroutine(DelayAnimationAndDisablePiloting(vehicle, vehicleDockingBay, packet.VehicleId, packet.PlayerId)); diff --git a/NitroxClient/Communication/Packets/Processors/VehicleUndockingProcessor.cs b/NitroxClient/Communication/Packets/Processors/VehicleUndockingProcessor.cs index 2f216ab825..998f4cea52 100644 --- a/NitroxClient/Communication/Packets/Processors/VehicleUndockingProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/VehicleUndockingProcessor.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using NitroxClient.Communication.Abstract; using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxClient.GameLogic; @@ -56,7 +56,7 @@ private void StartVehicleUndocking(VehicleUndocking packet, GameObject vehicleGo vehicle.mainAnimator.SetBool("player_in", true); playerInstance.Attach(vehicle.playerPosition.transform); // It can happen that the player turns in circles around himself in the vehicle. This stops it. - playerInstance.RigidBody.angularVelocity = Vector3.zero; + // playerInstance.RigidBody.angularVelocity = Vector3.zero; // May not happen anymore needs verifying playerInstance.ArmsController.SetWorldIKTarget(vehicle.leftHandPlug, vehicle.rightHandPlug); playerInstance.AnimationController["in_seamoth"] = vehicle is SeaMoth; playerInstance.AnimationController["in_exosuit"] = playerInstance.AnimationController["using_mechsuit"] = vehicle is Exosuit; diff --git a/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs b/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs index d7411fae0a..2ad4414060 100644 --- a/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs +++ b/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs @@ -78,14 +78,9 @@ public override IEnumerator Process(InitialPlayerSync packet, WaitScreen.ManualW yield break; } - Transform rootTransform = subRoot.transform; - Quaternion vehicleAngle = rootTransform.rotation; - // "position" is a relative position and "positionInVehicle" an absolute position - Vector3 positionInVehicle = vehicleAngle * position + rootTransform.position; - Player.main.SetPosition(positionInVehicle, rotation * vehicleAngle); - Player.main.cinematicModeActive = false; - Player.main.UpdateIsUnderwater(); - } + Player.main.cinematicModeActive = false; + Player.main.UpdateIsUnderwater(); + } private void AttachPlayerToEscapePod(NitroxId escapePodId) { diff --git a/NitroxClient/GameLogic/LocalPlayer.cs b/NitroxClient/GameLogic/LocalPlayer.cs index 5264b81818..d4110427a4 100644 --- a/NitroxClient/GameLogic/LocalPlayer.cs +++ b/NitroxClient/GameLogic/LocalPlayer.cs @@ -57,7 +57,7 @@ public void BroadcastLocation(Vector3 location, Vector3 velocity, Quaternion bod } else { - movement = new PlayerMovement(PlayerId, location.ToDto(), velocity.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto()); + movement = new PlayerMovement(PlayerId, location.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto()); } packetSender.Send(movement); diff --git a/NitroxClient/GameLogic/RemotePlayer.cs b/NitroxClient/GameLogic/RemotePlayer.cs index 2fbfc5d676..c805362b1b 100644 --- a/NitroxClient/GameLogic/RemotePlayer.cs +++ b/NitroxClient/GameLogic/RemotePlayer.cs @@ -32,6 +32,7 @@ public class RemotePlayer : INitroxPlayer public ItemsContainer Inventory { get; private set; } public Transform ItemAttachPoint { get; private set; } public RemotePlayerVitals vitals { get; private set; } + public MovementController MovementController { get; private set; } public ushort PlayerId => PlayerContext.PlayerId; public string PlayerName => PlayerContext.PlayerName; @@ -61,6 +62,9 @@ public void InitializeGameObject(GameObject playerBody) RigidBody = Body.AddComponent(); RigidBody.useGravity = false; RigidBody.interpolation = RigidbodyInterpolation.Interpolate; + RigidBody.isKinematic = true; + MovementController = Body.EnsureComponent(); + MovementController.AfterUpdate += OnUpdate; NitroxEntity.SetNewId(Body, PlayerContext.PlayerNitroxId); @@ -109,27 +113,27 @@ public void Detach() SkyEnvironmentChanged.Broadcast(Body, (GameObject)null); } - public void UpdatePosition(Vector3 position, Vector3 velocity, Quaternion bodyRotation, Quaternion aimingRotation) + public void UpdatePosition(Vector3 position, Quaternion bodyRotation, Quaternion aimingRotation) { Body.SetActive(true); - - // When receiving movement packets, a player can not be controlling a vehicle (they can walk through subroots though). SetVehicle(null); SetPilotingChair(null); - // If in a subroot the position will be relative to the subroot - if (SubRoot && !SubRoot.isBase) - { - Quaternion vehicleAngle = SubRoot.transform.rotation; - position = vehicleAngle * position; - position += SubRoot.transform.position; - bodyRotation = vehicleAngle * bodyRotation; - aimingRotation = vehicleAngle * aimingRotation; - } - RigidBody.velocity = AnimationController.Velocity = MovementHelper.GetCorrectedVelocity(position, velocity, Body, Time.fixedDeltaTime * (PlayerMovementBroadcaster.LOCATION_BROADCAST_TICK_SKIPS + 1)); - RigidBody.angularVelocity = MovementHelper.GetCorrectedAngularVelocity(bodyRotation, Vector3.zero, Body, Time.fixedDeltaTime * (PlayerMovementBroadcaster.LOCATION_BROADCAST_TICK_SKIPS + 1)); + + MovementController.enabled = true; + + MovementController.TargetPosition = position; + MovementController.TargetRotation = bodyRotation; AnimationController.AimingRotation = aimingRotation; - AnimationController.UpdatePlayerAnimations = true; + } + + private void OnUpdate() + { + if (!Vehicle && !PilotingChair) + { + AnimationController.Velocity = MovementController.Velocity; + AnimationController.UpdatePlayerAnimations = true; + } } public void SetPilotingChair(PilotingChair newPilotingChair) @@ -137,6 +141,7 @@ public void SetPilotingChair(PilotingChair newPilotingChair) if (PilotingChair != newPilotingChair) { PilotingChair = newPilotingChair; + bool isInPilotingChair = newPilotingChair != null; MultiplayerCyclops mpCyclops = null; @@ -170,7 +175,9 @@ public void SetPilotingChair(PilotingChair newPilotingChair) } } - RigidBody.isKinematic = AnimationController["cyclops_steering"] = newPilotingChair != null; + RigidBody.isKinematic = AnimationController["cyclops_steering"] = isInPilotingChair; + RigidBody.interpolation = isInPilotingChair ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate; + MovementController.enabled = !isInPilotingChair; } } @@ -243,10 +250,12 @@ public void SetVehicle(Vehicle newVehicle) } } - RigidBody.isKinematic = newVehicle; - Vehicle = newVehicle; + RigidBody.interpolation = Vehicle ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate; + RigidBody.isKinematic = Vehicle; + MovementController.enabled = !Vehicle; + AnimationController["in_seamoth"] = newVehicle is SeaMoth; AnimationController["in_exosuit"] = AnimationController["using_mechsuit"] = newVehicle is Exosuit; } diff --git a/NitroxClient/GameLogic/Vehicles.cs b/NitroxClient/GameLogic/Vehicles.cs index ea0fd0d530..d45d21002e 100644 --- a/NitroxClient/GameLogic/Vehicles.cs +++ b/NitroxClient/GameLogic/Vehicles.cs @@ -82,11 +82,9 @@ public void UpdateVehiclePosition(VehicleMovementData vehicleModel, Optional()); + PilotingChair pilotingChair = subRoot.AliveOrNull()?.GetComponentInChildren(); + playerInstance.SetPilotingChair(pilotingChair); playerInstance.AnimationController.UpdatePlayerAnimations = false; } } diff --git a/NitroxClient/GameLogic/MovementHelper.cs b/NitroxClient/Helpers/MovementHelper.cs similarity index 94% rename from NitroxClient/GameLogic/MovementHelper.cs rename to NitroxClient/Helpers/MovementHelper.cs index 3e7e1433a0..ac54f81a9f 100644 --- a/NitroxClient/GameLogic/MovementHelper.cs +++ b/NitroxClient/Helpers/MovementHelper.cs @@ -1,6 +1,6 @@ -using UnityEngine; +using UnityEngine; -namespace NitroxClient.GameLogic +namespace NitroxClient.Helpers { public static class MovementHelper { @@ -69,7 +69,7 @@ public static Vector3 GetCorrectedAngularVelocity(Quaternion remoteRotation, Vec // Here I drop down to 0.9f times the desired movement, // since we'd rather undershoot and ease into the correct angle // than overshoot and oscillate around it in the event of errors. - return (.9f * Mathf.Deg2Rad * angle / correctionTime) * axis + angularVelocty; + return .9f * Mathf.Deg2Rad * angle / correctionTime * axis + angularVelocty; } } } diff --git a/NitroxClient/MonoBehaviours/AnimationController.cs b/NitroxClient/MonoBehaviours/AnimationController.cs index 09fde7a211..da17a645ec 100644 --- a/NitroxClient/MonoBehaviours/AnimationController.cs +++ b/NitroxClient/MonoBehaviours/AnimationController.cs @@ -1,4 +1,4 @@ -using UnityEngine; +using UnityEngine; namespace NitroxClient.MonoBehaviours { @@ -23,13 +23,13 @@ public void Awake() this["is_underwater"] = true; } - public void FixedUpdate() + public void Update() { if (UpdatePlayerAnimations) { Vector3 rotationCorrectedVelocity = gameObject.transform.rotation.GetInverse() * Velocity; - smoothedVelocity = UWE.Utils.SlerpVector(smoothedVelocity, rotationCorrectedVelocity, Vector3.Normalize(rotationCorrectedVelocity - smoothedVelocity) * SMOOTHING_SPEED * Time.fixedDeltaTime); + smoothedVelocity = UWE.Utils.SlerpVector(smoothedVelocity, rotationCorrectedVelocity, Vector3.Normalize(rotationCorrectedVelocity - smoothedVelocity) * SMOOTHING_SPEED * Time.deltaTime); animator.SetFloat("move_speed", smoothedVelocity.magnitude); animator.SetFloat("move_speed_x", smoothedVelocity.x); @@ -43,7 +43,7 @@ public void FixedUpdate() } viewPitch = -viewPitch; - smoothViewPitch = Mathf.Lerp(smoothViewPitch, viewPitch, 4f * Time.fixedDeltaTime); + smoothViewPitch = Mathf.Lerp(smoothViewPitch, viewPitch, 4f * Time.deltaTime); animator.SetFloat("view_pitch", smoothViewPitch); } } diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MovementController.cs new file mode 100644 index 0000000000..3b26d2adaf --- /dev/null +++ b/NitroxClient/MonoBehaviours/MovementController.cs @@ -0,0 +1,69 @@ +using NitroxClient.GameLogic; +using Serilog.Events; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NitroxClient.MonoBehaviours +{ + public class MovementController : MonoBehaviour + { + public float Scalar { get; set; } = 1f; + public Vector3 TargetPosition { get; set; } + public Quaternion TargetRotation { get; set; } + public Transform TargetTransform { get; set; } + + public event Action BeforeUpdate = () => {}; + public event Action BeforeFixedUpdate = () => {}; + public event Action AfterUpdate = () => {}; + public event Action AfterFixedUpdate = () => {}; + + private Rigidbody rigidbody; + public Vector3 Velocity; + + private void Start() + { + rigidbody = GetComponent(); + } + + private void Update() + { + BeforeUpdate(); + if (!rigidbody) + { + transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, Scalar * Time.fixedDeltaTime); + transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, Scalar * Time.deltaTime); + } + AfterUpdate(); + } + + private void FixedUpdate() + { + BeforeFixedUpdate(); + if (rigidbody) + { + float timing = Scalar * Time.fixedDeltaTime; + Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, timing); + Quaternion newRot = Quaternion.Lerp(transform.rotation, TargetRotation, timing); + + if (rigidbody.isKinematic) + { + rigidbody.MovePosition(newPos); + rigidbody.MoveRotation(newRot); + } + else + { + rigidbody.velocity = Velocity; + + Quaternion delta = TargetRotation * transform.rotation.GetInverse(); + delta.ToAngleAxis(out float angle, out Vector3 axis); + rigidbody.angularVelocity = Mathf.Deg2Rad * angle / timing * axis; + } + } + AfterFixedUpdate(); + } + } +} diff --git a/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs b/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs index 1ca49d1ad2..ea8f493e08 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs @@ -1,4 +1,4 @@ -using NitroxClient.Unity.Smoothing; +using NitroxClient.Unity.Smoothing; using UnityEngine; namespace NitroxClient.MonoBehaviours @@ -15,7 +15,6 @@ protected override void Awake() WheelYawSetter = value => exosuit.steeringWheelYaw = value; WheelPitchSetter = value => exosuit.steeringWheelPitch = value; base.Awake(); - SmoothRotation = new ExosuitSmoothRotation(gameObject.transform.rotation); } internal override void Enter() diff --git a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs index f0bd70e127..ee4095aa52 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs @@ -1,4 +1,4 @@ -using System; +using System; using NitroxClient.GameLogic; using NitroxClient.Unity.Smoothing; using UnityEngine; @@ -7,28 +7,22 @@ namespace NitroxClient.MonoBehaviours { public abstract class MultiplayerVehicleControl : MonoBehaviour { - private Rigidbody rigidbody; + private MovementController movementController; protected readonly SmoothParameter SmoothYaw = new SmoothParameter(); protected readonly SmoothParameter SmoothPitch = new SmoothParameter(); protected readonly SmoothVector SmoothLeftArm = new SmoothVector(); protected readonly SmoothVector SmoothRightArm = new SmoothVector(); - protected SmoothVector SmoothPosition; - protected SmoothVector SmoothVelocity; - protected SmoothRotation SmoothRotation; - protected SmoothVector SmoothAngularVelocity; protected Action WheelYawSetter; protected Action WheelPitchSetter; protected virtual void Awake() { - rigidbody = gameObject.GetComponent(); + movementController = gameObject.EnsureComponent(); + // For now, we assume the set position and rotation is equal to the server one. - // Default velocities are probably empty, but set them anyway. - SmoothPosition = new SmoothVector(gameObject.transform.position); - SmoothVelocity = new SmoothVector(rigidbody.velocity); - SmoothRotation = new SmoothRotation(gameObject.transform.rotation); - SmoothAngularVelocity = new SmoothVector(rigidbody.angularVelocity); + movementController.TargetPosition = transform.position; + movementController.TargetRotation = transform.rotation; } protected virtual void FixedUpdate() @@ -36,25 +30,16 @@ protected virtual void FixedUpdate() SmoothYaw.FixedUpdate(); SmoothPitch.FixedUpdate(); - SmoothPosition.FixedUpdate(); - SmoothVelocity.FixedUpdate(); - rigidbody.isKinematic = false; // we should maybe find a way to remove UWE's FreezeRigidBodyWhenFar component...tried removing it but caused a bunch of issues. - rigidbody.velocity = MovementHelper.GetCorrectedVelocity(SmoothPosition.Current, SmoothVelocity.Current, gameObject, Time.fixedDeltaTime); - SmoothRotation.FixedUpdate(); - SmoothAngularVelocity.FixedUpdate(); - rigidbody.angularVelocity = MovementHelper.GetCorrectedAngularVelocity(SmoothRotation.Current, SmoothAngularVelocity.Current, gameObject, Time.fixedDeltaTime); - + WheelYawSetter(SmoothYaw.SmoothValue); WheelPitchSetter(SmoothPitch.SmoothValue); } - internal void SetPositionVelocityRotation(Vector3 remotePosition, Vector3 remoteVelocity, Quaternion remoteRotation, Vector3 remoteAngularVelocity) + internal void SetPositionRotation(Vector3 remotePosition, Quaternion remoteRotation) { gameObject.SetActive(true); - SmoothPosition.Target = remotePosition; - SmoothVelocity.Target = remoteVelocity; - SmoothRotation.Target = remoteRotation; - SmoothAngularVelocity.Target = remoteAngularVelocity; + movementController.TargetPosition = remotePosition; + movementController.TargetRotation = remoteRotation; } internal virtual void SetSteeringWheel(float yaw, float pitch) @@ -71,11 +56,13 @@ internal virtual void SetArmPositions(Vector3 leftArmPosition, Vector3 rightArmP internal virtual void Enter() { + movementController.enabled = true; enabled = true; } public virtual void Exit() { + movementController.enabled = false; enabled = false; } diff --git a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs index d2e02aea98..e5145de510 100644 --- a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs +++ b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs @@ -12,13 +12,13 @@ namespace NitroxClient.MonoBehaviours; public class PlayerMovementBroadcaster : MonoBehaviour { /// - /// Amount of physics updates to skip for sending location broadcasts. + /// Amount of time to skip for sending location broadcasts. /// TODO: Allow servers to set this value for clients. With many clients connected to the server, a higher value can be preferred. /// - public const int LOCATION_BROADCAST_TICK_SKIPS = 1; + public const float LOCATION_BROADCAST_TIME = 0.04f; private LocalPlayer localPlayer; - private int locationBroadcastSkipThreshold = LOCATION_BROADCAST_TICK_SKIPS; + private float nextLocationBroadcast; public void Awake() { @@ -27,13 +27,10 @@ public void Awake() public void FixedUpdate() { - // Throttle location broadcasts to not run on every physics tick. - if (locationBroadcastSkipThreshold-- > 0) + if (Time.fixedTime >= nextLocationBroadcast) { - return; + nextLocationBroadcast = Time.fixedTime + LOCATION_BROADCAST_TIME; } - // Reset skip threshold. - locationBroadcastSkipThreshold = LOCATION_BROADCAST_TICK_SKIPS; // Freecam does disable main camera control // But it's also disabled when driving the cyclops through a cyclops camera (content.activeSelf is only true when controlling through a cyclops camera) @@ -51,24 +48,11 @@ public void FixedUpdate() Quaternion aimingRotation = Player.main.camRoot.GetAimingTransform().rotation; Optional vehicle = GetVehicleMovement(); - SubRoot subRoot = Player.main.GetCurrentSub(); - - // If in a subroot the position will be relative to the subroot - if (subRoot && !subRoot.isBase) + if (Player.main.isPiloting) { - // Rotate relative player position relative to the subroot (else there are problems with respawning) - Transform subRootTransform = subRoot.transform; - Quaternion undoVehicleAngle = subRootTransform.rotation.GetInverse(); - currentPosition = currentPosition - subRootTransform.position; - currentPosition = undoVehicleAngle * currentPosition; - bodyRotation = undoVehicleAngle * bodyRotation; - aimingRotation = undoVehicleAngle * aimingRotation; - - if (Player.main.isPiloting && subRoot.isCyclops) - { - // In case you're driving the cyclops, the currentPosition is the real position of the player, so we need to send it to the server - vehicle.Value.DriverPosition = currentPosition.ToDto(); - } + // In case you're driving a vehicle, the currentPosition is the real position of the player, so we need to send it to the server + vehicle.Value.DriverPosition = currentPosition.ToDto(); + vehicle.Value.DriverRotation = Player.main.transform.rotation.ToDto(); } localPlayer.BroadcastLocation(currentPosition, playerVelocity, bodyRotation, aimingRotation, vehicle); diff --git a/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs b/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs index 30c2439329..4a85767bad 100644 --- a/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs +++ b/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.Serialization; using BinaryPack.Attributes; using NitroxModel.DataStructures; @@ -23,8 +23,8 @@ protected ExosuitMovementData() // Constructor for serialization. Has to be "protected" for json serialization. } - public ExosuitMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, NitroxVector3 velocity, NitroxVector3 angularVelocity, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3 leftAimTarget, NitroxVector3 rightAimTarget, NitroxVector3? driverPosition = null) - : base(techType, id, position, rotation, velocity, angularVelocity, steeringWheelYaw, steeringWheelPitch, appliedThrottle, driverPosition) + public ExosuitMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3 leftAimTarget, NitroxVector3 rightAimTarget, NitroxVector3 driverPosition = default, NitroxQuaternion driverRotation = default) + : base(techType, id, position, rotation, steeringWheelYaw, steeringWheelPitch, appliedThrottle, driverPosition, driverRotation) { LeftAimTarget = leftAimTarget; RightAimTarget = rightAimTarget; diff --git a/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs b/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs index e075a9bc2f..9f0a28189c 100644 --- a/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs +++ b/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs @@ -1,4 +1,4 @@ -using NitroxModel.DataStructures; +using NitroxModel.DataStructures; using NitroxModel.DataStructures.GameLogic; using NitroxModel_Subnautica.DataStructures; using NitroxModel_Subnautica.DataStructures.GameLogic; @@ -13,9 +13,9 @@ public static VehicleMovementData GetVehicleMovementData(TechType techType, Nitr switch (techType) { case TechType.Exosuit: - return new ExosuitMovementData(techType.ToDto(), id, position.ToDto(), rotation.ToDto(), velocity.ToDto(), angularVelocity.ToDto(), steeringWheelYaw, steeringWheelPitch, appliedThrottle, leftAimTarget.ToDto(), rightAimTarget.ToDto()); + return new ExosuitMovementData(techType.ToDto(), id, position.ToDto(), rotation.ToDto(), steeringWheelYaw, steeringWheelPitch, appliedThrottle, leftAimTarget.ToDto(), rightAimTarget.ToDto()); default: - return new BasicVehicleMovementData(techType.ToDto(), id, position.ToDto(), rotation.ToDto(), velocity.ToDto(), angularVelocity.ToDto(), steeringWheelYaw, steeringWheelPitch, appliedThrottle); + return new BasicVehicleMovementData(techType.ToDto(), id, position.ToDto(), rotation.ToDto(), steeringWheelYaw, steeringWheelPitch, appliedThrottle); } } } diff --git a/NitroxModel/DataStructures/GameLogic/BasicVehicleMovementData.cs b/NitroxModel/DataStructures/GameLogic/BasicVehicleMovementData.cs index aa073a2f40..6f83cb9b47 100644 --- a/NitroxModel/DataStructures/GameLogic/BasicVehicleMovementData.cs +++ b/NitroxModel/DataStructures/GameLogic/BasicVehicleMovementData.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.Serialization; using NitroxModel.DataStructures.Unity; @@ -11,6 +11,6 @@ public class BasicVehicleMovementData : VehicleMovementData public BasicVehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation) : base(techType, id, position, rotation) { } - public BasicVehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, NitroxVector3 velocity, NitroxVector3 angularVelocity, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3? driverPosition = null) : - base(techType, id, position, rotation, velocity, angularVelocity, steeringWheelYaw, steeringWheelPitch, appliedThrottle, driverPosition) { } + public BasicVehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3 driverPosition = default, NitroxQuaternion driverRotation = default) : + base(techType, id, position, rotation, steeringWheelYaw, steeringWheelPitch, appliedThrottle, driverPosition, driverRotation) { } } diff --git a/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs b/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs index 959aeb9afe..161092be16 100644 --- a/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs +++ b/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.Serialization; using BinaryPack.Attributes; using NitroxModel.DataStructures.Unity; @@ -21,12 +21,6 @@ public abstract class VehicleMovementData [DataMember(Order = 4)] public NitroxQuaternion Rotation { get; } - [DataMember(Order = 5)] - public NitroxVector3 Velocity { get; } - - [DataMember(Order = 6)] - public NitroxVector3 AngularVelocity { get; } - [DataMember(Order = 7)] public float SteeringWheelYaw { get; } @@ -37,7 +31,10 @@ public abstract class VehicleMovementData public bool AppliedThrottle { get; } [DataMember(Order = 10)] - public NitroxVector3? DriverPosition { get; set; } + public NitroxVector3 DriverPosition { get; set; } + + [DataMember(Order = 11)] + public NitroxQuaternion DriverRotation { get; set; } [IgnoreConstructor] protected VehicleMovementData() @@ -45,18 +42,17 @@ protected VehicleMovementData() // Constructor for serialization. Has to be "protected" for json serialization. } - public VehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, NitroxVector3 velocity, NitroxVector3 angularVelocity, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3? driverPosition = null) + public VehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3 driverPosition = default, NitroxQuaternion driverRotation = default) { TechType = techType; Id = id; Position = position; Rotation = rotation; - Velocity = velocity; - AngularVelocity = angularVelocity; SteeringWheelYaw = steeringWheelYaw; SteeringWheelPitch = steeringWheelPitch; AppliedThrottle = appliedThrottle; DriverPosition = driverPosition; + DriverRotation = driverRotation; } public VehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation) @@ -65,8 +61,6 @@ public VehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 p Id = id; Position = position; Rotation = rotation; - Velocity = NitroxVector3.Zero; - AngularVelocity = NitroxVector3.Zero; SteeringWheelYaw = 0f; SteeringWheelPitch = 0f; AppliedThrottle = false; @@ -74,7 +68,7 @@ public VehicleMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 p public override string ToString() { - return $"[VehicleMovementData - TechType: {TechType}, Id: {Id}, Position: {Position}, Rotation: {Rotation}, Velocity: {Velocity}, AngularVelocity: {AngularVelocity}, SteeringWheelYaw: {SteeringWheelYaw}, SteeringWheelPitch: {SteeringWheelPitch}, AppliedThrottle: {AppliedThrottle}]"; + return $"[VehicleMovementData - TechType: {TechType}, Id: {Id}, Position: {Position}, Rotation: {Rotation}, SteeringWheelYaw: {SteeringWheelYaw}, SteeringWheelPitch: {SteeringWheelPitch}, AppliedThrottle: {AppliedThrottle}, DriverPosition: {DriverPosition}]"; } } } diff --git a/NitroxModel/DataStructures/Unity/NitroxTransform.cs b/NitroxModel/DataStructures/Unity/NitroxTransform.cs index 259e3301bc..88bab69cee 100644 --- a/NitroxModel/DataStructures/Unity/NitroxTransform.cs +++ b/NitroxModel/DataStructures/Unity/NitroxTransform.cs @@ -23,7 +23,7 @@ public Matrix4x4 LocalToWorldMatrix { get { - Matrix4x4 cachedMatrix = Matrix4x4Extension.Compose(LocalPosition, LocalRotation, LocalScale); + Matrix4x4 cachedMatrix = Matrix4x4Extension.Compose(LocalPosition, LocalRotation, LocalScale); // its not cached yet return Parent != null ? cachedMatrix * Parent.LocalToWorldMatrix : cachedMatrix; } @@ -36,13 +36,11 @@ public NitroxVector3 Position { get { - Matrix4x4 matrix = Parent?.LocalToWorldMatrix ?? Matrix4x4.Identity; - return matrix.Transform(LocalPosition); + return TransformPoint(LocalPosition); } set { - Matrix4x4 matrix = Parent != null ? Matrix4x4Extension.Compose(value, LocalRotation, LocalScale) * Parent.LocalToWorldMatrix.Invert() : Matrix4x4Extension.Compose(value, LocalRotation, LocalScale); - LocalPosition = (NitroxVector3)matrix.Translation; + LocalPosition = InverseTransformPoint(value); } } @@ -58,7 +56,7 @@ public NitroxQuaternion Rotation } set { - Matrix4x4 matrix = Parent != null ? Matrix4x4Extension.Compose(LocalPosition, value, LocalScale) * Parent.LocalToWorldMatrix.Invert() : Matrix4x4Extension.Compose(LocalPosition, value, LocalScale); + Matrix4x4 matrix = Parent != null ? Matrix4x4.CreateFromQuaternion((Quaternion)value) * Parent.LocalToWorldMatrix.Invert() : Matrix4x4Extension.Compose(LocalPosition, value, LocalScale); Matrix4x4.Decompose(matrix, out Vector3 _, out Quaternion rotation, out Vector3 _); LocalRotation = (NitroxQuaternion)rotation; @@ -91,6 +89,20 @@ public NitroxTransform(NitroxVector3 localPosition, NitroxQuaternion localRotati LocalScale = scale; } + public NitroxVector3 InverseTransformPoint(NitroxVector3 point) + { + Matrix4x4 pointMatrix = Parent != null ? Matrix4x4.CreateTranslation((Vector3)point) * Parent.LocalToWorldMatrix.Invert() : Matrix4x4.CreateTranslation((Vector3)point); + + return (NitroxVector3)pointMatrix.Translation; + } + + public NitroxVector3 TransformPoint(NitroxVector3 localPoint) + { + Matrix4x4 pointMatrix = Parent != null ? Matrix4x4.CreateTranslation((Vector3)localPoint) * Parent.LocalToWorldMatrix : Matrix4x4.CreateTranslation((Vector3)localPoint); + + return (NitroxVector3)pointMatrix.Translation; + } + public override string ToString() { return $"(Position: {Position}, LocalPosition: {LocalPosition}, Rotation: {Rotation}, LocalRotation: {LocalRotation}, LocalScale: {LocalScale})"; diff --git a/NitroxModel/Packets/Movement.cs b/NitroxModel/Packets/Movement.cs index 12b4ad05a2..03c1a46b49 100644 --- a/NitroxModel/Packets/Movement.cs +++ b/NitroxModel/Packets/Movement.cs @@ -1,4 +1,4 @@ -using System; +using System; using NitroxModel.DataStructures.Unity; namespace NitroxModel.Packets; @@ -8,7 +8,6 @@ public abstract class Movement : Packet { public abstract ushort PlayerId { get; } public abstract NitroxVector3 Position { get; } - public abstract NitroxVector3 Velocity { get; } public abstract NitroxQuaternion BodyRotation { get; } public abstract NitroxQuaternion AimingRotation { get; } } diff --git a/NitroxModel/Packets/PlayerMovement.cs b/NitroxModel/Packets/PlayerMovement.cs index 094ae31784..965d042eb7 100644 --- a/NitroxModel/Packets/PlayerMovement.cs +++ b/NitroxModel/Packets/PlayerMovement.cs @@ -1,4 +1,4 @@ -using System; +using System; using NitroxModel.DataStructures.Unity; using NitroxModel.Networking; @@ -9,15 +9,13 @@ public class PlayerMovement : Movement { public override ushort PlayerId { get; } public override NitroxVector3 Position { get; } - public override NitroxVector3 Velocity { get; } public override NitroxQuaternion BodyRotation { get; } public override NitroxQuaternion AimingRotation { get; } - public PlayerMovement(ushort playerId, NitroxVector3 position, NitroxVector3 velocity, NitroxQuaternion bodyRotation, NitroxQuaternion aimingRotation) + public PlayerMovement(ushort playerId, NitroxVector3 position, NitroxQuaternion bodyRotation, NitroxQuaternion aimingRotation) { PlayerId = playerId; Position = position; - Velocity = velocity; BodyRotation = bodyRotation; AimingRotation = aimingRotation; DeliveryMethod = NitroxDeliveryMethod.DeliveryMethod.UNRELIABLE_SEQUENCED; diff --git a/NitroxModel/Packets/VehicleMovement.cs b/NitroxModel/Packets/VehicleMovement.cs index 5f1a9498ee..3ea1d356aa 100644 --- a/NitroxModel/Packets/VehicleMovement.cs +++ b/NitroxModel/Packets/VehicleMovement.cs @@ -1,4 +1,4 @@ -using System; +using System; using BinaryPack.Attributes; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.Unity; @@ -15,8 +15,6 @@ public class VehicleMovement : Movement [IgnoredMember] public override NitroxVector3 Position => VehicleMovementData.Position; [IgnoredMember] - public override NitroxVector3 Velocity => VehicleMovementData.Velocity; - [IgnoredMember] public override NitroxQuaternion BodyRotation => VehicleMovementData.Rotation; [IgnoredMember] public override NitroxQuaternion AimingRotation => VehicleMovementData.Rotation; diff --git a/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs b/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs index d1d991328d..c22dc75eec 100644 --- a/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using FMOD.Studio; using NitroxClient.GameLogic.FMOD; using NitroxClient.MonoBehaviours; @@ -25,7 +25,7 @@ public static void Prefix(FMOD_CustomEmitter __instance) return; } - if (!__instance.TryGetComponentInParent(out NitroxEntity entity)) + if (!__instance.transform.TryGetComponentInAscendance(10, out NitroxEntity entity)) { Log.Warn($"[FMOD_CustomEmitter_Start_Patch] - No NitroxEntity for \"{__instance.asset.path}\" found!"); return; diff --git a/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs b/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs index 9e0fd1de1e..6a22c3c9de 100644 --- a/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs @@ -31,7 +31,8 @@ public override void Process(VehicleMovement packet, Player player) if (player.Id == packet.PlayerId) { - player.Position = packet.VehicleMovementData.DriverPosition ?? packet.Position; + player.Position = packet.VehicleMovementData.DriverPosition; + player.Rotation = packet.VehicleMovementData.DriverRotation; ; } playerManager.SendPacketToOtherPlayers(packet, player); From c3718460fcb8f3f6f83a8d7fe87a349af0fad05d Mon Sep 17 00:00:00 2001 From: killzoms Date: Tue, 15 Aug 2023 12:57:04 -0400 Subject: [PATCH 02/19] fix null ref --- NitroxClient/GameLogic/RemotePlayer.cs | 6 +++--- NitroxClient/MonoBehaviours/MovementController.cs | 5 +++-- NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/NitroxClient/GameLogic/RemotePlayer.cs b/NitroxClient/GameLogic/RemotePlayer.cs index c805362b1b..04a2ae5eb0 100644 --- a/NitroxClient/GameLogic/RemotePlayer.cs +++ b/NitroxClient/GameLogic/RemotePlayer.cs @@ -119,7 +119,7 @@ public void UpdatePosition(Vector3 position, Quaternion bodyRotation, Quaternion SetVehicle(null); SetPilotingChair(null); - MovementController.enabled = true; + MovementController.IsMoving = true; MovementController.TargetPosition = position; MovementController.TargetRotation = bodyRotation; @@ -177,7 +177,7 @@ public void SetPilotingChair(PilotingChair newPilotingChair) RigidBody.isKinematic = AnimationController["cyclops_steering"] = isInPilotingChair; RigidBody.interpolation = isInPilotingChair ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate; - MovementController.enabled = !isInPilotingChair; + MovementController.IsMoving = !isInPilotingChair; } } @@ -254,7 +254,7 @@ public void SetVehicle(Vehicle newVehicle) RigidBody.interpolation = Vehicle ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate; RigidBody.isKinematic = Vehicle; - MovementController.enabled = !Vehicle; + MovementController.IsMoving = !Vehicle; AnimationController["in_seamoth"] = newVehicle is SeaMoth; AnimationController["in_exosuit"] = AnimationController["using_mechsuit"] = newVehicle is Exosuit; diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MovementController.cs index 3b26d2adaf..27c310c928 100644 --- a/NitroxClient/MonoBehaviours/MovementController.cs +++ b/NitroxClient/MonoBehaviours/MovementController.cs @@ -15,6 +15,7 @@ public class MovementController : MonoBehaviour public Vector3 TargetPosition { get; set; } public Quaternion TargetRotation { get; set; } public Transform TargetTransform { get; set; } + public bool IsMoving { get; set; } public event Action BeforeUpdate = () => {}; public event Action BeforeFixedUpdate = () => {}; @@ -34,7 +35,7 @@ private void Update() BeforeUpdate(); if (!rigidbody) { - transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, Scalar * Time.fixedDeltaTime); + transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, Scalar * Time.deltaTime); transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, Scalar * Time.deltaTime); } AfterUpdate(); @@ -60,7 +61,7 @@ private void FixedUpdate() Quaternion delta = TargetRotation * transform.rotation.GetInverse(); delta.ToAngleAxis(out float angle, out Vector3 axis); - rigidbody.angularVelocity = Mathf.Deg2Rad * angle / timing * axis; + rigidbody.angularVelocity = .9f * Mathf.Deg2Rad * angle / timing * axis; } } AfterFixedUpdate(); diff --git a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs index ee4095aa52..4517d1eac3 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs @@ -56,13 +56,13 @@ internal virtual void SetArmPositions(Vector3 leftArmPosition, Vector3 rightArmP internal virtual void Enter() { - movementController.enabled = true; + movementController.IsMoving = true; enabled = true; } public virtual void Exit() { - movementController.enabled = false; + movementController.IsMoving = false; enabled = false; } From 9b3d28fc8d24752d3ae13a4aba786efc482ef215 Mon Sep 17 00:00:00 2001 From: killzoms Date: Tue, 15 Aug 2023 20:23:16 -0400 Subject: [PATCH 03/19] add some Kinematic prevention patches --- .../MonoBehaviours/MovementController.cs | 13 ++++- ...reezeRigidbodyWhenFar_FixedUpdate_Patch.cs | 56 +++++++++++++++++++ .../Vehicle_ShouldSetKinematic_Patch.cs | 20 +++++++ 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs create mode 100644 NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MovementController.cs index 27c310c928..3a8628932f 100644 --- a/NitroxClient/MonoBehaviours/MovementController.cs +++ b/NitroxClient/MonoBehaviours/MovementController.cs @@ -33,7 +33,7 @@ private void Start() private void Update() { BeforeUpdate(); - if (!rigidbody) + if (!rigidbody && IsMoving) { transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, Scalar * Time.deltaTime); transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, Scalar * Time.deltaTime); @@ -44,7 +44,7 @@ private void Update() private void FixedUpdate() { BeforeFixedUpdate(); - if (rigidbody) + if (rigidbody && IsMoving) { float timing = Scalar * Time.fixedDeltaTime; Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, timing); @@ -61,7 +61,14 @@ private void FixedUpdate() Quaternion delta = TargetRotation * transform.rotation.GetInverse(); delta.ToAngleAxis(out float angle, out Vector3 axis); - rigidbody.angularVelocity = .9f * Mathf.Deg2Rad * angle / timing * axis; + if (!float.IsInfinity(axis.x) && !float.IsInfinity(axis.y) && !float.IsInfinity(axis.z)) + { + rigidbody.angularVelocity = .9f * Mathf.Deg2Rad * angle / timing * axis; + } + else + { + rigidbody.angularVelocity = Vector3.zero; + } } } AfterFixedUpdate(); diff --git a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs new file mode 100644 index 0000000000..78b05afb75 --- /dev/null +++ b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using HarmonyLib; +using NitroxClient.GameLogic; +using NitroxClient.MonoBehaviours; +using NitroxModel.Helper; +using UnityEngine; + +namespace NitroxPatcher.Patches.Dynamic +{ + public sealed partial class FreezeRigidbodyWhenFar_FixedUpdate_Patch : NitroxPatch, IDynamicPatch + { + public static readonly MethodInfo TARGET_METHOD = Reflect.Method((FreezeRigidbodyWhenFar t) => t.FixedUpdate()); + + public static IEnumerable Transpiler(MethodBase original, IEnumerable instructions, ILGenerator generator) + { + List instructionList = instructions.ToList(); + for (int i = 0; i < instructionList.Count; i++) + { + CodeInstruction instruction = instructionList[i]; + + if (instruction.opcode == OpCodes.Call && instruction.operand.Equals(Reflect.Method((Component c) => c.GetComponent()))) + { + yield return instruction; + yield return instructionList[i+1]; + object jmpLabel = null; + + for (int j = i; j < instructionList.Count; j++) // search for branch instruction + { + if (instructionList[j].opcode == OpCodes.Ble_Un) + { + jmpLabel = instructionList[j].operand; + break; + } + } + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Call, Reflect.Property((Component c) => c.gameObject).GetGetMethod()); + yield return new CodeInstruction(OpCodes.Call, Reflect.Method(() => IsMoving(default))); + yield return new CodeInstruction(OpCodes.Brtrue, jmpLabel); + i = i + 1; + continue; + } + + yield return instruction; + } + } + + public static bool IsMoving(GameObject go) + { + return go.TryGetComponent(out MovementController mc) && mc.IsMoving; + } + } +} diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs new file mode 100644 index 0000000000..821d0801bb --- /dev/null +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using NitroxClient.MonoBehaviours; +using NitroxModel.Helper; + +namespace NitroxPatcher.Patches.Dynamic; + +public sealed partial class Vehicle_ShouldSetKinematic_Patch : NitroxPatch, IDynamicPatch +{ + public static readonly MethodInfo TARGET_METHOD = Reflect.Method((Vehicle t) => t.ShouldSetKinematic()); + + public static bool Prefix(Vehicle __instance, ref bool __result) + { + if (__instance.TryGetComponent(out MovementController movementController)) + { + __result = !movementController.IsMoving; + return false; + } + return true; + } +} From 6d58ba495bb27184eb5ed8b0a95033032ecc92b7 Mon Sep 17 00:00:00 2001 From: killzoms Date: Fri, 18 Aug 2023 18:46:21 -0400 Subject: [PATCH 04/19] first round of bug fixes --- .../ConnectionState/DisconnectedStateTests.cs | 8 +- .../Processors/BasicMovementProcessor.cs | 28 +++++ .../Processors/PlayerMovementProcessor.cs | 4 +- .../SimulationOwnershipResponseProcessor.cs | 16 ++- .../Processors/VehicleMovementProcessor.cs | 4 +- NitroxClient/Debuggers/NetworkDebugger.cs | 3 +- NitroxClient/GameLogic/Entities.cs | 5 +- NitroxClient/GameLogic/LocalPlayer.cs | 45 ++++---- NitroxClient/GameLogic/MobileVehicleBay.cs | 11 +- NitroxClient/GameLogic/RemotePlayer.cs | 12 +- .../GameLogic/Simulation/LockRequest.cs | 4 +- NitroxClient/GameLogic/SimulationOwnership.cs | 15 ++- .../ReefbackWorldEntitySpawner.cs | 4 +- .../VehicleWorldEntitySpawner.cs | 14 ++- .../WorldEntitySpawnerResolver.cs | 3 +- .../GameLogic/Spawning/WorldEntitySpawner.cs | 53 ++++++++- NitroxClient/GameLogic/Vehicles.cs | 10 -- .../MonoBehaviours/MovementController.cs | 105 ++++++++++++++++-- .../MultiplayerVehicleControl.cs | 3 +- NitroxClient/MonoBehaviours/NitroxEntity.cs | 5 +- .../PlayerMovementBroadcaster.cs | 8 +- NitroxModel/Packets/BasicMovementPacket.cs | 29 +++++ NitroxModel/Packets/Movement.cs | 7 +- NitroxModel/Packets/Packet.cs | 5 +- NitroxModel/Packets/PlayerMovement.cs | 13 ++- NitroxModel/Packets/VehicleMovement.cs | 12 +- ...reezeRigidbodyWhenFar_FixedUpdate_Patch.cs | 2 +- .../PilotingChair_OnHandClick_Patch.cs | 7 +- .../PilotingChair_OnPlayerDeath_Patch.cs | 7 +- .../Dynamic/PilotingChair_ReleaseBy_Patch.cs | 7 +- .../Dynamic/Vehicle_OnPilotModeBegin_Patch.cs | 7 +- .../Dynamic/Vehicle_OnPilotModeEnd_Patch.cs | 6 +- .../Vehicle_ShouldSetKinematic_Patch.cs | 4 +- .../BasicMovementPacketProcessor.cs | 35 ++++++ .../Processors/PlayerMovementProcessor.cs | 4 +- .../VehicleMovementPacketProcessor.cs | 2 +- 36 files changed, 406 insertions(+), 101 deletions(-) create mode 100644 NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs create mode 100644 NitroxModel/Packets/BasicMovementPacket.cs create mode 100644 NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs diff --git a/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs b/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs index b9a46c131f..66a055832b 100644 --- a/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs +++ b/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -29,7 +29,7 @@ public void NegotiateShouldStartTheClientOnTheContext() Disconnected connectionState = new Disconnected(); // Act - connectionState.NegotiateReservationAsync(connectionContext); + connectionState.NegotiateReservationAsync(connectionContext).RunSynchronously(); // Assert serverClient.IsConnected.Should().BeTrue(); @@ -52,7 +52,7 @@ public void NegotiateShouldSendMultiplayerSessionPolicyRequestPacketToClient() Disconnected connectionState = new Disconnected(); // Act - connectionState.NegotiateReservationAsync(connectionContext); + connectionState.NegotiateReservationAsync(connectionContext).RunSynchronously(); // Assert serverClient.Received().Send(Arg.Any()); @@ -75,7 +75,7 @@ public void NegotiateShouldTransitionToEstablishingSessionPolicyState() Disconnected connectionState = new Disconnected(); // Act - connectionState.NegotiateReservationAsync(connectionContext); + connectionState.NegotiateReservationAsync(connectionContext).RunSynchronously(); // Assert connectionContext.Received().UpdateConnectionState(Arg.Any()); diff --git a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs new file mode 100644 index 0000000000..84f465361a --- /dev/null +++ b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs @@ -0,0 +1,28 @@ +using System.Collections; +using NitroxClient.Communication.Packets.Processors.Abstract; +using NitroxClient.GameLogic; +using NitroxClient.MonoBehaviours; +using NitroxClient.Unity.Helper; +using NitroxModel_Subnautica.DataStructures; +using NitroxModel.DataStructures.Util; +using NitroxModel.Packets; +using UnityEngine; + +namespace NitroxClient.Communication.Packets.Processors; + +public class BasicMovementProcessor : ClientPacketProcessor +{ + public BasicMovementProcessor() + { + } + + public override void Process(BasicMovement movement) + { + if (NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) + { + MovementController mc = gameObject.EnsureComponent(); + mc.TargetPosition = movement.Position.ToUnity(); + mc.TargetRotation = movement.Rotation.ToUnity(); + } + } +} diff --git a/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs index 6dc6082d8c..75ee300f11 100644 --- a/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs @@ -20,14 +20,14 @@ public PlayerMovementProcessor(PlayerManager remotePlayerManager) public override void Process(PlayerMovement movement) { - Optional remotePlayer = remotePlayerManager.Find(movement.PlayerId); + Optional remotePlayer = remotePlayerManager.Find(movement.Id); if (!remotePlayer.HasValue) { return; } remotePlayer.Value.UpdatePosition(movement.Position.ToUnity(), - movement.BodyRotation.ToUnity(), + movement.Rotation.ToUnity(), movement.AimingRotation.ToUnity()); } } diff --git a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs index 45578434b5..f7faca9962 100644 --- a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs @@ -1,4 +1,4 @@ -using NitroxClient.Communication.Abstract; +using NitroxClient.Communication.Abstract; using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; @@ -37,6 +37,8 @@ public override void Process(SimulationOwnershipResponse response) { RemoveRemoteController(response.Id); } + + SwapMovementController(response.Id, response.LockAcquired); } private void RemoveRemoteController(NitroxId id) @@ -49,5 +51,17 @@ private void RemoveRemoteController(NitroxId id) Object.Destroy(remotelyControlled); } } + + private void SwapMovementController(NitroxId id, bool lockAcquired) + { + Optional gameObject = NitroxEntity.GetObjectFrom(id); + + if (gameObject.HasValue) + { + MovementController movementController = gameObject.Value.GetComponent(); + movementController.SetBroadcasting(lockAcquired); + movementController.SetReceiving(!lockAcquired); + } + } } } diff --git a/NitroxClient/Communication/Packets/Processors/VehicleMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/VehicleMovementProcessor.cs index 2963d91a2c..347cf5e06c 100644 --- a/NitroxClient/Communication/Packets/Processors/VehicleMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/VehicleMovementProcessor.cs @@ -1,4 +1,4 @@ -using NitroxClient.Communication.Packets.Processors.Abstract; +using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxClient.GameLogic; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.Util; @@ -20,7 +20,7 @@ public VehicleMovementProcessor(PlayerManager remotePlayerManager, Vehicles vehi public override void Process(VehicleMovement vehicleMovement) { VehicleMovementData vehicleModel = vehicleMovement.VehicleMovementData; - Optional player = remotePlayerManager.Find(vehicleMovement.PlayerId); + Optional player = remotePlayerManager.Find(vehicleMovement.Id); vehicles.UpdateVehiclePosition(vehicleModel, player); } } diff --git a/NitroxClient/Debuggers/NetworkDebugger.cs b/NitroxClient/Debuggers/NetworkDebugger.cs index a062d005b8..4e39b9269e 100644 --- a/NitroxClient/Debuggers/NetworkDebugger.cs +++ b/NitroxClient/Debuggers/NetworkDebugger.cs @@ -18,7 +18,8 @@ public class NetworkDebugger : BaseDebugger, INetworkDebugger private readonly List filter = new() { nameof(PlayerMovement), nameof(EntityTransformUpdates), nameof(PlayerStats), nameof(SpawnEntities), nameof(VehicleMovement), nameof(PlayerCinematicControllerCall), - nameof(PlayFMODAsset), nameof(PlayFMODCustomEmitter), nameof(PlayFMODStudioEmitter), nameof(PlayFMODCustomLoopingEmitter), nameof(SimulationOwnershipChange) + nameof(PlayFMODAsset), nameof(PlayFMODCustomEmitter), nameof(PlayFMODStudioEmitter), nameof(PlayFMODCustomLoopingEmitter), nameof(SimulationOwnershipChange), + nameof(BasicMovement) }; private readonly List packets = new List(PACKET_STORED_COUNT); diff --git a/NitroxClient/GameLogic/Entities.cs b/NitroxClient/GameLogic/Entities.cs index dde49db4b3..00203030b1 100644 --- a/NitroxClient/GameLogic/Entities.cs +++ b/NitroxClient/GameLogic/Entities.cs @@ -38,7 +38,8 @@ public class Entities public List EntitiesToSpawn { get; private init; } private bool spawningEntities; - public Entities(IPacketSender packetSender, ThrottledPacketSender throttledPacketSender, PlayerManager playerManager, ILocalNitroxPlayer localPlayer) + public Entities(IPacketSender packetSender, ThrottledPacketSender throttledPacketSender, PlayerManager playerManager, ILocalNitroxPlayer localPlayer, SimulationOwnership simulationOwnership) + { this.packetSender = packetSender; this.throttledPacketSender = throttledPacketSender; @@ -50,7 +51,7 @@ public Entities(IPacketSender packetSender, ThrottledPacketSender throttledPacke entitySpawnersByType[typeof(InstalledBatteryEntity)] = new InstalledBatteryEntitySpawner(); entitySpawnersByType[typeof(InventoryEntity)] = new InventoryEntitySpawner(); entitySpawnersByType[typeof(InventoryItemEntity)] = new InventoryItemEntitySpawner(); - entitySpawnersByType[typeof(WorldEntity)] = new WorldEntitySpawner(playerManager, localPlayer, this); + entitySpawnersByType[typeof(WorldEntity)] = new WorldEntitySpawner(playerManager, localPlayer, simulationOwnership, this); entitySpawnersByType[typeof(PlaceholderGroupWorldEntity)] = entitySpawnersByType[typeof(WorldEntity)]; entitySpawnersByType[typeof(EscapePodWorldEntity)] = entitySpawnersByType[typeof(WorldEntity)]; entitySpawnersByType[typeof(PlayerWorldEntity)] = entitySpawnersByType[typeof(WorldEntity)]; diff --git a/NitroxClient/GameLogic/LocalPlayer.cs b/NitroxClient/GameLogic/LocalPlayer.cs index d4110427a4..e320dae6a2 100644 --- a/NitroxClient/GameLogic/LocalPlayer.cs +++ b/NitroxClient/GameLogic/LocalPlayer.cs @@ -24,6 +24,7 @@ public class LocalPlayer : ILocalNitroxPlayer private readonly Lazy body; private readonly Lazy playerModel; private readonly Lazy bodyPrototype; + private readonly NitroxEntity entity; public GameObject Body => body.Value; @@ -37,28 +38,34 @@ public class LocalPlayer : ILocalNitroxPlayer public Perms Permissions; - public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetSender, ThrottledPacketSender throttledPacketSender) - { - this.multiplayerSession = multiplayerSession; - this.packetSender = packetSender; - this.throttledPacketSender = throttledPacketSender; - body = new Lazy(() => Player.main.RequireGameObject("body")); - playerModel = new Lazy(() => Body.RequireGameObject("player_view")); - bodyPrototype = new Lazy(CreateBodyPrototype); - Permissions = Perms.PLAYER; - } - - public void BroadcastLocation(Vector3 location, Vector3 velocity, Quaternion bodyRotation, Quaternion aimingRotation, Optional vehicle) - { - Movement movement; - if (vehicle.HasValue) + public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetSender, ThrottledPacketSender throttledPacketSender) { - movement = new VehicleMovement(PlayerId, vehicle.Value); + this.multiplayerSession = multiplayerSession; + this.packetSender = packetSender; + this.throttledPacketSender = throttledPacketSender; + body = new Lazy(() => Player.main.RequireGameObject("body")); + playerModel = new Lazy(() => Body.RequireGameObject("player_view")); + bodyPrototype = new Lazy(CreateBodyPrototype); + Permissions = Perms.PLAYER; + + if (!Player.mainObject.TryGetComponent(out NitroxEntity nitroxEntity)) + { + nitroxEntity = Player.mainObject.AddComponent(); + } + entity = nitroxEntity; } - else + + public void BroadcastLocation(Vector3 location, Quaternion bodyRotation, Quaternion aimingRotation, Optional vehicle) { - movement = new PlayerMovement(PlayerId, location.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto()); - } + Movement movement; + if (vehicle.HasValue) + { + movement = new VehicleMovement(entity.Id, vehicle.Value); + } + else + { + movement = new PlayerMovement(entity.Id, location.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto()); + } packetSender.Send(movement); } diff --git a/NitroxClient/GameLogic/MobileVehicleBay.cs b/NitroxClient/GameLogic/MobileVehicleBay.cs index 16c6456ce7..1d19c0fbdd 100644 --- a/NitroxClient/GameLogic/MobileVehicleBay.cs +++ b/NitroxClient/GameLogic/MobileVehicleBay.cs @@ -15,12 +15,12 @@ public class MobileVehicleBay public static GameObject MostRecentlyCrafted { get; set; } private readonly IPacketSender packetSender; - private readonly Vehicles vehicles; + private readonly SimulationOwnership simulationOwnership; - public MobileVehicleBay(IPacketSender packetSender, Vehicles vehicles) + public MobileVehicleBay(IPacketSender packetSender, Vehicles vehicles, SimulationOwnership simulationOwnership) { this.packetSender = packetSender; - this.vehicles = vehicles; + this.simulationOwnership = simulationOwnership; } public void BeginCrafting(ConstructorInput constructor, GameObject constructedObject, TechType techType, float duration) @@ -42,11 +42,12 @@ public void BeginCrafting(ConstructorInput constructor, GameObject constructedOb NitroxId constructedObjectId = NitroxEntity.GenerateNewId(constructedObject); + MovementController mc = constructedObject.AddComponent(); + VehicleWorldEntity vehicleEntity = new(constructorId, DayNightCycle.main.timePassedAsFloat, constructedObject.transform.ToLocalDto(), string.Empty, false, constructedObjectId, techType.ToDto(), null); VehicleChildEntityHelper.PopulateChildren(constructedObjectId, constructedObject.GetFullHierarchyPath(), vehicleEntity.ChildEntities, constructedObject); packetSender.Send(new EntitySpawnedByClient(vehicleEntity)); - - constructor.StartCoroutine(vehicles.UpdateVehiclePositionAfterSpawn(constructedObjectId, techType, constructedObject, duration + 10.0f)); + simulationOwnership.RequestSimulationLock(constructedObjectId, SimulationLockType.TRANSIENT); } } diff --git a/NitroxClient/GameLogic/RemotePlayer.cs b/NitroxClient/GameLogic/RemotePlayer.cs index 04a2ae5eb0..15b4fbfac5 100644 --- a/NitroxClient/GameLogic/RemotePlayer.cs +++ b/NitroxClient/GameLogic/RemotePlayer.cs @@ -119,7 +119,7 @@ public void UpdatePosition(Vector3 position, Quaternion bodyRotation, Quaternion SetVehicle(null); SetPilotingChair(null); - MovementController.IsMoving = true; + MovementController.SetReceiving(true); MovementController.TargetPosition = position; MovementController.TargetRotation = bodyRotation; @@ -177,7 +177,10 @@ public void SetPilotingChair(PilotingChair newPilotingChair) RigidBody.isKinematic = AnimationController["cyclops_steering"] = isInPilotingChair; RigidBody.interpolation = isInPilotingChair ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate; - MovementController.IsMoving = !isInPilotingChair; + if (isInPilotingChair) + { + MovementController.SetReceiving(false); + } } } @@ -254,7 +257,10 @@ public void SetVehicle(Vehicle newVehicle) RigidBody.interpolation = Vehicle ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate; RigidBody.isKinematic = Vehicle; - MovementController.IsMoving = !Vehicle; + if (Vehicle) + { + MovementController.SetReceiving(false); + } AnimationController["in_seamoth"] = newVehicle is SeaMoth; AnimationController["in_exosuit"] = AnimationController["using_mechsuit"] = newVehicle is Exosuit; diff --git a/NitroxClient/GameLogic/Simulation/LockRequest.cs b/NitroxClient/GameLogic/Simulation/LockRequest.cs index 9ccda1eb19..cefebed1f7 100644 --- a/NitroxClient/GameLogic/Simulation/LockRequest.cs +++ b/NitroxClient/GameLogic/Simulation/LockRequest.cs @@ -1,4 +1,4 @@ -using NitroxModel.DataStructures; +using NitroxModel.DataStructures; namespace NitroxClient.GameLogic.Simulation { @@ -19,7 +19,7 @@ public override void LockRequestComplete(NitroxId id, bool lockAquired) { if (onComplete != null) { - onComplete(id, lockAquired, (T)context); + onComplete(id, lockAquired, context); } } diff --git a/NitroxClient/GameLogic/SimulationOwnership.cs b/NitroxClient/GameLogic/SimulationOwnership.cs index 00c1535c5b..f8024266df 100644 --- a/NitroxClient/GameLogic/SimulationOwnership.cs +++ b/NitroxClient/GameLogic/SimulationOwnership.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using NitroxClient.Communication.Abstract; using NitroxClient.GameLogic.Simulation; using NitroxModel.DataStructures; @@ -13,6 +14,9 @@ public class SimulationOwnership private readonly Dictionary simulatedIdsByLockType = new Dictionary(); private readonly Dictionary lockRequestsById = new Dictionary(); + public event Action StoppedSimulatingEntity; + public event Action StartedSimulatingEntity; + public SimulationOwnership(IMultiplayerSession muliplayerSession, IPacketSender packetSender) { this.muliplayerSession = muliplayerSession; @@ -68,11 +72,20 @@ public void ReceivedSimulationLockResponse(NitroxId id, bool lockAquired, Simula public void SimulateEntity(NitroxId id, SimulationLockType lockType) { simulatedIdsByLockType[id] = lockType; + if (StartedSimulatingEntity != null) + { + StartedSimulatingEntity(id); + } } public void StopSimulatingEntity(NitroxId id) { simulatedIdsByLockType.Remove(id); + + if (StoppedSimulatingEntity != null) + { + StoppedSimulatingEntity(id); + } } } } diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs index d6f56aa4e5..06777200ce 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.GameLogic.Entities; using NitroxModel.DataStructures.Util; @@ -33,7 +33,7 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, E } life.initialized = true; - life.SpawnPlants(); + yield return life.SpawnPlants(); foreach (Entity childEntity in entity.ChildEntities) { if (childEntity is WorldEntity worldChild) diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs index 101fc44b8b..5f4125633d 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs @@ -2,6 +2,7 @@ using NitroxClient.MonoBehaviours; using NitroxClient.MonoBehaviours.Overrides; using NitroxClient.Unity.Helper; +using NitroxModel.DataStructures; using NitroxModel.DataStructures.GameLogic.Entities; using NitroxModel.DataStructures.Util; using NitroxModel.Helper; @@ -23,6 +24,12 @@ public VehicleWorldEntitySpawner(Entities entities) // that they are within allowed range. However, this range is a bit restrictive. We will allow constructor spawning up to a specified // distance - anything more will simply use world spawning (no need to play the animation anyways). private const float ALLOWED_CONSTRUCTOR_DISTANCE = 100.0f; + private readonly SimulationOwnership simulationOwnership; + + internal VehicleWorldEntitySpawner(SimulationOwnership simulationOwnership) + { + this.simulationOwnership = simulationOwnership; + } public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, EntityCell cellRoot, TaskResult> result) { @@ -41,12 +48,17 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, E { MobileVehicleBay.TransmitLocalSpawns = false; yield return SpawnViaConstructor(vehicleEntity, constructor, result); + result.value.Value.EnsureComponent(); + + simulationOwnership.RequestSimulationLock(vehicleEntity.Id, SimulationLockType.TRANSIENT); MobileVehicleBay.TransmitLocalSpawns = true; yield break; } } - yield return SpawnInWorld(vehicleEntity, result, parent); + yield return SpawnInWorld(vehicleEntity, result, parent); + result.value.Value.EnsureComponent(); + simulationOwnership.RequestSimulationLock(vehicleEntity.Id, SimulationLockType.TRANSIENT); } private IEnumerator SpawnInWorld(VehicleWorldEntity vehicleEntity, TaskResult> result, Optional parent) diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs index 2715ec7b3a..cffe88d273 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs @@ -15,7 +15,7 @@ public class WorldEntitySpawnerResolver private readonly Dictionary customSpawnersByTechType = new(); - public WorldEntitySpawnerResolver(PlayerManager playerManager, ILocalNitroxPlayer localPlayer, Entities entities) + public WorldEntitySpawnerResolver(PlayerManager playerManager, ILocalNitroxPlayer localPlayer, SimulationOwnership simulationOwnership, Entities entities) { customSpawnersByTechType[TechType.Crash] = new CrashEntitySpawner(); customSpawnersByTechType[TechType.Reefback] = new ReefbackWorldEntitySpawner(defaultEntitySpawner); @@ -24,6 +24,7 @@ public WorldEntitySpawnerResolver(PlayerManager playerManager, ILocalNitroxPlaye vehicleWorldEntitySpawner = new(entities); prefabWorldEntitySpawner = new PlaceholderGroupWorldEntitySpawner(this, defaultEntitySpawner); playerWorldEntitySpawner = new PlayerWorldEntitySpawner(playerManager, localPlayer); + vehicleWorldEntitySpawner = new VehicleWorldEntitySpawner(simulationOwnership); } public IWorldEntitySpawner ResolveEntitySpawner(WorldEntity entity) diff --git a/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs index 0b3341fe23..6e0579b3a6 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs @@ -18,13 +18,58 @@ public class WorldEntitySpawner : EntitySpawner private readonly WorldEntitySpawnerResolver worldEntitySpawnResolver; private readonly Dictionary batchCellsById; - public WorldEntitySpawner(PlayerManager playerManager, ILocalNitroxPlayer localPlayer, Entities entities) + public WorldEntitySpawner(PlayerManager playerManager, ILocalNitroxPlayer localPlayer, SimulationOwnership simulationOwnership, Entities entities) { - worldEntitySpawnResolver = new WorldEntitySpawnerResolver(playerManager, localPlayer, entities); + worldEntitySpawnResolver = new WorldEntitySpawnerResolver(playerManager, localPlayer, simulationOwnership, entities); - if (NitroxEnvironment.IsNormal) + if (NitroxEnvironment.IsNormal) + { + batchCellsById = (Dictionary)LargeWorldStreamer.main.cellManager.batch2cells; + } + } + + public override IEnumerator SpawnAsync(WorldEntity entity, TaskResult> result) { - batchCellsById = (Dictionary)LargeWorldStreamer.main.cellManager.batch2cells; + LargeWorldStreamer.main.cellManager.UnloadBatchCells(entity.AbsoluteEntityCell.CellId.ToUnity()); // Just in case + + EntityCell cellRoot = EnsureCell(entity); + + Optional parent = (entity.ParentId != null) ? NitroxEntity.GetObjectFrom(entity.ParentId) : Optional.Empty; + + IWorldEntitySpawner entitySpawner = worldEntitySpawnResolver.ResolveEntitySpawner(entity); + + return entitySpawner.SpawnAsync(entity, parent, cellRoot, result); + } + public override bool SpawnsOwnChildren(WorldEntity entity) + { + IWorldEntitySpawner entitySpawner = worldEntitySpawnResolver.ResolveEntitySpawner(entity); + return entitySpawner.SpawnsOwnChildren(); + } + + private EntityCell EnsureCell(WorldEntity entity) + { + EntityCell entityCell; + + Int3 batchId = entity.AbsoluteEntityCell.BatchId.ToUnity(); + Int3 cellId = entity.AbsoluteEntityCell.CellId.ToUnity(); + + if (!batchCellsById.TryGetValue(batchId, out BatchCells batchCells)) + { + batchCells = LargeWorldStreamer.main.cellManager.InitializeBatchCells(batchId); + } + + entityCell = batchCells.Get(cellId, entity.AbsoluteEntityCell.Level); + + if (entityCell == null) + { + entityCell = batchCells.Add(cellId, entity.AbsoluteEntityCell.Level); + entityCell.Initialize(); + } + + entityCell.EnsureRoot(); + + return entityCell; +>>>>>>> ddf37665 (first round of bug fixes) } } diff --git a/NitroxClient/GameLogic/Vehicles.cs b/NitroxClient/GameLogic/Vehicles.cs index d45d21002e..9a7f033c6c 100644 --- a/NitroxClient/GameLogic/Vehicles.cs +++ b/NitroxClient/GameLogic/Vehicles.cs @@ -173,16 +173,6 @@ public IEnumerator AllowMovementPacketsAfterDockingAnimation(PacketSuppressor {}; public event Action BeforeFixedUpdate = () => {}; public event Action AfterUpdate = () => {}; public event Action AfterFixedUpdate = () => {}; + private Vector3 velocity; + private float curTime; private Rigidbody rigidbody; - public Vector3 Velocity; + private IPacketSender packetSender; + private SimulationOwnership simulationOwnership; + private NitroxEntity entity; + private static bool runOnce; + + public void SetBroadcasting(bool broadcasting) + { + Broadcasting = broadcasting; + if (Receiving && broadcasting) + { + Receiving = !broadcasting; + } + } + + public void SetReceiving(bool receiving) + { + Receiving = receiving; + if (Broadcasting && receiving) + { + Broadcasting = !receiving; + } + } + + private static void StartedSimulatingEntity(NitroxId id) + { + if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) + { + if (gameObject.TryGetComponent(out MovementController mc)) + { + mc.SetBroadcasting(true); + } + } + } + + private static void StoppedSimulatingEntity(NitroxId id) + { + if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) + { + if (gameObject.TryGetComponent(out MovementController mc)) + { + mc.SetReceiving(true); + } + } + } + + private void Awake() + { + packetSender = NitroxServiceLocator.LocateService(); + simulationOwnership = NitroxServiceLocator.LocateService(); + if (!runOnce) + { + runOnce = true; + simulationOwnership.StartedSimulatingEntity += StartedSimulatingEntity; + simulationOwnership.StoppedSimulatingEntity += StoppedSimulatingEntity; + } + } private void Start() { rigidbody = GetComponent(); + if (!TryGetComponent(out NitroxEntity nitroxEntity)) + { + NitroxEntity.GenerateNewId(gameObject); + + nitroxEntity = GetComponent(); + } + entity = nitroxEntity; } private void Update() { BeforeUpdate(); - if (!rigidbody && IsMoving) + if (!rigidbody && Receiving) { - transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, Scalar * Time.deltaTime); + transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, Scalar * Time.deltaTime); transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, Scalar * Time.deltaTime); } AfterUpdate(); @@ -44,10 +121,22 @@ private void Update() private void FixedUpdate() { BeforeFixedUpdate(); - if (rigidbody && IsMoving) + + if (Broadcasting && simulationOwnership.HasAnyLockType(entity.Id)) + { + curTime += Time.fixedDeltaTime; + if (curTime >= LOCATION_BROADCAST_TIME) + { + curTime = 0f; + + packetSender.Send(new BasicMovement(entity.Id, transform.position.ToDto(), transform.rotation.ToDto())); + } + } + + if (rigidbody && Receiving) { float timing = Scalar * Time.fixedDeltaTime; - Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref Velocity, timing); + Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, timing); Quaternion newRot = Quaternion.Lerp(transform.rotation, TargetRotation, timing); if (rigidbody.isKinematic) @@ -57,7 +146,7 @@ private void FixedUpdate() } else { - rigidbody.velocity = Velocity; + rigidbody.velocity = velocity; Quaternion delta = TargetRotation * transform.rotation.GetInverse(); delta.ToAngleAxis(out float angle, out Vector3 axis); diff --git a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs index 4517d1eac3..574d23e21c 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs @@ -56,13 +56,12 @@ internal virtual void SetArmPositions(Vector3 leftArmPosition, Vector3 rightArmP internal virtual void Enter() { - movementController.IsMoving = true; + movementController.SetReceiving(true); enabled = true; } public virtual void Exit() { - movementController.IsMoving = false; enabled = false; } diff --git a/NitroxClient/MonoBehaviours/NitroxEntity.cs b/NitroxClient/MonoBehaviours/NitroxEntity.cs index 95b0206527..3b5f4accd3 100644 --- a/NitroxClient/MonoBehaviours/NitroxEntity.cs +++ b/NitroxClient/MonoBehaviours/NitroxEntity.cs @@ -80,7 +80,10 @@ public static void SetNewId(GameObject gameObject, NitroxId id) if (gameObject.TryGetComponent(out NitroxEntity entity)) { - gameObjectsById.Remove(entity.Id); + if (entity.Id != null) + { + gameObjectsById.Remove(entity.Id); + } } else { diff --git a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs index e5145de510..675689726b 100644 --- a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs +++ b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs @@ -41,7 +41,6 @@ public void FixedUpdate() } Vector3 currentPosition = Player.main.transform.position; - Vector3 playerVelocity = Player.main.playerController.velocity; // IDEA: possibly only CameraRotation is of interest, because bodyrotation is extracted from that. Quaternion bodyRotation = MainCameraControl.main.viewModel.transform.rotation; @@ -55,7 +54,7 @@ public void FixedUpdate() vehicle.Value.DriverRotation = Player.main.transform.rotation.ToDto(); } - localPlayer.BroadcastLocation(currentPosition, playerVelocity, bodyRotation, aimingRotation, vehicle); + localPlayer.BroadcastLocation(currentPosition, bodyRotation, aimingRotation, vehicle); } private Optional GetVehicleMovement() @@ -82,6 +81,11 @@ private Optional GetVehicleMovement() return Optional.Empty; } + if (vehicle.TryGetComponent(out MovementController mc)) + { + mc.SetReceiving(false); + } + Transform vehicleTransform = vehicle.transform; position = vehicleTransform.position; rotation = vehicleTransform.rotation; diff --git a/NitroxModel/Packets/BasicMovementPacket.cs b/NitroxModel/Packets/BasicMovementPacket.cs new file mode 100644 index 0000000000..2c5611eb94 --- /dev/null +++ b/NitroxModel/Packets/BasicMovementPacket.cs @@ -0,0 +1,29 @@ +using NitroxModel.DataStructures.Unity; +using NitroxModel.DataStructures; +using NitroxModel.Networking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static NitroxModel.Packets.Packet; + +namespace NitroxModel.Packets +{ + [Serializable] + public class BasicMovement : Movement + { + public override NitroxId Id { get; } + public override NitroxVector3 Position { get; } + public override NitroxQuaternion Rotation { get; } + + public BasicMovement(NitroxId id, NitroxVector3 position, NitroxQuaternion rotation) + { + Id = id; + Position = position; + Rotation = rotation; + DeliveryMethod = NitroxDeliveryMethod.DeliveryMethod.UNRELIABLE_SEQUENCED; + UdpChannel = UdpChannelId.MISC_MOVEMENT; + } + } +} diff --git a/NitroxModel/Packets/Movement.cs b/NitroxModel/Packets/Movement.cs index 03c1a46b49..7fef304003 100644 --- a/NitroxModel/Packets/Movement.cs +++ b/NitroxModel/Packets/Movement.cs @@ -1,13 +1,14 @@ using System; +using NitroxModel.DataStructures; using NitroxModel.DataStructures.Unity; +using NitroxModel.Networking; namespace NitroxModel.Packets; [Serializable] public abstract class Movement : Packet { - public abstract ushort PlayerId { get; } + public abstract NitroxId Id { get; } public abstract NitroxVector3 Position { get; } - public abstract NitroxQuaternion BodyRotation { get; } - public abstract NitroxQuaternion AimingRotation { get; } + public abstract NitroxQuaternion Rotation { get; } } diff --git a/NitroxModel/Packets/Packet.cs b/NitroxModel/Packets/Packet.cs index b49142aa3f..654eb66147 100644 --- a/NitroxModel/Packets/Packet.cs +++ b/NitroxModel/Packets/Packet.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -79,7 +79,8 @@ public enum UdpChannelId DEFAULT = 0, PLAYER_MOVEMENT = 1, VEHICLE_MOVEMENT = 2, - PLAYER_STATS = 3 + PLAYER_STATS = 3, + MISC_MOVEMENT = 4 } public byte[] Serialize() diff --git a/NitroxModel/Packets/PlayerMovement.cs b/NitroxModel/Packets/PlayerMovement.cs index 965d042eb7..78a5015db0 100644 --- a/NitroxModel/Packets/PlayerMovement.cs +++ b/NitroxModel/Packets/PlayerMovement.cs @@ -1,4 +1,5 @@ using System; +using NitroxModel.DataStructures; using NitroxModel.DataStructures.Unity; using NitroxModel.Networking; @@ -7,16 +8,16 @@ namespace NitroxModel.Packets [Serializable] public class PlayerMovement : Movement { - public override ushort PlayerId { get; } + public override NitroxId Id { get; } public override NitroxVector3 Position { get; } - public override NitroxQuaternion BodyRotation { get; } - public override NitroxQuaternion AimingRotation { get; } + public override NitroxQuaternion Rotation { get; } + public NitroxQuaternion AimingRotation { get; } - public PlayerMovement(ushort playerId, NitroxVector3 position, NitroxQuaternion bodyRotation, NitroxQuaternion aimingRotation) + public PlayerMovement(NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, NitroxQuaternion aimingRotation) { - PlayerId = playerId; + Id = id; Position = position; - BodyRotation = bodyRotation; + Rotation = rotation; AimingRotation = aimingRotation; DeliveryMethod = NitroxDeliveryMethod.DeliveryMethod.UNRELIABLE_SEQUENCED; UdpChannel = UdpChannelId.PLAYER_MOVEMENT; diff --git a/NitroxModel/Packets/VehicleMovement.cs b/NitroxModel/Packets/VehicleMovement.cs index 3ea1d356aa..aa784af085 100644 --- a/NitroxModel/Packets/VehicleMovement.cs +++ b/NitroxModel/Packets/VehicleMovement.cs @@ -1,5 +1,6 @@ using System; using BinaryPack.Attributes; +using NitroxModel.DataStructures; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.Unity; using NitroxModel.Networking; @@ -9,19 +10,18 @@ namespace NitroxModel.Packets [Serializable] public class VehicleMovement : Movement { - public override ushort PlayerId { get; } + public override NitroxId Id { get; } public VehicleMovementData VehicleMovementData { get; } [IgnoredMember] public override NitroxVector3 Position => VehicleMovementData.Position; [IgnoredMember] - public override NitroxQuaternion BodyRotation => VehicleMovementData.Rotation; - [IgnoredMember] - public override NitroxQuaternion AimingRotation => VehicleMovementData.Rotation; + public override NitroxQuaternion Rotation => VehicleMovementData.Rotation; - public VehicleMovement(ushort playerId, VehicleMovementData vehicleMovementData) + /// Player Id + public VehicleMovement(NitroxId id, VehicleMovementData vehicleMovementData) { - PlayerId = playerId; + Id = id; VehicleMovementData = vehicleMovementData; DeliveryMethod = NitroxDeliveryMethod.DeliveryMethod.UNRELIABLE_SEQUENCED; UdpChannel = UdpChannelId.VEHICLE_MOVEMENT; diff --git a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs index 78b05afb75..6c58e6d3fe 100644 --- a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs @@ -50,7 +50,7 @@ public static IEnumerable Transpiler(MethodBase original, IEnum public static bool IsMoving(GameObject go) { - return go.TryGetComponent(out MovementController mc) && mc.IsMoving; + return go.TryGetComponent(out MovementController mc) && mc.Receiving; } } } diff --git a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs index e96108c1d6..2974a75f8c 100644 --- a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs @@ -1,7 +1,8 @@ -using System.Reflection; +using System.Reflection; using NitroxClient.GameLogic; using NitroxClient.GameLogic.HUD.Components; using NitroxClient.GameLogic.Simulation; +using NitroxClient.MonoBehaviours; using NitroxModel.DataStructures; using NitroxModel.Helper; @@ -50,6 +51,10 @@ private static void ReceivedSimulationLockResponse(NitroxId id, bool lockAquired { skipPrefix = true; pilotingChair.OnHandClick(context.GuiHand); + if (pilotingChair.subRoot.TryGetComponent(out MovementController mc)) + { + mc.SetBroadcasting(false); + } skipPrefix = false; } else diff --git a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs index 95ff53903a..3e246488f5 100644 --- a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs @@ -1,5 +1,6 @@ -using System.Reflection; +using System.Reflection; using NitroxClient.GameLogic; +using NitroxClient.MonoBehaviours; using NitroxModel.DataStructures; using NitroxModel.Helper; @@ -18,6 +19,10 @@ public static void Postfix(PilotingChair __instance) { // Request to be downgraded to a transient lock so we can still simulate the positioning. Resolve().RequestSimulationLock(id, SimulationLockType.TRANSIENT); + if (__instance.subRoot.TryGetComponent(out MovementController mc)) + { + mc.SetBroadcasting(true); + } } } } diff --git a/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs b/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs index 6f30e5684a..8d7838f946 100644 --- a/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs @@ -1,5 +1,6 @@ -using System.Reflection; +using System.Reflection; using NitroxClient.GameLogic; +using NitroxClient.MonoBehaviours; using NitroxModel.DataStructures; using NitroxModel.Helper; @@ -18,6 +19,10 @@ public static void Postfix(PilotingChair __instance) { // Request to be downgraded to a transient lock so we can still simulate the positioning. Resolve().RequestSimulationLock(id, SimulationLockType.TRANSIENT); + if (__instance.subRoot.TryGetComponent(out MovementController mc)) + { + mc.SetBroadcasting(true); + } } } } diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs index 73711d9c10..ef9a38448d 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs @@ -1,5 +1,6 @@ -using System.Reflection; +using System.Reflection; using NitroxClient.GameLogic; +using NitroxClient.MonoBehaviours; using NitroxModel.Helper; namespace NitroxPatcher.Patches.Dynamic; @@ -11,5 +12,9 @@ public sealed partial class Vehicle_OnPilotModeBegin_Patch : NitroxPatch, IDynam public static void Prefix(Vehicle __instance) { Resolve().BroadcastOnPilotModeChanged(__instance, true); + if (__instance.TryGetComponent(out MovementController mc)) + { + mc.SetBroadcasting(false); + } } } diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs index a86d788319..eb06a9e0f3 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; using NitroxModel.DataStructures; @@ -22,6 +22,10 @@ public static void Prefix(Vehicle __instance) if (__instance.TryGetIdOrWarn(out NitroxId id)) { Resolve().RequestSimulationLock(id, SimulationLockType.TRANSIENT); + if (__instance.TryGetComponent(out MovementController mc)) + { + mc.SetBroadcasting(true); + } } } } diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs index 821d0801bb..7b2e48e954 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs @@ -10,9 +10,9 @@ public sealed partial class Vehicle_ShouldSetKinematic_Patch : NitroxPatch, IDyn public static bool Prefix(Vehicle __instance, ref bool __result) { - if (__instance.TryGetComponent(out MovementController movementController)) + if (__instance.TryGetComponent(out MovementController movementController) && movementController.Receiving) { - __result = !movementController.IsMoving; + __result = true; return false; } return true; diff --git a/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs b/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs new file mode 100644 index 0000000000..5c758d9256 --- /dev/null +++ b/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs @@ -0,0 +1,35 @@ +using NitroxModel.DataStructures.GameLogic; +using NitroxModel.DataStructures.GameLogic.Entities; +using NitroxModel.DataStructures.Util; +using NitroxModel.Packets; +using NitroxServer.Communication.Packets.Processors.Abstract; +using NitroxServer.GameLogic; +using NitroxServer.GameLogic.Entities; + +namespace NitroxServer.Communication.Packets.Processors +{ + class BasicMovementPacketProcessor : AuthenticatedPacketProcessor + { + private readonly PlayerManager playerManager; + private readonly EntityRegistry entityRegistry; + + public BasicMovementPacketProcessor(PlayerManager playerManager, EntityRegistry entityRegistry) + { + this.playerManager = playerManager; + this.entityRegistry = entityRegistry; + } + + public override void Process(BasicMovement packet, Player player) + { + Optional entity = entityRegistry.GetEntityById(packet.Id); + + if (entity.HasValue) + { + entity.Value.Transform.Position = packet.Position; + entity.Value.Transform.Rotation = packet.Rotation; + } + + playerManager.SendPacketToOtherPlayers(packet, player); + } + } +} diff --git a/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs b/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs index f84bbfeb36..b11642dabd 100644 --- a/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs @@ -26,11 +26,11 @@ public override void Process(PlayerMovement packet, Player player) if (playerEntity.HasValue) { playerEntity.Value.Transform.Position = packet.Position; - playerEntity.Value.Transform.Rotation = packet.BodyRotation; + playerEntity.Value.Transform.Rotation = packet.Rotation; } player.Position = packet.Position; - player.Rotation = packet.BodyRotation; + player.Rotation = packet.Rotation; playerManager.SendPacketToOtherPlayers(packet, player); } } diff --git a/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs b/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs index 6a22c3c9de..c222de6866 100644 --- a/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs @@ -29,7 +29,7 @@ public override void Process(VehicleMovement packet, Player player) worldVehicle.Transform.Rotation = packet.VehicleMovementData.Rotation; } - if (player.Id == packet.PlayerId) + if (player.GameObjectId == packet.Id) { player.Position = packet.VehicleMovementData.DriverPosition; player.Rotation = packet.VehicleMovementData.DriverRotation; ; From 0371b0f621bddff1bd359d773be0a16e9fe6d325 Mon Sep 17 00:00:00 2001 From: tornac1234 Date: Fri, 18 Aug 2023 19:57:05 -0400 Subject: [PATCH 05/19] add QoL change to GroundMotor.movingPlatform.movementTransfer Co-authored-by: tornac1234 --- .../Dynamic/SubRoot_OnPlayerEntered_Patch.cs | 11 +++++++++- .../Dynamic/SubRoot_OnPlayerExited_Patch.cs | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs diff --git a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs index d5821e4ce6..2fbab0f024 100644 --- a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -60,4 +60,13 @@ public static IEnumerable Transpiler(MethodBase original, IEnum } return instructionList; } + + public static void Prefix() + { + PlayerMotor motor = Player.main.playerController.activeController; + if (motor is GroundMotor groundMotor) + { + groundMotor.movingPlatform.movementTransfer = GroundMotor.MovementTransferOnJump.PermaLocked; + } + } } diff --git a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs new file mode 100644 index 0000000000..562dacd6d7 --- /dev/null +++ b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using HarmonyLib; +using NitroxModel.Helper; + +namespace NitroxPatcher.Patches.Dynamic; + +public sealed partial class SubRoot_OnPlayerExited_Patch : NitroxPatch, IDynamicPatch +{ + private static readonly MethodInfo TARGET_METHOD = Reflect.Method((SubRoot t) => t.OnPlayerExited(default(Player))); + + public static void Prefix() + { + PlayerMotor motor = Player.main.playerController.activeController; + if (motor is GroundMotor groundMotor) + { + groundMotor.movingPlatform.movementTransfer = GroundMotor.MovementTransferOnJump.PermaTransfer; + } + } +} From 16f4d512550830ed4201925c6c953e8a07df19a1 Mon Sep 17 00:00:00 2001 From: killzoms Date: Fri, 18 Aug 2023 20:34:06 -0400 Subject: [PATCH 06/19] disallow High Precision physics when the Cyclops is being simulated --- .../Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs b/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs index 9b1a287d49..c96ed54f16 100644 --- a/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs @@ -18,11 +18,11 @@ public static bool Prefix(ref bool __result) { if (Player.main.currentSub) { - MultiplayerCyclops cyclops = Player.main.currentSub.GetComponent(); + MovementController movementController = Player.main.currentSub.GetComponent(); - if (cyclops) + if (movementController && movementController.Receiving) { - __result = (cyclops.CurrentPlayer != null); + __result = false; return false; } } From 58380f4f9ddb37ef9673698ba4f94643f9b97ab9 Mon Sep 17 00:00:00 2001 From: killzoms Date: Fri, 29 Sep 2023 17:29:09 -0400 Subject: [PATCH 07/19] latest changes --- .../WorldEntities/EscapePodWorldEntitySpawner.cs | 13 +++++++++++-- .../WorldEntities/ReefbackWorldEntitySpawner.cs | 6 ++++++ .../WorldEntities/WorldEntitySpawnerResolver.cs | 2 +- NitroxClient/MonoBehaviours/MovementController.cs | 9 +++++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs index 0266fdb6cc..fec52948eb 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs @@ -2,6 +2,7 @@ using NitroxClient.GameLogic.Spawning.Metadata; using NitroxClient.MonoBehaviours; using NitroxClient.MonoBehaviours.Overrides; +using NitroxModel.DataStructures; using NitroxModel.DataStructures.GameLogic.Entities; using NitroxModel.DataStructures.Util; using NitroxModel_Subnautica.DataStructures; @@ -17,6 +18,12 @@ public class EscapePodWorldEntitySpawner : IWorldEntitySpawner * EscapePod.main to the new escape pod. */ public static bool SURPRESS_ESCAPE_POD_AWAKE_METHOD; + private SimulationOwnership simulationOwnership; + + public EscapePodWorldEntitySpawner(SimulationOwnership simulationOwnership) + { + this.simulationOwnership = simulationOwnership; + } public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, EntityCell cellRoot, TaskResult> result) { @@ -30,6 +37,8 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, E SURPRESS_ESCAPE_POD_AWAKE_METHOD = true; GameObject escapePod = CreateNewEscapePod(escapePodEntity); + escapePod.EnsureComponent(); + simulationOwnership.RequestSimulationLock(entity.Id, SimulationLockType.TRANSIENT); SURPRESS_ESCAPE_POD_AWAKE_METHOD = false; @@ -48,7 +57,7 @@ private static GameObject CreateNewEscapePod(EscapePodWorldEntity escapePodEntit EntityMetadataProcessor.ApplyMetadata(escapePod, escapePodEntity.Metadata); - Rigidbody rigidbody = escapePod.GetComponent(); + Rigidbody rigidbody = escapePod.GetComponent();/* if (rigidbody != null) { rigidbody.constraints = RigidbodyConstraints.FreezeAll; @@ -57,7 +66,7 @@ private static GameObject CreateNewEscapePod(EscapePodWorldEntity escapePodEntit { Log.Error("Escape pod did not have a rigid body!"); } - + */ escapePod.transform.position = escapePodEntity.Transform.Position.ToUnity(); FixStartMethods(escapePod); diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs index 06777200ce..b69f75431c 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/ReefbackWorldEntitySpawner.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.GameLogic.Entities; @@ -38,6 +39,11 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, E { if (childEntity is WorldEntity worldChild) { + if (DateTime.Now.Month == 4 && DateTime.Now.Day == 1) + { + worldChild.ClassId = entity.ClassId; // Reefback Migration + } + TaskResult> childTaskResult = new(); yield return defaultSpawner.SpawnAsync(worldChild, reefback, cellRoot, childTaskResult); Optional child = childTaskResult.Get(); diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs index cffe88d273..7928d3a9d4 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/WorldEntitySpawnerResolver.cs @@ -19,7 +19,7 @@ public WorldEntitySpawnerResolver(PlayerManager playerManager, ILocalNitroxPlaye { customSpawnersByTechType[TechType.Crash] = new CrashEntitySpawner(); customSpawnersByTechType[TechType.Reefback] = new ReefbackWorldEntitySpawner(defaultEntitySpawner); - customSpawnersByTechType[TechType.EscapePod] = new EscapePodWorldEntitySpawner(); + customSpawnersByTechType[TechType.EscapePod] = new EscapePodWorldEntitySpawner(simulationOwnership); vehicleWorldEntitySpawner = new(entities); prefabWorldEntitySpawner = new PlaceholderGroupWorldEntitySpawner(this, defaultEntitySpawner); diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MovementController.cs index 8efca21501..cde6cb8156 100644 --- a/NitroxClient/MonoBehaviours/MovementController.cs +++ b/NitroxClient/MonoBehaviours/MovementController.cs @@ -137,12 +137,11 @@ private void FixedUpdate() { float timing = Scalar * Time.fixedDeltaTime; Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, timing); - Quaternion newRot = Quaternion.Lerp(transform.rotation, TargetRotation, timing); if (rigidbody.isKinematic) { rigidbody.MovePosition(newPos); - rigidbody.MoveRotation(newRot); + rigidbody.MoveRotation(TargetRotation); } else { @@ -150,8 +149,14 @@ private void FixedUpdate() Quaternion delta = TargetRotation * transform.rotation.GetInverse(); delta.ToAngleAxis(out float angle, out Vector3 axis); + if (!float.IsInfinity(axis.x) && !float.IsInfinity(axis.y) && !float.IsInfinity(axis.z)) { + if (angle > 180f) + { + angle -= 360f; + } + rigidbody.angularVelocity = .9f * Mathf.Deg2Rad * angle / timing * axis; } else From 2b30676b550a7a8d05d133387f80fc030e365461 Mon Sep 17 00:00:00 2001 From: killzoms Date: Sat, 30 Sep 2023 18:14:21 -0400 Subject: [PATCH 08/19] couple bug fixes --- .../SimulationOwnershipResponseProcessor.cs | 2 +- .../GroundMotor_UpdateFunction_Patch.cs | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs diff --git a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs index f7faca9962..a3b0c9e681 100644 --- a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs @@ -58,7 +58,7 @@ private void SwapMovementController(NitroxId id, bool lockAcquired) if (gameObject.HasValue) { - MovementController movementController = gameObject.Value.GetComponent(); + MovementController movementController = gameObject.Value.EnsureComponent(); movementController.SetBroadcasting(lockAcquired); movementController.SetReceiving(!lockAcquired); } diff --git a/NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs b/NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs new file mode 100644 index 0000000000..1a093d3a0a --- /dev/null +++ b/NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs @@ -0,0 +1,28 @@ +using System.Reflection; +using NitroxClient.GameLogic; +using NitroxModel.DataStructures; +using NitroxModel.DataStructures.GameLogic.Entities.Metadata; +using NitroxModel.Helper; +using NitroxModel_Subnautica.DataStructures; +using UnityEngine; + +namespace NitroxPatcher.Patches.Dynamic; + +public sealed partial class GroundMotor_UpdateFunction_Patch : NitroxPatch, IDynamicPatch +{ + private static readonly MethodInfo TARGET_METHOD = Reflect.Method((GroundMotor t) => t.UpdateFunction()); + + public static void Postfix(GroundMotor __instance) + { + if (Physics.Raycast(__instance.transform.position + __instance.controller.center + Vector3.down * __instance.controller.height * 0.5f, Vector3.down, out RaycastHit hitInfo, __instance.controller.skinWidth + 0.01f) && hitInfo.transform.TryGetComponent(out Rigidbody rb)) + { + Vector3 platformPosition = hitInfo.transform.position; + Vector3 rbPosition = rb.position; + + Vector3 posRelativeToRigidbody = __instance.transform.position - rbPosition; + Vector3 posRelativeToPlatform = posRelativeToRigidbody + platformPosition; + + __instance.transform.position = posRelativeToPlatform; + } + } +} From 2f29edbccfe9fbed9b9881db4a50b8a8aa68ff57 Mon Sep 17 00:00:00 2001 From: killzoms Date: Sat, 30 Sep 2023 18:41:45 -0400 Subject: [PATCH 09/19] movementTransfer patch fix --- .../Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs | 7 ++----- .../Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs index 2fbab0f024..504a773049 100644 --- a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerEntered_Patch.cs @@ -63,10 +63,7 @@ public static IEnumerable Transpiler(MethodBase original, IEnum public static void Prefix() { - PlayerMotor motor = Player.main.playerController.activeController; - if (motor is GroundMotor groundMotor) - { - groundMotor.movingPlatform.movementTransfer = GroundMotor.MovementTransferOnJump.PermaLocked; - } + GroundMotor motor = Player.main.groundMotor; + motor.movingPlatform.movementTransfer = GroundMotor.MovementTransferOnJump.PermaLocked; } } diff --git a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs index 562dacd6d7..5fbd3d6dfe 100644 --- a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs @@ -13,10 +13,7 @@ public sealed partial class SubRoot_OnPlayerExited_Patch : NitroxPatch, IDynamic public static void Prefix() { - PlayerMotor motor = Player.main.playerController.activeController; - if (motor is GroundMotor groundMotor) - { - groundMotor.movingPlatform.movementTransfer = GroundMotor.MovementTransferOnJump.PermaTransfer; - } + GroundMotor motor = Player.main.groundMotor; + motor.movingPlatform.movementTransfer = GroundMotor.MovementTransferOnJump.PermaTransfer; } } From 22caa5bdb115b12f1854ebaad89be3f83e279072 Mon Sep 17 00:00:00 2001 From: killzoms Date: Sat, 21 Oct 2023 13:36:51 -0400 Subject: [PATCH 10/19] Reapply HighPrecisionPhysics --- .../GameLogic/Spawning/WorldEntitySpawner.cs | 49 +------------------ .../GroundMotor_UpdateFunction_Patch.cs | 28 ----------- ...ayer_RequiresHighPrecisionPhysics_Patch.cs | 2 +- 3 files changed, 3 insertions(+), 76 deletions(-) delete mode 100644 NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs diff --git a/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs index 6e0579b3a6..04080a1e55 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntitySpawner.cs @@ -22,54 +22,9 @@ public WorldEntitySpawner(PlayerManager playerManager, ILocalNitroxPlayer localP { worldEntitySpawnResolver = new WorldEntitySpawnerResolver(playerManager, localPlayer, simulationOwnership, entities); - if (NitroxEnvironment.IsNormal) - { - batchCellsById = (Dictionary)LargeWorldStreamer.main.cellManager.batch2cells; - } - } - - public override IEnumerator SpawnAsync(WorldEntity entity, TaskResult> result) + if (NitroxEnvironment.IsNormal) { - LargeWorldStreamer.main.cellManager.UnloadBatchCells(entity.AbsoluteEntityCell.CellId.ToUnity()); // Just in case - - EntityCell cellRoot = EnsureCell(entity); - - Optional parent = (entity.ParentId != null) ? NitroxEntity.GetObjectFrom(entity.ParentId) : Optional.Empty; - - IWorldEntitySpawner entitySpawner = worldEntitySpawnResolver.ResolveEntitySpawner(entity); - - return entitySpawner.SpawnAsync(entity, parent, cellRoot, result); - } - public override bool SpawnsOwnChildren(WorldEntity entity) - { - IWorldEntitySpawner entitySpawner = worldEntitySpawnResolver.ResolveEntitySpawner(entity); - return entitySpawner.SpawnsOwnChildren(); - } - - private EntityCell EnsureCell(WorldEntity entity) - { - EntityCell entityCell; - - Int3 batchId = entity.AbsoluteEntityCell.BatchId.ToUnity(); - Int3 cellId = entity.AbsoluteEntityCell.CellId.ToUnity(); - - if (!batchCellsById.TryGetValue(batchId, out BatchCells batchCells)) - { - batchCells = LargeWorldStreamer.main.cellManager.InitializeBatchCells(batchId); - } - - entityCell = batchCells.Get(cellId, entity.AbsoluteEntityCell.Level); - - if (entityCell == null) - { - entityCell = batchCells.Add(cellId, entity.AbsoluteEntityCell.Level); - entityCell.Initialize(); - } - - entityCell.EnsureRoot(); - - return entityCell; ->>>>>>> ddf37665 (first round of bug fixes) + batchCellsById = (Dictionary)LargeWorldStreamer.main.cellManager.batch2cells; } } diff --git a/NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs b/NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs deleted file mode 100644 index 1a093d3a0a..0000000000 --- a/NitroxPatcher/Patches/Dynamic/GroundMotor_UpdateFunction_Patch.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Reflection; -using NitroxClient.GameLogic; -using NitroxModel.DataStructures; -using NitroxModel.DataStructures.GameLogic.Entities.Metadata; -using NitroxModel.Helper; -using NitroxModel_Subnautica.DataStructures; -using UnityEngine; - -namespace NitroxPatcher.Patches.Dynamic; - -public sealed partial class GroundMotor_UpdateFunction_Patch : NitroxPatch, IDynamicPatch -{ - private static readonly MethodInfo TARGET_METHOD = Reflect.Method((GroundMotor t) => t.UpdateFunction()); - - public static void Postfix(GroundMotor __instance) - { - if (Physics.Raycast(__instance.transform.position + __instance.controller.center + Vector3.down * __instance.controller.height * 0.5f, Vector3.down, out RaycastHit hitInfo, __instance.controller.skinWidth + 0.01f) && hitInfo.transform.TryGetComponent(out Rigidbody rb)) - { - Vector3 platformPosition = hitInfo.transform.position; - Vector3 rbPosition = rb.position; - - Vector3 posRelativeToRigidbody = __instance.transform.position - rbPosition; - Vector3 posRelativeToPlatform = posRelativeToRigidbody + platformPosition; - - __instance.transform.position = posRelativeToPlatform; - } - } -} diff --git a/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs b/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs index c96ed54f16..56abb89188 100644 --- a/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs @@ -22,7 +22,7 @@ public static bool Prefix(ref bool __result) if (movementController && movementController.Receiving) { - __result = false; + __result = true; return false; } } From 65d02842bea1aee8b9f143534fcddae4b33f6159 Mon Sep 17 00:00:00 2001 From: killzoms Date: Wed, 22 Nov 2023 22:46:31 -0500 Subject: [PATCH 11/19] removed all unused usings, made most requested changes --- .editorconfig | 80 +++++++++++++++++++ .../Diagnostics/EnumeratorUsageAnalyzer.cs | 2 +- Nitrox.Test/Helper/Faker/NitroxAutoFaker.cs | 1 - .../Dynamic/DevConsole_Update_PatchTest.cs | 2 +- .../Serialization/WorldPersistenceTest.cs | 1 - NitroxClient/ClientAutoFacRegistrar.cs | 2 - .../MultiplayerSessionManager.cs | 1 - .../Processors/BasicMovementProcessor.cs | 18 ++--- .../Processors/ExosuitArmActionProcessor.cs | 3 +- .../Processors/ItemPositionProcessor.cs | 1 - .../Processors/PlayerMovementProcessor.cs | 3 - .../SimulationOwnershipResponseProcessor.cs | 13 +-- NitroxClient/GameLogic/LiveMixinManager.cs | 1 - NitroxClient/GameLogic/MobileVehicleBay.cs | 2 +- NitroxClient/GameLogic/RemotePlayer.cs | 2 +- NitroxClient/GameLogic/SimulationOwnership.cs | 12 +-- .../Spawning/Bases/BuildEntitySpawner.cs | 1 - .../Metadata/RocketMetadataProcessor.cs | 1 - .../EscapePodWorldEntitySpawner.cs | 11 +-- .../VehicleWorldEntitySpawner.cs | 13 ++- NitroxClient/Helpers/MovementHelper.cs | 2 +- .../MonoBehaviours/MovementController.cs | 5 -- .../MonoBehaviours/MultiplayerExosuit.cs | 1 - .../MultiplayerVehicleControl.cs | 2 - NitroxClient/MonoBehaviours/NitroxEntity.cs | 27 +++++++ .../MonoBehaviours/RemotelyControlled.cs | 1 - NitroxLauncher/Properties/AssemblyInfo.cs | 8 +- .../Packets/ExosuitArmActionPacket.cs | 1 - .../GameLogic/VehicleMovementData.cs | 10 +-- NitroxModel/Packets/BasicMovementPacket.cs | 36 ++++----- NitroxModel/Packets/Movement.cs | 1 - .../Platforms/OS/Windows/WinFileSystem.cs | 1 - NitroxPatcher/Main.cs | 1 - .../Dynamic/Bed_EnterInUseMode_Patch.cs | 1 - .../Dynamic/FMOD_CustomEmitter_Start_Patch.cs | 2 +- ...reezeRigidbodyWhenFar_FixedUpdate_Patch.cs | 63 +++++++-------- .../Dynamic/SubRoot_OnPlayerExited_Patch.cs | 4 - .../BasicMovementPacketProcessor.cs | 1 - .../Processors/PlayerMovementProcessor.cs | 1 - .../VehicleMovementPacketProcessor.cs | 2 +- .../Entities/Spawning/IEntityBootstrapper.cs | 4 +- NitroxServer/Properties/AssemblyInfo.cs | 1 - .../Serialization/BatchCellsParser.cs | 1 - 43 files changed, 192 insertions(+), 154 deletions(-) diff --git a/.editorconfig b/.editorconfig index c96fce69ad..be3fbe2414 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,6 +12,38 @@ resharper_wrap_object_and_collection_initializer_style = chop_if_long [*.{proj, csproj, targets}] indent_size = 4 insert_final_newline = true +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_readonly_field = true:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion +dotnet_style_allow_multiple_blank_lines_experimental = true:silent +dotnet_style_allow_statement_immediately_after_block_experimental = true:silent +dotnet_code_quality_unused_parameters = all:suggestion +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent [App.config] indent_size = 4 @@ -21,6 +53,54 @@ insert_final_newline = true indent_size = 4 insert_final_newline = true charset = utf-8 +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = file_scoped:suggestion +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_indent_labels = one_less_than_current +csharp_style_throw_expression = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent +csharp_prefer_static_local_function = true:suggestion +csharp_style_prefer_readonly_struct = true:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent +csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = false:silent +csharp_space_around_binary_operators = before_and_after [*.g.cs] generated_code = true diff --git a/Nitrox.Analyzers/Diagnostics/EnumeratorUsageAnalyzer.cs b/Nitrox.Analyzers/Diagnostics/EnumeratorUsageAnalyzer.cs index 22e93cac8f..3cdd5c25d7 100644 --- a/Nitrox.Analyzers/Diagnostics/EnumeratorUsageAnalyzer.cs +++ b/Nitrox.Analyzers/Diagnostics/EnumeratorUsageAnalyzer.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; diff --git a/Nitrox.Test/Helper/Faker/NitroxAutoFaker.cs b/Nitrox.Test/Helper/Faker/NitroxAutoFaker.cs index 6507060e44..164867568c 100644 --- a/Nitrox.Test/Helper/Faker/NitroxAutoFaker.cs +++ b/Nitrox.Test/Helper/Faker/NitroxAutoFaker.cs @@ -6,7 +6,6 @@ using System.Runtime.Serialization; using System.Text.RegularExpressions; using BinaryPack.Attributes; -using NitroxModel.Logger; namespace Nitrox.Test.Helper.Faker; diff --git a/Nitrox.Test/Patcher/Patches/Dynamic/DevConsole_Update_PatchTest.cs b/Nitrox.Test/Patcher/Patches/Dynamic/DevConsole_Update_PatchTest.cs index 03a1625aa1..8850ffe5a6 100644 --- a/Nitrox.Test/Patcher/Patches/Dynamic/DevConsole_Update_PatchTest.cs +++ b/Nitrox.Test/Patcher/Patches/Dynamic/DevConsole_Update_PatchTest.cs @@ -1,4 +1,4 @@ -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; using System.Linq; using FluentAssertions; using HarmonyLib; diff --git a/Nitrox.Test/Server/Serialization/WorldPersistenceTest.cs b/Nitrox.Test/Server/Serialization/WorldPersistenceTest.cs index 8c3741ed66..66d4e52f97 100644 --- a/Nitrox.Test/Server/Serialization/WorldPersistenceTest.cs +++ b/Nitrox.Test/Server/Serialization/WorldPersistenceTest.cs @@ -5,7 +5,6 @@ using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; using Nitrox.Test; -using Nitrox.Test.Helper; using Nitrox.Test.Helper.Faker; using NitroxModel.Core; using NitroxModel.DataStructures.GameLogic; diff --git a/NitroxClient/ClientAutoFacRegistrar.cs b/NitroxClient/ClientAutoFacRegistrar.cs index 96942f362a..9355fb24a2 100644 --- a/NitroxClient/ClientAutoFacRegistrar.cs +++ b/NitroxClient/ClientAutoFacRegistrar.cs @@ -9,8 +9,6 @@ using NitroxClient.Communication.MultiplayerSession; using NitroxClient.Communication.NetworkingLayer.LiteNetLib; using NitroxClient.Communication.Packets.Processors.Abstract; -using NitroxClient.Debuggers; -using NitroxClient.Debuggers.Drawer; using NitroxClient.GameLogic; using NitroxClient.GameLogic.ChatUI; using NitroxClient.GameLogic.FMOD; diff --git a/NitroxClient/Communication/MultiplayerSession/MultiplayerSessionManager.cs b/NitroxClient/Communication/MultiplayerSession/MultiplayerSessionManager.cs index 3abe212d48..5554ca0af7 100644 --- a/NitroxClient/Communication/MultiplayerSession/MultiplayerSessionManager.cs +++ b/NitroxClient/Communication/MultiplayerSession/MultiplayerSessionManager.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using NitroxClient.Communication.Abstract; using NitroxClient.Communication.MultiplayerSession.ConnectionState; diff --git a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs index 84f465361a..1fe87984d1 100644 --- a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs @@ -1,26 +1,22 @@ -using System.Collections; using NitroxClient.Communication.Packets.Processors.Abstract; -using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; -using NitroxClient.Unity.Helper; -using NitroxModel_Subnautica.DataStructures; -using NitroxModel.DataStructures.Util; using NitroxModel.Packets; +using NitroxModel_Subnautica.DataStructures; using UnityEngine; namespace NitroxClient.Communication.Packets.Processors; public class BasicMovementProcessor : ClientPacketProcessor { - public BasicMovementProcessor() - { - } - public override void Process(BasicMovement movement) { - if (NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) + if (!NitroxEntity.TryGetMovementControllerFrom(movement.Id, out MovementController mc) && NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) + { + mc = gameObject.EnsureComponent(); + } + + if (mc) { - MovementController mc = gameObject.EnsureComponent(); mc.TargetPosition = movement.Position.ToUnity(); mc.TargetRotation = movement.Rotation.ToUnity(); } diff --git a/NitroxClient/Communication/Packets/Processors/ExosuitArmActionProcessor.cs b/NitroxClient/Communication/Packets/Processors/ExosuitArmActionProcessor.cs index 3e8f75ac91..e8a510efa0 100644 --- a/NitroxClient/Communication/Packets/Processors/ExosuitArmActionProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/ExosuitArmActionProcessor.cs @@ -1,5 +1,4 @@ -using System; -using NitroxClient.Communication.Abstract; +using NitroxClient.Communication.Abstract; using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; diff --git a/NitroxClient/Communication/Packets/Processors/ItemPositionProcessor.cs b/NitroxClient/Communication/Packets/Processors/ItemPositionProcessor.cs index 25ea4dfbfb..fe4f8c8f5c 100644 --- a/NitroxClient/Communication/Packets/Processors/ItemPositionProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/ItemPositionProcessor.cs @@ -1,5 +1,4 @@ using NitroxClient.Communication.Packets.Processors.Abstract; -using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; using NitroxModel.DataStructures.Util; using NitroxModel.Packets; diff --git a/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs index 75ee300f11..10662dc7fd 100644 --- a/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/PlayerMovementProcessor.cs @@ -1,8 +1,5 @@ -using System.Collections; using NitroxClient.Communication.Packets.Processors.Abstract; using NitroxClient.GameLogic; -using NitroxClient.MonoBehaviours; -using NitroxClient.Unity.Helper; using NitroxModel_Subnautica.DataStructures; using NitroxModel.DataStructures.Util; using NitroxModel.Packets; diff --git a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs index a3b0c9e681..657899c9ab 100644 --- a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs @@ -3,7 +3,6 @@ using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; using NitroxModel.DataStructures; -using NitroxModel.DataStructures.Util; using NitroxModel.Packets; using UnityEngine; @@ -43,22 +42,18 @@ public override void Process(SimulationOwnershipResponse response) private void RemoveRemoteController(NitroxId id) { - Optional gameObject = NitroxEntity.GetObjectFrom(id); - - if (gameObject.HasValue) + if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) { - RemotelyControlled remotelyControlled = gameObject.Value.GetComponent(); + RemotelyControlled remotelyControlled = gameObject.GetComponent(); Object.Destroy(remotelyControlled); } } private void SwapMovementController(NitroxId id, bool lockAcquired) { - Optional gameObject = NitroxEntity.GetObjectFrom(id); - - if (gameObject.HasValue) + if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) { - MovementController movementController = gameObject.Value.EnsureComponent(); + MovementController movementController = gameObject.EnsureComponent(); movementController.SetBroadcasting(lockAcquired); movementController.SetReceiving(!lockAcquired); } diff --git a/NitroxClient/GameLogic/LiveMixinManager.cs b/NitroxClient/GameLogic/LiveMixinManager.cs index f8f2e0da9b..b24b3694d6 100644 --- a/NitroxClient/GameLogic/LiveMixinManager.cs +++ b/NitroxClient/GameLogic/LiveMixinManager.cs @@ -1,4 +1,3 @@ -using NitroxClient.MonoBehaviours; using NitroxModel.DataStructures; using UnityEngine; diff --git a/NitroxClient/GameLogic/MobileVehicleBay.cs b/NitroxClient/GameLogic/MobileVehicleBay.cs index 1d19c0fbdd..2cae9073c2 100644 --- a/NitroxClient/GameLogic/MobileVehicleBay.cs +++ b/NitroxClient/GameLogic/MobileVehicleBay.cs @@ -42,7 +42,7 @@ public void BeginCrafting(ConstructorInput constructor, GameObject constructedOb NitroxId constructedObjectId = NitroxEntity.GenerateNewId(constructedObject); - MovementController mc = constructedObject.AddComponent(); + constructedObject.AddComponent(); VehicleWorldEntity vehicleEntity = new(constructorId, DayNightCycle.main.timePassedAsFloat, constructedObject.transform.ToLocalDto(), string.Empty, false, constructedObjectId, techType.ToDto(), null); VehicleChildEntityHelper.PopulateChildren(constructedObjectId, constructedObject.GetFullHierarchyPath(), vehicleEntity.ChildEntities, constructedObject); diff --git a/NitroxClient/GameLogic/RemotePlayer.cs b/NitroxClient/GameLogic/RemotePlayer.cs index 15b4fbfac5..dc1edf054f 100644 --- a/NitroxClient/GameLogic/RemotePlayer.cs +++ b/NitroxClient/GameLogic/RemotePlayer.cs @@ -141,7 +141,6 @@ public void SetPilotingChair(PilotingChair newPilotingChair) if (PilotingChair != newPilotingChair) { PilotingChair = newPilotingChair; - bool isInPilotingChair = newPilotingChair != null; MultiplayerCyclops mpCyclops = null; @@ -175,6 +174,7 @@ public void SetPilotingChair(PilotingChair newPilotingChair) } } + bool isInPilotingChair = newPilotingChair != null; RigidBody.isKinematic = AnimationController["cyclops_steering"] = isInPilotingChair; RigidBody.interpolation = isInPilotingChair ? RigidbodyInterpolation.None : RigidbodyInterpolation.Interpolate; if (isInPilotingChair) diff --git a/NitroxClient/GameLogic/SimulationOwnership.cs b/NitroxClient/GameLogic/SimulationOwnership.cs index f8024266df..391d08ecf4 100644 --- a/NitroxClient/GameLogic/SimulationOwnership.cs +++ b/NitroxClient/GameLogic/SimulationOwnership.cs @@ -14,8 +14,8 @@ public class SimulationOwnership private readonly Dictionary simulatedIdsByLockType = new Dictionary(); private readonly Dictionary lockRequestsById = new Dictionary(); - public event Action StoppedSimulatingEntity; public event Action StartedSimulatingEntity; + public event Action StoppedSimulatingEntity; public SimulationOwnership(IMultiplayerSession muliplayerSession, IPacketSender packetSender) { @@ -72,20 +72,14 @@ public void ReceivedSimulationLockResponse(NitroxId id, bool lockAquired, Simula public void SimulateEntity(NitroxId id, SimulationLockType lockType) { simulatedIdsByLockType[id] = lockType; - if (StartedSimulatingEntity != null) - { - StartedSimulatingEntity(id); - } + StartedSimulatingEntity?.Invoke(id); } public void StopSimulatingEntity(NitroxId id) { simulatedIdsByLockType.Remove(id); - if (StoppedSimulatingEntity != null) - { - StoppedSimulatingEntity(id); - } + StoppedSimulatingEntity?.Invoke(id); } } } diff --git a/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs index 6144c78d2d..2bf12b13fb 100644 --- a/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs @@ -1,6 +1,5 @@ using System.Collections; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using NitroxClient.GameLogic.Bases; using NitroxClient.GameLogic.Helper; diff --git a/NitroxClient/GameLogic/Spawning/Metadata/RocketMetadataProcessor.cs b/NitroxClient/GameLogic/Spawning/Metadata/RocketMetadataProcessor.cs index 4219c05756..4bbf003b94 100644 --- a/NitroxClient/GameLogic/Spawning/Metadata/RocketMetadataProcessor.cs +++ b/NitroxClient/GameLogic/Spawning/Metadata/RocketMetadataProcessor.cs @@ -2,7 +2,6 @@ using System.Linq; using NitroxClient.Communication; using NitroxClient.Communication.Abstract; -using NitroxClient.Helpers; using NitroxClient.Unity.Helper; using NitroxModel.DataStructures.GameLogic.Entities.Metadata; using NitroxModel.Packets; diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs index fec52948eb..3d37a07339 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs @@ -18,6 +18,7 @@ public class EscapePodWorldEntitySpawner : IWorldEntitySpawner * EscapePod.main to the new escape pod. */ public static bool SURPRESS_ESCAPE_POD_AWAKE_METHOD; + private SimulationOwnership simulationOwnership; public EscapePodWorldEntitySpawner(SimulationOwnership simulationOwnership) @@ -57,16 +58,6 @@ private static GameObject CreateNewEscapePod(EscapePodWorldEntity escapePodEntit EntityMetadataProcessor.ApplyMetadata(escapePod, escapePodEntity.Metadata); - Rigidbody rigidbody = escapePod.GetComponent();/* - if (rigidbody != null) - { - rigidbody.constraints = RigidbodyConstraints.FreezeAll; - } - else - { - Log.Error("Escape pod did not have a rigid body!"); - } - */ escapePod.transform.position = escapePodEntity.Transform.Position.ToUnity(); FixStartMethods(escapePod); diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs index 5f4125633d..49c9a14c8b 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs @@ -14,19 +14,18 @@ namespace NitroxClient.GameLogic.Spawning.WorldEntities; public class VehicleWorldEntitySpawner : IWorldEntitySpawner { private readonly Entities entities; - - public VehicleWorldEntitySpawner(Entities entities) - { - this.entities = entities; - } + private readonly SimulationOwnership simulationOwnership; // The constructor has mixed results when the remote player is a long distance away. UWE even has a built in distance tracker to ensure // that they are within allowed range. However, this range is a bit restrictive. We will allow constructor spawning up to a specified // distance - anything more will simply use world spawning (no need to play the animation anyways). private const float ALLOWED_CONSTRUCTOR_DISTANCE = 100.0f; - private readonly SimulationOwnership simulationOwnership; - internal VehicleWorldEntitySpawner(SimulationOwnership simulationOwnership) + public VehicleWorldEntitySpawner(Entities entities) + { + this.entities = entities; + } + public VehicleWorldEntitySpawner(SimulationOwnership simulationOwnership) { this.simulationOwnership = simulationOwnership; } diff --git a/NitroxClient/Helpers/MovementHelper.cs b/NitroxClient/Helpers/MovementHelper.cs index ac54f81a9f..dd9a9e0821 100644 --- a/NitroxClient/Helpers/MovementHelper.cs +++ b/NitroxClient/Helpers/MovementHelper.cs @@ -69,7 +69,7 @@ public static Vector3 GetCorrectedAngularVelocity(Quaternion remoteRotation, Vec // Here I drop down to 0.9f times the desired movement, // since we'd rather undershoot and ease into the correct angle // than overshoot and oscillate around it in the event of errors. - return .9f * Mathf.Deg2Rad * angle / correctionTime * axis + angularVelocty; + return 0.9f * Mathf.Deg2Rad * angle / correctionTime * axis + angularVelocty; } } } diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MovementController.cs index cde6cb8156..a19bdd6c4b 100644 --- a/NitroxClient/MonoBehaviours/MovementController.cs +++ b/NitroxClient/MonoBehaviours/MovementController.cs @@ -4,12 +4,7 @@ using NitroxModel.DataStructures; using NitroxModel.Packets; using NitroxModel_Subnautica.DataStructures; -using Serilog.Events; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; namespace NitroxClient.MonoBehaviours diff --git a/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs b/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs index ea8f493e08..f5983d2009 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerExosuit.cs @@ -1,4 +1,3 @@ -using NitroxClient.Unity.Smoothing; using UnityEngine; namespace NitroxClient.MonoBehaviours diff --git a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs index 574d23e21c..0ad83a4ac9 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs @@ -1,5 +1,4 @@ using System; -using NitroxClient.GameLogic; using NitroxClient.Unity.Smoothing; using UnityEngine; @@ -30,7 +29,6 @@ protected virtual void FixedUpdate() SmoothYaw.FixedUpdate(); SmoothPitch.FixedUpdate(); - WheelYawSetter(SmoothYaw.SmoothValue); WheelPitchSetter(SmoothPitch.SmoothValue); } diff --git a/NitroxClient/MonoBehaviours/NitroxEntity.cs b/NitroxClient/MonoBehaviours/NitroxEntity.cs index 3b5f4accd3..5e12d60cda 100644 --- a/NitroxClient/MonoBehaviours/NitroxEntity.cs +++ b/NitroxClient/MonoBehaviours/NitroxEntity.cs @@ -16,6 +16,7 @@ namespace NitroxClient.MonoBehaviours public class NitroxEntity : MonoBehaviour, IProtoTreeEventListener { private static readonly Dictionary gameObjectsById = new(); + private static readonly Dictionary movementControllersById = new(); [DataMember(Order = 1)] [ProtoMember(1)] @@ -73,6 +74,32 @@ public static bool TryGetComponentFrom(NitroxId id, out T component) gameObject.TryGetComponent(out component); } + public static bool TryGetMovementControllerFrom(NitroxId id, out MovementController mc) + { + mc = null; + if (id == null) // Early Exit + { + return false; + } + + + if (!movementControllersById.TryGetValue(id, out mc)) + { + if (!TryGetObjectFrom(id, out GameObject gameObject)) + { + return false; + } + + if (gameObject.TryGetComponent(out mc) && mc) + { + movementControllersById.Add(id, mc); + return true; + } + } + + return mc; + } + public static void SetNewId(GameObject gameObject, NitroxId id) { Validate.IsTrue(gameObject); diff --git a/NitroxClient/MonoBehaviours/RemotelyControlled.cs b/NitroxClient/MonoBehaviours/RemotelyControlled.cs index 66fa9afb54..5e20020b57 100644 --- a/NitroxClient/MonoBehaviours/RemotelyControlled.cs +++ b/NitroxClient/MonoBehaviours/RemotelyControlled.cs @@ -1,4 +1,3 @@ -using NitroxClient.GameLogic; using NitroxClient.Unity.Smoothing; using UnityEngine; diff --git a/NitroxLauncher/Properties/AssemblyInfo.cs b/NitroxLauncher/Properties/AssemblyInfo.cs index 4a05c7d474..4f943deb82 100644 --- a/NitroxLauncher/Properties/AssemblyInfo.cs +++ b/NitroxLauncher/Properties/AssemblyInfo.cs @@ -2,9 +2,9 @@ [assembly: ThemeInfo( ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) + //(used if a resource is not found in the page, + // or application resource dictionaries) ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) )] \ No newline at end of file diff --git a/NitroxModel-Subnautica/Packets/ExosuitArmActionPacket.cs b/NitroxModel-Subnautica/Packets/ExosuitArmActionPacket.cs index b2e9a6bb62..bb7dbf1996 100644 --- a/NitroxModel-Subnautica/Packets/ExosuitArmActionPacket.cs +++ b/NitroxModel-Subnautica/Packets/ExosuitArmActionPacket.cs @@ -2,7 +2,6 @@ using NitroxModel.DataStructures; using NitroxModel.DataStructures.Unity; using NitroxModel.Packets; -using UnityEngine; namespace NitroxModel_Subnautica.Packets { diff --git a/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs b/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs index 161092be16..98fb6f5c39 100644 --- a/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs +++ b/NitroxModel/DataStructures/GameLogic/VehicleMovementData.cs @@ -21,19 +21,19 @@ public abstract class VehicleMovementData [DataMember(Order = 4)] public NitroxQuaternion Rotation { get; } - [DataMember(Order = 7)] + [DataMember(Order = 5)] public float SteeringWheelYaw { get; } - [DataMember(Order = 8)] + [DataMember(Order = 6)] public float SteeringWheelPitch { get; } - [DataMember(Order = 9)] + [DataMember(Order = 7)] public bool AppliedThrottle { get; } - [DataMember(Order = 10)] + [DataMember(Order = 8)] public NitroxVector3 DriverPosition { get; set; } - [DataMember(Order = 11)] + [DataMember(Order = 9)] public NitroxQuaternion DriverRotation { get; set; } [IgnoreConstructor] diff --git a/NitroxModel/Packets/BasicMovementPacket.cs b/NitroxModel/Packets/BasicMovementPacket.cs index 2c5611eb94..6ab9ea303e 100644 --- a/NitroxModel/Packets/BasicMovementPacket.cs +++ b/NitroxModel/Packets/BasicMovementPacket.cs @@ -1,29 +1,23 @@ -using NitroxModel.DataStructures.Unity; using NitroxModel.DataStructures; +using NitroxModel.DataStructures.Unity; using NitroxModel.Networking; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static NitroxModel.Packets.Packet; -namespace NitroxModel.Packets +namespace NitroxModel.Packets; + +[Serializable] +public class BasicMovement : Movement { - [Serializable] - public class BasicMovement : Movement - { - public override NitroxId Id { get; } - public override NitroxVector3 Position { get; } - public override NitroxQuaternion Rotation { get; } + public override NitroxId Id { get; } + public override NitroxVector3 Position { get; } + public override NitroxQuaternion Rotation { get; } - public BasicMovement(NitroxId id, NitroxVector3 position, NitroxQuaternion rotation) - { - Id = id; - Position = position; - Rotation = rotation; - DeliveryMethod = NitroxDeliveryMethod.DeliveryMethod.UNRELIABLE_SEQUENCED; - UdpChannel = UdpChannelId.MISC_MOVEMENT; - } + public BasicMovement(NitroxId id, NitroxVector3 position, NitroxQuaternion rotation) + { + Id = id; + Position = position; + Rotation = rotation; + DeliveryMethod = NitroxDeliveryMethod.DeliveryMethod.UNRELIABLE_SEQUENCED; + UdpChannel = UdpChannelId.MISC_MOVEMENT; } } diff --git a/NitroxModel/Packets/Movement.cs b/NitroxModel/Packets/Movement.cs index 7fef304003..a0796eaa4f 100644 --- a/NitroxModel/Packets/Movement.cs +++ b/NitroxModel/Packets/Movement.cs @@ -1,7 +1,6 @@ using System; using NitroxModel.DataStructures; using NitroxModel.DataStructures.Unity; -using NitroxModel.Networking; namespace NitroxModel.Packets; diff --git a/NitroxModel/Platforms/OS/Windows/WinFileSystem.cs b/NitroxModel/Platforms/OS/Windows/WinFileSystem.cs index 6c4d23ae23..432b201040 100644 --- a/NitroxModel/Platforms/OS/Windows/WinFileSystem.cs +++ b/NitroxModel/Platforms/OS/Windows/WinFileSystem.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; using Microsoft.Win32; diff --git a/NitroxPatcher/Main.cs b/NitroxPatcher/Main.cs index 377b07d860..16a34e87c6 100644 --- a/NitroxPatcher/Main.cs +++ b/NitroxPatcher/Main.cs @@ -1,5 +1,4 @@ extern alias JB; -global using static NitroxModel.Extensions; global using NitroxModel.Logger; global using static NitroxClient.Helpers.NitroxEntityExtensions; using System; diff --git a/NitroxPatcher/Patches/Dynamic/Bed_EnterInUseMode_Patch.cs b/NitroxPatcher/Patches/Dynamic/Bed_EnterInUseMode_Patch.cs index feb61a1ada..95a1aa2557 100644 --- a/NitroxPatcher/Patches/Dynamic/Bed_EnterInUseMode_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Bed_EnterInUseMode_Patch.cs @@ -1,6 +1,5 @@ using System.Reflection; using NitroxClient.Communication.Abstract; -using NitroxModel.Core; using NitroxModel.Helper; using NitroxModel.Packets; diff --git a/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs b/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs index c22dc75eec..ed574f1e8c 100644 --- a/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs @@ -25,7 +25,7 @@ public static void Prefix(FMOD_CustomEmitter __instance) return; } - if (!__instance.transform.TryGetComponentInAscendance(10, out NitroxEntity entity)) + if (!__instance.transform.TryGetComponentInParent(out NitroxEntity entity)) { Log.Warn($"[FMOD_CustomEmitter_Start_Patch] - No NitroxEntity for \"{__instance.asset.path}\" found!"); return; diff --git a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs index 6c58e6d3fe..6826b3ffd0 100644 --- a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs @@ -1,56 +1,53 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; using HarmonyLib; -using NitroxClient.GameLogic; using NitroxClient.MonoBehaviours; using NitroxModel.Helper; using UnityEngine; -namespace NitroxPatcher.Patches.Dynamic +namespace NitroxPatcher.Patches.Dynamic; + +public sealed partial class FreezeRigidbodyWhenFar_FixedUpdate_Patch : NitroxPatch, IDynamicPatch { - public sealed partial class FreezeRigidbodyWhenFar_FixedUpdate_Patch : NitroxPatch, IDynamicPatch - { - public static readonly MethodInfo TARGET_METHOD = Reflect.Method((FreezeRigidbodyWhenFar t) => t.FixedUpdate()); + public static readonly MethodInfo TARGET_METHOD = Reflect.Method((FreezeRigidbodyWhenFar t) => t.FixedUpdate()); - public static IEnumerable Transpiler(MethodBase original, IEnumerable instructions, ILGenerator generator) + public static IEnumerable Transpiler(MethodBase original, IEnumerable instructions, ILGenerator generator) + { + List instructionList = instructions.ToList(); + for (int i = 0; i < instructionList.Count; i++) { - List instructionList = instructions.ToList(); - for (int i = 0; i < instructionList.Count; i++) + CodeInstruction instruction = instructionList[i]; + + if (instruction.opcode == OpCodes.Call && instruction.operand.Equals(Reflect.Method((Component c) => c.GetComponent()))) { - CodeInstruction instruction = instructionList[i]; + yield return instruction; + yield return instructionList[i + 1]; + object jmpLabel = null; - if (instruction.opcode == OpCodes.Call && instruction.operand.Equals(Reflect.Method((Component c) => c.GetComponent()))) + for (int j = i; j < instructionList.Count; j++) // search for branch instruction { - yield return instruction; - yield return instructionList[i+1]; - object jmpLabel = null; - - for (int j = i; j < instructionList.Count; j++) // search for branch instruction + if (instructionList[j].opcode == OpCodes.Ble_Un) { - if (instructionList[j].opcode == OpCodes.Ble_Un) - { - jmpLabel = instructionList[j].operand; - break; - } + jmpLabel = instructionList[j].operand; + break; } - yield return new CodeInstruction(OpCodes.Ldarg_0); - yield return new CodeInstruction(OpCodes.Call, Reflect.Property((Component c) => c.gameObject).GetGetMethod()); - yield return new CodeInstruction(OpCodes.Call, Reflect.Method(() => IsMoving(default))); - yield return new CodeInstruction(OpCodes.Brtrue, jmpLabel); - i = i + 1; - continue; } - - yield return instruction; + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Call, Reflect.Property((Component c) => c.gameObject).GetGetMethod()); + yield return new CodeInstruction(OpCodes.Call, Reflect.Method(() => IsMoving(default))); + yield return new CodeInstruction(OpCodes.Brtrue, jmpLabel); + i = i + 1; + continue; } - } - public static bool IsMoving(GameObject go) - { - return go.TryGetComponent(out MovementController mc) && mc.Receiving; + yield return instruction; } } + + public static bool IsMoving(GameObject go) + { + return go.TryGetComponent(out MovementController mc) && mc.Receiving; + } } diff --git a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs index 5fbd3d6dfe..e53e5f1a26 100644 --- a/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/SubRoot_OnPlayerExited_Patch.cs @@ -1,8 +1,4 @@ -using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Reflection.Emit; -using HarmonyLib; using NitroxModel.Helper; namespace NitroxPatcher.Patches.Dynamic; diff --git a/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs b/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs index 5c758d9256..0575d31e31 100644 --- a/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs @@ -1,4 +1,3 @@ -using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.GameLogic.Entities; using NitroxModel.DataStructures.Util; using NitroxModel.Packets; diff --git a/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs b/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs index b11642dabd..98e46c5ff9 100644 --- a/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/PlayerMovementProcessor.cs @@ -1,4 +1,3 @@ -using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.GameLogic.Entities; using NitroxModel.DataStructures.Util; using NitroxModel.Packets; diff --git a/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs b/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs index c222de6866..432170e349 100644 --- a/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/VehicleMovementPacketProcessor.cs @@ -32,7 +32,7 @@ public override void Process(VehicleMovement packet, Player player) if (player.GameObjectId == packet.Id) { player.Position = packet.VehicleMovementData.DriverPosition; - player.Rotation = packet.VehicleMovementData.DriverRotation; ; + player.Rotation = packet.VehicleMovementData.DriverRotation; } playerManager.SendPacketToOtherPlayers(packet, player); diff --git a/NitroxServer/GameLogic/Entities/Spawning/IEntityBootstrapper.cs b/NitroxServer/GameLogic/Entities/Spawning/IEntityBootstrapper.cs index f85c11daa5..b6a4c1c168 100644 --- a/NitroxServer/GameLogic/Entities/Spawning/IEntityBootstrapper.cs +++ b/NitroxServer/GameLogic/Entities/Spawning/IEntityBootstrapper.cs @@ -1,5 +1,5 @@ -using NitroxServer.Helper; -using NitroxModel.DataStructures.GameLogic.Entities; +using NitroxServer.Helper; +using NitroxModel.DataStructures.GameLogic.Entities; namespace NitroxServer.GameLogic.Entities.Spawning { diff --git a/NitroxServer/Properties/AssemblyInfo.cs b/NitroxServer/Properties/AssemblyInfo.cs index 90f58e7710..a7288d193b 100644 --- a/NitroxServer/Properties/AssemblyInfo.cs +++ b/NitroxServer/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/NitroxServer/Serialization/BatchCellsParser.cs b/NitroxServer/Serialization/BatchCellsParser.cs index 800b3233b0..8377f2368b 100644 --- a/NitroxServer/Serialization/BatchCellsParser.cs +++ b/NitroxServer/Serialization/BatchCellsParser.cs @@ -6,7 +6,6 @@ using NitroxModel.DataStructures; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.Unity; -using NitroxModel.Discovery; using NitroxModel.Helper; using NitroxServer.GameLogic.Entities.Spawning; using NitroxServer.UnityStubs; From 696dd1caaccf39f5e7a174abd07cb08d3a945043 Mon Sep 17 00:00:00 2001 From: killzoms Date: Wed, 22 Nov 2023 23:18:26 -0500 Subject: [PATCH 12/19] Minor Refactoring in MovementController --- NitroxClient/Helpers/MovementHelper.cs | 6 +- .../MonoBehaviours/MovementController.cs | 220 +++++++++--------- .../MonoBehaviours/RemotelyControlled.cs | 2 +- 3 files changed, 110 insertions(+), 118 deletions(-) diff --git a/NitroxClient/Helpers/MovementHelper.cs b/NitroxClient/Helpers/MovementHelper.cs index dd9a9e0821..2de968103d 100644 --- a/NitroxClient/Helpers/MovementHelper.cs +++ b/NitroxClient/Helpers/MovementHelper.cs @@ -49,7 +49,7 @@ public static Vector3 GetCorrectedVelocity(Vector3 remotePosition, Vector3 remot return remoteVelocity; } - public static Vector3 GetCorrectedAngularVelocity(Quaternion remoteRotation, Vector3 angularVelocty, GameObject gameObject, float correctionTime) + public static Vector3 GetCorrectedAngularVelocity(Quaternion remoteRotation, GameObject gameObject, float correctionTime) { Quaternion delta = remoteRotation * gameObject.transform.rotation.GetInverse(); @@ -58,7 +58,7 @@ public static Vector3 GetCorrectedAngularVelocity(Quaternion remoteRotation, Vec // We get an infinite axis in the event that our rotation is already aligned. if (float.IsInfinity(axis.x)) { - return angularVelocty; + return Vector3.zero; } if (angle > 180f) @@ -69,7 +69,7 @@ public static Vector3 GetCorrectedAngularVelocity(Quaternion remoteRotation, Vec // Here I drop down to 0.9f times the desired movement, // since we'd rather undershoot and ease into the correct angle // than overshoot and oscillate around it in the event of errors. - return 0.9f * Mathf.Deg2Rad * angle / correctionTime * axis + angularVelocty; + return 0.9f * Mathf.Deg2Rad * angle / correctionTime * axis; } } } diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MovementController.cs index a19bdd6c4b..d6d4e47adc 100644 --- a/NitroxClient/MonoBehaviours/MovementController.cs +++ b/NitroxClient/MonoBehaviours/MovementController.cs @@ -7,160 +7,152 @@ using System; using UnityEngine; -namespace NitroxClient.MonoBehaviours +namespace NitroxClient.MonoBehaviours; + +public class MovementController : MonoBehaviour { - public class MovementController : MonoBehaviour + public const float LOCATION_BROADCAST_TIME = 0.04f; + + public float Scalar { get; set; } = 1f; + public Vector3 TargetPosition { get; set; } + public Quaternion TargetRotation { get; set; } + public bool Receiving { get; private set; } + public bool Broadcasting { get; private set; } + public Vector3 Velocity { - public const float LOCATION_BROADCAST_TIME = 0.04f; - public float Scalar { get; set; } = 1f; - public Vector3 TargetPosition { get; set; } - public Quaternion TargetRotation { get; set; } - public bool Receiving { get; private set; } - public bool Broadcasting { get; private set; } - public Vector3 Velocity + get { - get - { - return velocity; - } + return velocity; } + } - public event Action BeforeUpdate = () => {}; - public event Action BeforeFixedUpdate = () => {}; - public event Action AfterUpdate = () => {}; - public event Action AfterFixedUpdate = () => {}; + public event Action BeforeUpdate = () => {}; + public event Action BeforeFixedUpdate = () => {}; + public event Action AfterUpdate = () => {}; + public event Action AfterFixedUpdate = () => {}; - private Vector3 velocity; - private float curTime; - private Rigidbody rigidbody; - private IPacketSender packetSender; - private SimulationOwnership simulationOwnership; - private NitroxEntity entity; - private static bool runOnce; + private Vector3 velocity; + private float curTime; + private Rigidbody rigidbody; + private IPacketSender packetSender; + private SimulationOwnership simulationOwnership; + private NitroxEntity entity; - public void SetBroadcasting(bool broadcasting) + public void SetBroadcasting(bool broadcasting) + { + Broadcasting = broadcasting; + if (Receiving && broadcasting) { - Broadcasting = broadcasting; - if (Receiving && broadcasting) - { - Receiving = !broadcasting; - } + Receiving = !broadcasting; } + } - public void SetReceiving(bool receiving) + public void SetReceiving(bool receiving) + { + Receiving = receiving; + if (Broadcasting && receiving) { - Receiving = receiving; - if (Broadcasting && receiving) - { - Broadcasting = !receiving; - } + Broadcasting = !receiving; } + } - private static void StartedSimulatingEntity(NitroxId id) + private static void StartedSimulatingEntity(NitroxId id) + { + if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) { - if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) + if (gameObject.TryGetComponent(out MovementController mc)) { - if (gameObject.TryGetComponent(out MovementController mc)) - { - mc.SetBroadcasting(true); - } + mc.SetBroadcasting(true); } } + } - private static void StoppedSimulatingEntity(NitroxId id) + private static void StoppedSimulatingEntity(NitroxId id) + { + if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) { - if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) + if (gameObject.TryGetComponent(out MovementController mc)) { - if (gameObject.TryGetComponent(out MovementController mc)) - { - mc.SetReceiving(true); - } + mc.SetReceiving(true); } } + } - private void Awake() + private void Awake() + { + packetSender = NitroxServiceLocator.LocateService(); + simulationOwnership = NitroxServiceLocator.LocateService(); + } + + private void Start() + { + rigidbody = GetComponent(); + if (!TryGetComponent(out NitroxEntity nitroxEntity)) { - packetSender = NitroxServiceLocator.LocateService(); - simulationOwnership = NitroxServiceLocator.LocateService(); - if (!runOnce) - { - runOnce = true; - simulationOwnership.StartedSimulatingEntity += StartedSimulatingEntity; - simulationOwnership.StoppedSimulatingEntity += StoppedSimulatingEntity; - } + NitroxEntity.GenerateNewId(gameObject); + + nitroxEntity = GetComponent(); } + entity = nitroxEntity; + } - private void Start() - { - rigidbody = GetComponent(); - if (!TryGetComponent(out NitroxEntity nitroxEntity)) - { - NitroxEntity.GenerateNewId(gameObject); + private void Update() + { + BeforeUpdate(); - nitroxEntity = GetComponent(); - } - entity = nitroxEntity; + if (!rigidbody && Receiving) + { + transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, Scalar * Time.deltaTime); + transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, Scalar * Time.deltaTime); } - private void Update() + AfterUpdate(); + } + + private void FixedUpdate() + { + BeforeFixedUpdate(); + + if (Broadcasting && simulationOwnership.HasAnyLockType(entity.Id)) { - BeforeUpdate(); - if (!rigidbody && Receiving) + curTime += Time.fixedDeltaTime; + if (curTime >= LOCATION_BROADCAST_TIME) { - transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, Scalar * Time.deltaTime); - transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, Scalar * Time.deltaTime); + curTime = 0f; + + packetSender.Send(new BasicMovement(entity.Id, transform.position.ToDto(), transform.rotation.ToDto())); } - AfterUpdate(); } - private void FixedUpdate() + if (rigidbody && Receiving) { - BeforeFixedUpdate(); + float timing = Scalar * Time.fixedDeltaTime; + Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, timing); - if (Broadcasting && simulationOwnership.HasAnyLockType(entity.Id)) + if (rigidbody.isKinematic) { - curTime += Time.fixedDeltaTime; - if (curTime >= LOCATION_BROADCAST_TIME) - { - curTime = 0f; - - packetSender.Send(new BasicMovement(entity.Id, transform.position.ToDto(), transform.rotation.ToDto())); - } + rigidbody.MovePosition(newPos); + rigidbody.MoveRotation(TargetRotation); } - - if (rigidbody && Receiving) + else { - float timing = Scalar * Time.fixedDeltaTime; - Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, timing); - - if (rigidbody.isKinematic) - { - rigidbody.MovePosition(newPos); - rigidbody.MoveRotation(TargetRotation); - } - else - { - rigidbody.velocity = velocity; - - Quaternion delta = TargetRotation * transform.rotation.GetInverse(); - delta.ToAngleAxis(out float angle, out Vector3 axis); - - if (!float.IsInfinity(axis.x) && !float.IsInfinity(axis.y) && !float.IsInfinity(axis.z)) - { - if (angle > 180f) - { - angle -= 360f; - } - - rigidbody.angularVelocity = .9f * Mathf.Deg2Rad * angle / timing * axis; - } - else - { - rigidbody.angularVelocity = Vector3.zero; - } - } + rigidbody.velocity = velocity; + rigidbody.angularVelocity = MovementHelper.GetCorrectedAngularVelocity(TargetRotation, gameObject, timing); } - AfterFixedUpdate(); } + + AfterFixedUpdate(); + } + + private void OnEnable() + { + simulationOwnership.StartedSimulatingEntity += StartedSimulatingEntity; + simulationOwnership.StoppedSimulatingEntity -= StoppedSimulatingEntity; + } + + private void OnDisable() + { + simulationOwnership.StartedSimulatingEntity -= StartedSimulatingEntity; + simulationOwnership.StoppedSimulatingEntity -= StoppedSimulatingEntity; } } diff --git a/NitroxClient/MonoBehaviours/RemotelyControlled.cs b/NitroxClient/MonoBehaviours/RemotelyControlled.cs index 5e20020b57..8073ae8d79 100644 --- a/NitroxClient/MonoBehaviours/RemotelyControlled.cs +++ b/NitroxClient/MonoBehaviours/RemotelyControlled.cs @@ -31,7 +31,7 @@ public void FixedUpdate() rigidbody.isKinematic = false; rigidbody.velocity = MovementHelper.GetCorrectedVelocity(smoothPosition.Current, Vector3.zero, gameObject, EntityPositionBroadcaster.BROADCAST_INTERVAL); - rigidbody.angularVelocity = MovementHelper.GetCorrectedAngularVelocity(smoothRotation.Current, Vector3.zero, gameObject, EntityPositionBroadcaster.BROADCAST_INTERVAL); + rigidbody.angularVelocity = MovementHelper.GetCorrectedAngularVelocity(smoothRotation.Current, gameObject, EntityPositionBroadcaster.BROADCAST_INTERVAL); } public void UpdateOrientation(Vector3 position, Quaternion rotation) From a3227432a5eb1f53389f50c0f49d587c5504fc7d Mon Sep 17 00:00:00 2001 From: killzoms Date: Thu, 23 Nov 2023 10:27:20 -0500 Subject: [PATCH 13/19] most Requested changes --- .../DeferredPacketReceiverTest.cs | 7 +- .../ConnectionState/DisconnectedStateTests.cs | 12 +-- .../Packets/Processors/PacketProcessorTest.cs | 3 + NitroxClient/ClientAutoFacRegistrar.cs | 12 +-- .../Processors/BasicMovementProcessor.cs | 2 +- .../PlayerPositionInitialSyncProcessor.cs | 7 +- NitroxClient/GameLogic/LocalPlayer.cs | 49 ++++++------ NitroxClient/GameLogic/SimulationOwnership.cs | 1 - .../Spawning/Bases/BuildEntitySpawner.cs | 2 +- .../VehicleWorldEntitySpawner.cs | 9 ++- .../MonoBehaviours/MovementController.cs | 80 ++++++++++++------- NitroxClient/MonoBehaviours/NitroxEntity.cs | 27 ------- .../PlayerMovementBroadcaster.cs | 14 ++-- NitroxModel/Packets/BasicMovementPacket.cs | 2 +- NitroxPatcher/Main.cs | 4 + .../Dynamic/FMOD_CustomEmitter_Start_Patch.cs | 2 +- .../BasicMovementPacketProcessor.cs | 36 ++++----- .../GameLogic/Entities/EntityRegistry.cs | 4 +- 18 files changed, 136 insertions(+), 137 deletions(-) diff --git a/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs b/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs index 85db11f35f..4182c706a0 100644 --- a/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs +++ b/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs @@ -1,6 +1,7 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using Nitrox.Test.Client.Communication; using NitroxClient.Map; +using NitroxModel.Core; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.Unity; using NitroxModel.Packets; @@ -23,6 +24,10 @@ public class DeferredPacketReceiverTest public void TestInitialize() { packetReceiver = new PacketReceiver(); + ClientAutoFacRegistrar registrar = new ClientAutoFacRegistrar(); + NitroxServiceLocator.InitializeDependencyContainer(registrar); + NitroxServiceLocator.BeginNewLifetimeScope(); + loadedCell = new AbsoluteEntityCell(loadedActionPosition, CELL_LEVEL); visibleCells.Add(loadedCell); } diff --git a/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs b/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs index 66a055832b..854913df05 100644 --- a/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs +++ b/Nitrox.Test/Client/Communication/MultiplayerSession/ConnectionState/DisconnectedStateTests.cs @@ -13,7 +13,7 @@ namespace NitroxClient.Communication.MultiplayerSession.ConnectionState public class DisconnectedStateTests { [TestMethod] - public void NegotiateShouldStartTheClientOnTheContext() + public async Task NegotiateShouldStartTheClientOnTheContext() { // Arrange IClient serverClient = Substitute.For(); @@ -29,14 +29,14 @@ public void NegotiateShouldStartTheClientOnTheContext() Disconnected connectionState = new Disconnected(); // Act - connectionState.NegotiateReservationAsync(connectionContext).RunSynchronously(); + await connectionState.NegotiateReservationAsync(connectionContext); // Assert serverClient.IsConnected.Should().BeTrue(); } [TestMethod] - public void NegotiateShouldSendMultiplayerSessionPolicyRequestPacketToClient() + public async Task NegotiateShouldSendMultiplayerSessionPolicyRequestPacketToClient() { // Arrange IClient serverClient = Substitute.For(); @@ -52,14 +52,14 @@ public void NegotiateShouldSendMultiplayerSessionPolicyRequestPacketToClient() Disconnected connectionState = new Disconnected(); // Act - connectionState.NegotiateReservationAsync(connectionContext).RunSynchronously(); + await connectionState.NegotiateReservationAsync(connectionContext); // Assert serverClient.Received().Send(Arg.Any()); } [TestMethod] - public void NegotiateShouldTransitionToEstablishingSessionPolicyState() + public async Task NegotiateShouldTransitionToEstablishingSessionPolicyState() { // Arrange IClient serverClient = Substitute.For(); @@ -75,7 +75,7 @@ public void NegotiateShouldTransitionToEstablishingSessionPolicyState() Disconnected connectionState = new Disconnected(); // Act - connectionState.NegotiateReservationAsync(connectionContext).RunSynchronously(); + await connectionState.NegotiateReservationAsync(connectionContext); // Assert connectionContext.Received().UpdateConnectionState(Arg.Any()); diff --git a/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs b/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs index 773e6d9b2c..175e2cc68a 100644 --- a/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs +++ b/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs @@ -85,6 +85,9 @@ public void AllPacketsAreHandled() List packetTypes = typeof(DefaultServerPacketProcessor).Assembly.GetTypes() .Where(p => typeof(PacketProcessor).IsAssignableFrom(p) && p.IsClass && !p.IsAbstract) .ToList(); + ServerAutoFacRegistrar serverDependencyRegistrar = new ServerAutoFacRegistrar(); + NitroxServiceLocator.InitializeDependencyContainer(serverDependencyRegistrar); + NitroxServiceLocator.BeginNewLifetimeScope(); List abstractProcessorTypes = new(); diff --git a/NitroxClient/ClientAutoFacRegistrar.cs b/NitroxClient/ClientAutoFacRegistrar.cs index 9355fb24a2..d6113aa4d2 100644 --- a/NitroxClient/ClientAutoFacRegistrar.cs +++ b/NitroxClient/ClientAutoFacRegistrar.cs @@ -56,20 +56,20 @@ private static void RegisterCoreDependencies(ContainerBuilder containerBuilder) { #if DEBUG containerBuilder.RegisterAssemblyTypes(currentAssembly) - .AssignableTo() - .As() + .AssignableTo() + .As() .AsImplementedInterfaces() .AsSelf() .SingleInstance(); containerBuilder.RegisterAssemblyTypes(currentAssembly) - .AssignableTo() - .As() + .AssignableTo() + .As() .SingleInstance(); containerBuilder.RegisterAssemblyTypes(currentAssembly) - .AssignableTo() - .As() + .AssignableTo() + .As() .SingleInstance(); #endif containerBuilder.Register(c => new NitroxProtobufSerializer($"{nameof(NitroxModel)}.dll")); diff --git a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs index 1fe87984d1..cda5a5260d 100644 --- a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs @@ -10,7 +10,7 @@ public class BasicMovementProcessor : ClientPacketProcessor { public override void Process(BasicMovement movement) { - if (!NitroxEntity.TryGetMovementControllerFrom(movement.Id, out MovementController mc) && NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) + if (!MovementController.TryGetMovementControllerFrom(movement.Id, out MovementController mc) && NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) { mc = gameObject.EnsureComponent(); } diff --git a/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs b/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs index 2ad4414060..1034dbceb6 100644 --- a/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs +++ b/NitroxClient/GameLogic/InitialSync/PlayerPositionInitialSyncProcessor.cs @@ -78,9 +78,9 @@ public override IEnumerator Process(InitialPlayerSync packet, WaitScreen.ManualW yield break; } - Player.main.cinematicModeActive = false; - Player.main.UpdateIsUnderwater(); - } + Player.main.cinematicModeActive = false; + Player.main.UpdateIsUnderwater(); + } private void AttachPlayerToEscapePod(NitroxId escapePodId) { @@ -94,5 +94,4 @@ private void AttachPlayerToEscapePod(NitroxId escapePodId) Player.main.currentEscapePod = escapePod.GetComponent(); } - } diff --git a/NitroxClient/GameLogic/LocalPlayer.cs b/NitroxClient/GameLogic/LocalPlayer.cs index e320dae6a2..8db6aafc0f 100644 --- a/NitroxClient/GameLogic/LocalPlayer.cs +++ b/NitroxClient/GameLogic/LocalPlayer.cs @@ -24,7 +24,7 @@ public class LocalPlayer : ILocalNitroxPlayer private readonly Lazy body; private readonly Lazy playerModel; private readonly Lazy bodyPrototype; - private readonly NitroxEntity entity; + private readonly Lazy entity; public GameObject Body => body.Value; @@ -38,34 +38,31 @@ public class LocalPlayer : ILocalNitroxPlayer public Perms Permissions; - public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetSender, ThrottledPacketSender throttledPacketSender) + public LocalPlayer(IMultiplayerSession multiplayerSession, IPacketSender packetSender, ThrottledPacketSender throttledPacketSender) + { + this.multiplayerSession = multiplayerSession; + this.packetSender = packetSender; + this.throttledPacketSender = throttledPacketSender; + + body = new Lazy(() => Player.main.RequireGameObject("body")); + playerModel = new Lazy(() => Body.RequireGameObject("player_view")); + bodyPrototype = new Lazy(CreateBodyPrototype); + Permissions = Perms.PLAYER; + + entity = new Lazy(() => Player.mainObject.EnsureComponent()); + } + + public void BroadcastLocation(Vector3 location, Quaternion bodyRotation, Quaternion aimingRotation, Optional vehicle) + { + Movement movement; + if (vehicle.HasValue) { - this.multiplayerSession = multiplayerSession; - this.packetSender = packetSender; - this.throttledPacketSender = throttledPacketSender; - body = new Lazy(() => Player.main.RequireGameObject("body")); - playerModel = new Lazy(() => Body.RequireGameObject("player_view")); - bodyPrototype = new Lazy(CreateBodyPrototype); - Permissions = Perms.PLAYER; - - if (!Player.mainObject.TryGetComponent(out NitroxEntity nitroxEntity)) - { - nitroxEntity = Player.mainObject.AddComponent(); - } - entity = nitroxEntity; + movement = new VehicleMovement(entity.Value.Id, vehicle.Value); } - - public void BroadcastLocation(Vector3 location, Quaternion bodyRotation, Quaternion aimingRotation, Optional vehicle) + else { - Movement movement; - if (vehicle.HasValue) - { - movement = new VehicleMovement(entity.Id, vehicle.Value); - } - else - { - movement = new PlayerMovement(entity.Id, location.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto()); - } + movement = new PlayerMovement(entity.Value.Id, location.ToDto(), bodyRotation.ToDto(), aimingRotation.ToDto()); + } packetSender.Send(movement); } diff --git a/NitroxClient/GameLogic/SimulationOwnership.cs b/NitroxClient/GameLogic/SimulationOwnership.cs index 391d08ecf4..86643f03e1 100644 --- a/NitroxClient/GameLogic/SimulationOwnership.cs +++ b/NitroxClient/GameLogic/SimulationOwnership.cs @@ -78,7 +78,6 @@ public void SimulateEntity(NitroxId id, SimulationLockType lockType) public void StopSimulatingEntity(NitroxId id) { simulatedIdsByLockType.Remove(id); - StoppedSimulatingEntity?.Invoke(id); } } diff --git a/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs index 2bf12b13fb..5787f64272 100644 --- a/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/Bases/BuildEntitySpawner.cs @@ -34,7 +34,7 @@ protected override IEnumerator SpawnAsync(BuildEntity entity, TaskResult(); - + foreach (VFXConstructing vfxConstructing in vfxConstructions) { vfxConstructing.EndGracefully(); @@ -198,19 +199,19 @@ private void DockVehicle(GameObject gameObject, GameObject parent) return; } - dockingBay.DockVehicle(vehicle); + dockingBay.DockVehicle(vehicle); } public bool SpawnsOwnChildren() { return false; } - + private float GetCraftDuration(TechType techType) { // UWE hard codes the build times into if/else logic inside ConstructorInput.Craft(). - switch(techType) + switch (techType) { case TechType.Seamoth: return 10f; diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MovementController.cs index d6d4e47adc..2c59abbf72 100644 --- a/NitroxClient/MonoBehaviours/MovementController.cs +++ b/NitroxClient/MonoBehaviours/MovementController.cs @@ -1,10 +1,11 @@ +using System; +using System.Collections.Generic; using NitroxClient.Communication.Abstract; using NitroxClient.GameLogic; using NitroxModel.Core; using NitroxModel.DataStructures; using NitroxModel.Packets; using NitroxModel_Subnautica.DataStructures; -using System; using UnityEngine; namespace NitroxClient.MonoBehaviours; @@ -13,26 +14,21 @@ public class MovementController : MonoBehaviour { public const float LOCATION_BROADCAST_TIME = 0.04f; - public float Scalar { get; set; } = 1f; + private static readonly Dictionary movementControllersById = new(); + + public float TimeScalar { get; set; } = 1f; public Vector3 TargetPosition { get; set; } public Quaternion TargetRotation { get; set; } public bool Receiving { get; private set; } public bool Broadcasting { get; private set; } - public Vector3 Velocity - { - get - { - return velocity; - } - } + public Vector3 Velocity { get; private set; } - public event Action BeforeUpdate = () => {}; - public event Action BeforeFixedUpdate = () => {}; - public event Action AfterUpdate = () => {}; - public event Action AfterFixedUpdate = () => {}; + public event Action BeforeUpdate = () => { }; + public event Action BeforeFixedUpdate = () => { }; + public event Action AfterUpdate = () => { }; + public event Action AfterFixedUpdate = () => { }; - private Vector3 velocity; - private float curTime; + private float timeSinceLastBroadcast; private Rigidbody rigidbody; private IPacketSender packetSender; private SimulationOwnership simulationOwnership; @@ -56,25 +52,45 @@ public void SetReceiving(bool receiving) } } - private static void StartedSimulatingEntity(NitroxId id) + public static bool TryGetMovementControllerFrom(NitroxId id, out MovementController mc) { - if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) + mc = null; + if (id == null) // Early Exit + { + return false; + } + + + if (!movementControllersById.TryGetValue(id, out mc)) { - if (gameObject.TryGetComponent(out MovementController mc)) + if (!NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) { - mc.SetBroadcasting(true); + return false; } + + if (gameObject.TryGetComponent(out mc) && mc) + { + movementControllersById.Add(id, mc); + return true; + } + } + + return mc; + } + + private static void StartedSimulatingEntity(NitroxId id) + { + if (NitroxEntity.TryGetComponentFrom(id, out MovementController mc)) + { + mc.SetBroadcasting(true); } } private static void StoppedSimulatingEntity(NitroxId id) { - if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) + if (NitroxEntity.TryGetComponentFrom(id, out MovementController mc)) { - if (gameObject.TryGetComponent(out MovementController mc)) - { - mc.SetReceiving(true); - } + mc.SetReceiving(true); } } @@ -102,8 +118,9 @@ private void Update() if (!rigidbody && Receiving) { - transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, Scalar * Time.deltaTime); - transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, Scalar * Time.deltaTime); + Vector3 velocity = Velocity; + transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, TimeScalar * Time.deltaTime); + transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, TimeScalar * Time.deltaTime); } AfterUpdate(); @@ -115,10 +132,10 @@ private void FixedUpdate() if (Broadcasting && simulationOwnership.HasAnyLockType(entity.Id)) { - curTime += Time.fixedDeltaTime; - if (curTime >= LOCATION_BROADCAST_TIME) + timeSinceLastBroadcast += Time.fixedDeltaTime; + if (timeSinceLastBroadcast >= LOCATION_BROADCAST_TIME) { - curTime = 0f; + timeSinceLastBroadcast = 0f; packetSender.Send(new BasicMovement(entity.Id, transform.position.ToDto(), transform.rotation.ToDto())); } @@ -126,7 +143,8 @@ private void FixedUpdate() if (rigidbody && Receiving) { - float timing = Scalar * Time.fixedDeltaTime; + Vector3 velocity = Velocity; + float timing = TimeScalar * Time.fixedDeltaTime; Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, timing); if (rigidbody.isKinematic) @@ -147,7 +165,7 @@ private void FixedUpdate() private void OnEnable() { simulationOwnership.StartedSimulatingEntity += StartedSimulatingEntity; - simulationOwnership.StoppedSimulatingEntity -= StoppedSimulatingEntity; + simulationOwnership.StoppedSimulatingEntity += StoppedSimulatingEntity; } private void OnDisable() diff --git a/NitroxClient/MonoBehaviours/NitroxEntity.cs b/NitroxClient/MonoBehaviours/NitroxEntity.cs index 5e12d60cda..3b5f4accd3 100644 --- a/NitroxClient/MonoBehaviours/NitroxEntity.cs +++ b/NitroxClient/MonoBehaviours/NitroxEntity.cs @@ -16,7 +16,6 @@ namespace NitroxClient.MonoBehaviours public class NitroxEntity : MonoBehaviour, IProtoTreeEventListener { private static readonly Dictionary gameObjectsById = new(); - private static readonly Dictionary movementControllersById = new(); [DataMember(Order = 1)] [ProtoMember(1)] @@ -74,32 +73,6 @@ public static bool TryGetComponentFrom(NitroxId id, out T component) gameObject.TryGetComponent(out component); } - public static bool TryGetMovementControllerFrom(NitroxId id, out MovementController mc) - { - mc = null; - if (id == null) // Early Exit - { - return false; - } - - - if (!movementControllersById.TryGetValue(id, out mc)) - { - if (!TryGetObjectFrom(id, out GameObject gameObject)) - { - return false; - } - - if (gameObject.TryGetComponent(out mc) && mc) - { - movementControllersById.Add(id, mc); - return true; - } - } - - return mc; - } - public static void SetNewId(GameObject gameObject, NitroxId id) { Validate.IsTrue(gameObject); diff --git a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs index 675689726b..6490d17b7c 100644 --- a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs +++ b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs @@ -1,10 +1,10 @@ using NitroxClient.GameLogic; -using NitroxModel_Subnautica.DataStructures; -using NitroxModel_Subnautica.Helper; using NitroxModel.Core; using NitroxModel.DataStructures; using NitroxModel.DataStructures.GameLogic; using NitroxModel.DataStructures.Util; +using NitroxModel_Subnautica.DataStructures; +using NitroxModel_Subnautica.Helper; using UnityEngine; namespace NitroxClient.MonoBehaviours; @@ -18,7 +18,7 @@ public class PlayerMovementBroadcaster : MonoBehaviour public const float LOCATION_BROADCAST_TIME = 0.04f; private LocalPlayer localPlayer; - private float nextLocationBroadcast; + private float timeSinceLastLocationBroadcast; public void Awake() { @@ -27,11 +27,15 @@ public void Awake() public void FixedUpdate() { - if (Time.fixedTime >= nextLocationBroadcast) + timeSinceLastLocationBroadcast += Time.fixedDeltaTime; + + if (timeSinceLastLocationBroadcast <= LOCATION_BROADCAST_TIME) { - nextLocationBroadcast = Time.fixedTime + LOCATION_BROADCAST_TIME; + return; } + timeSinceLastLocationBroadcast = 0; + // Freecam does disable main camera control // But it's also disabled when driving the cyclops through a cyclops camera (content.activeSelf is only true when controlling through a cyclops camera) if (!MainCameraControl.main.isActiveAndEnabled && diff --git a/NitroxModel/Packets/BasicMovementPacket.cs b/NitroxModel/Packets/BasicMovementPacket.cs index 6ab9ea303e..a648048092 100644 --- a/NitroxModel/Packets/BasicMovementPacket.cs +++ b/NitroxModel/Packets/BasicMovementPacket.cs @@ -1,7 +1,7 @@ +using System; using NitroxModel.DataStructures; using NitroxModel.DataStructures.Unity; using NitroxModel.Networking; -using System; namespace NitroxModel.Packets; diff --git a/NitroxPatcher/Main.cs b/NitroxPatcher/Main.cs index 16a34e87c6..e47c3041f1 100644 --- a/NitroxPatcher/Main.cs +++ b/NitroxPatcher/Main.cs @@ -1,6 +1,7 @@ extern alias JB; global using NitroxModel.Logger; global using static NitroxClient.Helpers.NitroxEntityExtensions; +global using static NitroxModel.Extensions; using System; using System.IO; using System.Reflection; @@ -106,6 +107,9 @@ private static void Init() } }; + uint forGlobalUsing = 0; + forGlobalUsing.AsByteUnitText(); // added so Code Cleanup does not nuke NitroxModel.Extensions + Log.Info($"Using Nitrox {NitroxEnvironment.ReleasePhase} V{NitroxEnvironment.Version} built on {NitroxEnvironment.BuildDate}"); try { diff --git a/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs b/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs index ed574f1e8c..373050806e 100644 --- a/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/FMOD_CustomEmitter_Start_Patch.cs @@ -25,7 +25,7 @@ public static void Prefix(FMOD_CustomEmitter __instance) return; } - if (!__instance.transform.TryGetComponentInParent(out NitroxEntity entity)) + if (!__instance.TryGetComponentInParent(out NitroxEntity entity)) { Log.Warn($"[FMOD_CustomEmitter_Start_Patch] - No NitroxEntity for \"{__instance.asset.path}\" found!"); return; diff --git a/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs b/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs index 0575d31e31..a3607dcb8b 100644 --- a/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs +++ b/NitroxServer/Communication/Packets/Processors/BasicMovementPacketProcessor.cs @@ -1,34 +1,30 @@ using NitroxModel.DataStructures.GameLogic.Entities; -using NitroxModel.DataStructures.Util; using NitroxModel.Packets; using NitroxServer.Communication.Packets.Processors.Abstract; using NitroxServer.GameLogic; using NitroxServer.GameLogic.Entities; -namespace NitroxServer.Communication.Packets.Processors +namespace NitroxServer.Communication.Packets.Processors; + +public class BasicMovementPacketProcessor : AuthenticatedPacketProcessor { - class BasicMovementPacketProcessor : AuthenticatedPacketProcessor + private readonly PlayerManager playerManager; + private readonly EntityRegistry entityRegistry; + + public BasicMovementPacketProcessor(PlayerManager playerManager, EntityRegistry entityRegistry) { - private readonly PlayerManager playerManager; - private readonly EntityRegistry entityRegistry; + this.playerManager = playerManager; + this.entityRegistry = entityRegistry; + } - public BasicMovementPacketProcessor(PlayerManager playerManager, EntityRegistry entityRegistry) + public override void Process(BasicMovement packet, Player player) + { + if (entityRegistry.TryGetEntityById(packet.Id, out WorldEntity entity)) { - this.playerManager = playerManager; - this.entityRegistry = entityRegistry; + entity.Transform.Position = packet.Position; + entity.Transform.Rotation = packet.Rotation; } - public override void Process(BasicMovement packet, Player player) - { - Optional entity = entityRegistry.GetEntityById(packet.Id); - - if (entity.HasValue) - { - entity.Value.Transform.Position = packet.Position; - entity.Value.Transform.Rotation = packet.Rotation; - } - - playerManager.SendPacketToOtherPlayers(packet, player); - } + playerManager.SendPacketToOtherPlayers(packet, player); } } diff --git a/NitroxServer/GameLogic/Entities/EntityRegistry.cs b/NitroxServer/GameLogic/Entities/EntityRegistry.cs index 5753d53d73..d066e667dd 100644 --- a/NitroxServer/GameLogic/Entities/EntityRegistry.cs +++ b/NitroxServer/GameLogic/Entities/EntityRegistry.cs @@ -42,7 +42,7 @@ public List GetAllEntities(bool exceptGlobalRoot = false) { return new(entitiesById.Values.Where(entity => entity is not GlobalRootEntity)); } - return new List(entitiesById.Values); + return new List(entitiesById.Values); } public List GetEntities(List ids) @@ -85,7 +85,7 @@ public void AddOrUpdate(Entity entity) public void AddEntities(IEnumerable entities) { - foreach(Entity entity in entities) + foreach (Entity entity in entities) { AddEntity(entity); } From f29f922a00346c97f007a9e2f57fb450802866fb Mon Sep 17 00:00:00 2001 From: killzoms Date: Thu, 23 Nov 2023 10:40:16 -0500 Subject: [PATCH 14/19] rename MovementController --- .../Packets/Processors/BasicMovementProcessor.cs | 4 ++-- .../Processors/SimulationOwnershipResponseProcessor.cs | 2 +- NitroxClient/GameLogic/MobileVehicleBay.cs | 2 +- NitroxClient/GameLogic/RemotePlayer.cs | 4 ++-- .../WorldEntities/EscapePodWorldEntitySpawner.cs | 2 +- .../WorldEntities/VehicleWorldEntitySpawner.cs | 4 ++-- ...tController.cs => MultiplayerMovementController.cs} | 10 +++++----- .../MonoBehaviours/MultiplayerVehicleControl.cs | 4 ++-- .../MonoBehaviours/PlayerMovementBroadcaster.cs | 2 +- .../FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs | 2 +- .../Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs | 2 +- .../Dynamic/PilotingChair_OnPlayerDeath_Patch.cs | 2 +- .../Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs | 2 +- .../Player_RequiresHighPrecisionPhysics_Patch.cs | 2 +- .../Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs | 2 +- .../Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs | 2 +- .../Dynamic/Vehicle_ShouldSetKinematic_Patch.cs | 2 +- 17 files changed, 25 insertions(+), 25 deletions(-) rename NitroxClient/MonoBehaviours/{MovementController.cs => MultiplayerMovementController.cs} (92%) diff --git a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs index cda5a5260d..29a685369f 100644 --- a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs @@ -10,9 +10,9 @@ public class BasicMovementProcessor : ClientPacketProcessor { public override void Process(BasicMovement movement) { - if (!MovementController.TryGetMovementControllerFrom(movement.Id, out MovementController mc) && NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) + if (!MultiplayerMovementController.TryGetMovementControllerFrom(movement.Id, out MultiplayerMovementController mc) && NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) { - mc = gameObject.EnsureComponent(); + mc = gameObject.EnsureComponent(); } if (mc) diff --git a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs index 657899c9ab..580489226e 100644 --- a/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/SimulationOwnershipResponseProcessor.cs @@ -53,7 +53,7 @@ private void SwapMovementController(NitroxId id, bool lockAcquired) { if (NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) { - MovementController movementController = gameObject.EnsureComponent(); + MultiplayerMovementController movementController = gameObject.EnsureComponent(); movementController.SetBroadcasting(lockAcquired); movementController.SetReceiving(!lockAcquired); } diff --git a/NitroxClient/GameLogic/MobileVehicleBay.cs b/NitroxClient/GameLogic/MobileVehicleBay.cs index 2cae9073c2..147153fe68 100644 --- a/NitroxClient/GameLogic/MobileVehicleBay.cs +++ b/NitroxClient/GameLogic/MobileVehicleBay.cs @@ -42,7 +42,7 @@ public void BeginCrafting(ConstructorInput constructor, GameObject constructedOb NitroxId constructedObjectId = NitroxEntity.GenerateNewId(constructedObject); - constructedObject.AddComponent(); + constructedObject.AddComponent(); VehicleWorldEntity vehicleEntity = new(constructorId, DayNightCycle.main.timePassedAsFloat, constructedObject.transform.ToLocalDto(), string.Empty, false, constructedObjectId, techType.ToDto(), null); VehicleChildEntityHelper.PopulateChildren(constructedObjectId, constructedObject.GetFullHierarchyPath(), vehicleEntity.ChildEntities, constructedObject); diff --git a/NitroxClient/GameLogic/RemotePlayer.cs b/NitroxClient/GameLogic/RemotePlayer.cs index dc1edf054f..3111311c00 100644 --- a/NitroxClient/GameLogic/RemotePlayer.cs +++ b/NitroxClient/GameLogic/RemotePlayer.cs @@ -32,7 +32,7 @@ public class RemotePlayer : INitroxPlayer public ItemsContainer Inventory { get; private set; } public Transform ItemAttachPoint { get; private set; } public RemotePlayerVitals vitals { get; private set; } - public MovementController MovementController { get; private set; } + public MultiplayerMovementController MovementController { get; private set; } public ushort PlayerId => PlayerContext.PlayerId; public string PlayerName => PlayerContext.PlayerName; @@ -63,7 +63,7 @@ public void InitializeGameObject(GameObject playerBody) RigidBody.useGravity = false; RigidBody.interpolation = RigidbodyInterpolation.Interpolate; RigidBody.isKinematic = true; - MovementController = Body.EnsureComponent(); + MovementController = Body.EnsureComponent(); MovementController.AfterUpdate += OnUpdate; NitroxEntity.SetNewId(Body, PlayerContext.PlayerNitroxId); diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs index 3d37a07339..0740df0c95 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/EscapePodWorldEntitySpawner.cs @@ -38,7 +38,7 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, E SURPRESS_ESCAPE_POD_AWAKE_METHOD = true; GameObject escapePod = CreateNewEscapePod(escapePodEntity); - escapePod.EnsureComponent(); + escapePod.EnsureComponent(); simulationOwnership.RequestSimulationLock(entity.Id, SimulationLockType.TRANSIENT); SURPRESS_ESCAPE_POD_AWAKE_METHOD = false; diff --git a/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs b/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs index fa94e70847..310af1a63e 100644 --- a/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs +++ b/NitroxClient/GameLogic/Spawning/WorldEntities/VehicleWorldEntitySpawner.cs @@ -48,7 +48,7 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, E { MobileVehicleBay.TransmitLocalSpawns = false; yield return SpawnViaConstructor(vehicleEntity, constructor, result); - result.value.Value.EnsureComponent(); + result.value.Value.EnsureComponent(); simulationOwnership.RequestSimulationLock(vehicleEntity.Id, SimulationLockType.TRANSIENT); MobileVehicleBay.TransmitLocalSpawns = true; @@ -57,7 +57,7 @@ public IEnumerator SpawnAsync(WorldEntity entity, Optional parent, E } yield return SpawnInWorld(vehicleEntity, result, parent); - result.value.Value.EnsureComponent(); + result.value.Value.EnsureComponent(); simulationOwnership.RequestSimulationLock(vehicleEntity.Id, SimulationLockType.TRANSIENT); } diff --git a/NitroxClient/MonoBehaviours/MovementController.cs b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs similarity index 92% rename from NitroxClient/MonoBehaviours/MovementController.cs rename to NitroxClient/MonoBehaviours/MultiplayerMovementController.cs index 2c59abbf72..595107b2bf 100644 --- a/NitroxClient/MonoBehaviours/MovementController.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs @@ -10,11 +10,11 @@ namespace NitroxClient.MonoBehaviours; -public class MovementController : MonoBehaviour +public class MultiplayerMovementController : MonoBehaviour { public const float LOCATION_BROADCAST_TIME = 0.04f; - private static readonly Dictionary movementControllersById = new(); + private static readonly Dictionary movementControllersById = new(); public float TimeScalar { get; set; } = 1f; public Vector3 TargetPosition { get; set; } @@ -52,7 +52,7 @@ public void SetReceiving(bool receiving) } } - public static bool TryGetMovementControllerFrom(NitroxId id, out MovementController mc) + public static bool TryGetMovementControllerFrom(NitroxId id, out MultiplayerMovementController mc) { mc = null; if (id == null) // Early Exit @@ -80,7 +80,7 @@ public static bool TryGetMovementControllerFrom(NitroxId id, out MovementControl private static void StartedSimulatingEntity(NitroxId id) { - if (NitroxEntity.TryGetComponentFrom(id, out MovementController mc)) + if (NitroxEntity.TryGetComponentFrom(id, out MultiplayerMovementController mc)) { mc.SetBroadcasting(true); } @@ -88,7 +88,7 @@ private static void StartedSimulatingEntity(NitroxId id) private static void StoppedSimulatingEntity(NitroxId id) { - if (NitroxEntity.TryGetComponentFrom(id, out MovementController mc)) + if (NitroxEntity.TryGetComponentFrom(id, out MultiplayerMovementController mc)) { mc.SetReceiving(true); } diff --git a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs index 0ad83a4ac9..8865b719c2 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerVehicleControl.cs @@ -6,7 +6,7 @@ namespace NitroxClient.MonoBehaviours { public abstract class MultiplayerVehicleControl : MonoBehaviour { - private MovementController movementController; + private MultiplayerMovementController movementController; protected readonly SmoothParameter SmoothYaw = new SmoothParameter(); protected readonly SmoothParameter SmoothPitch = new SmoothParameter(); @@ -17,7 +17,7 @@ public abstract class MultiplayerVehicleControl : MonoBehaviour protected virtual void Awake() { - movementController = gameObject.EnsureComponent(); + movementController = gameObject.EnsureComponent(); // For now, we assume the set position and rotation is equal to the server one. movementController.TargetPosition = transform.position; diff --git a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs index 6490d17b7c..943f507a7c 100644 --- a/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs +++ b/NitroxClient/MonoBehaviours/PlayerMovementBroadcaster.cs @@ -85,7 +85,7 @@ private Optional GetVehicleMovement() return Optional.Empty; } - if (vehicle.TryGetComponent(out MovementController mc)) + if (vehicle.TryGetComponent(out MultiplayerMovementController mc)) { mc.SetReceiving(false); } diff --git a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs index 6826b3ffd0..74371607c2 100644 --- a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs @@ -48,6 +48,6 @@ public static IEnumerable Transpiler(MethodBase original, IEnum public static bool IsMoving(GameObject go) { - return go.TryGetComponent(out MovementController mc) && mc.Receiving; + return go.TryGetComponent(out MultiplayerMovementController mc) && mc.Receiving; } } diff --git a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs index 2974a75f8c..ba13b5a605 100644 --- a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnHandClick_Patch.cs @@ -51,7 +51,7 @@ private static void ReceivedSimulationLockResponse(NitroxId id, bool lockAquired { skipPrefix = true; pilotingChair.OnHandClick(context.GuiHand); - if (pilotingChair.subRoot.TryGetComponent(out MovementController mc)) + if (pilotingChair.subRoot.TryGetComponent(out MultiplayerMovementController mc)) { mc.SetBroadcasting(false); } diff --git a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs index 3e246488f5..6c5453cd84 100644 --- a/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/PilotingChair_OnPlayerDeath_Patch.cs @@ -19,7 +19,7 @@ public static void Postfix(PilotingChair __instance) { // Request to be downgraded to a transient lock so we can still simulate the positioning. Resolve().RequestSimulationLock(id, SimulationLockType.TRANSIENT); - if (__instance.subRoot.TryGetComponent(out MovementController mc)) + if (__instance.subRoot.TryGetComponent(out MultiplayerMovementController mc)) { mc.SetBroadcasting(true); } diff --git a/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs b/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs index 8d7838f946..fcf85f38c6 100644 --- a/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/PilotingChair_ReleaseBy_Patch.cs @@ -19,7 +19,7 @@ public static void Postfix(PilotingChair __instance) { // Request to be downgraded to a transient lock so we can still simulate the positioning. Resolve().RequestSimulationLock(id, SimulationLockType.TRANSIENT); - if (__instance.subRoot.TryGetComponent(out MovementController mc)) + if (__instance.subRoot.TryGetComponent(out MultiplayerMovementController mc)) { mc.SetBroadcasting(true); } diff --git a/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs b/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs index 56abb89188..91942a0fbf 100644 --- a/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Player_RequiresHighPrecisionPhysics_Patch.cs @@ -18,7 +18,7 @@ public static bool Prefix(ref bool __result) { if (Player.main.currentSub) { - MovementController movementController = Player.main.currentSub.GetComponent(); + MultiplayerMovementController movementController = Player.main.currentSub.GetComponent(); if (movementController && movementController.Receiving) { diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs index ef9a38448d..705e17c61a 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeBegin_Patch.cs @@ -12,7 +12,7 @@ public sealed partial class Vehicle_OnPilotModeBegin_Patch : NitroxPatch, IDynam public static void Prefix(Vehicle __instance) { Resolve().BroadcastOnPilotModeChanged(__instance, true); - if (__instance.TryGetComponent(out MovementController mc)) + if (__instance.TryGetComponent(out MultiplayerMovementController mc)) { mc.SetBroadcasting(false); } diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs index eb06a9e0f3..db9bc57cfa 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_OnPilotModeEnd_Patch.cs @@ -22,7 +22,7 @@ public static void Prefix(Vehicle __instance) if (__instance.TryGetIdOrWarn(out NitroxId id)) { Resolve().RequestSimulationLock(id, SimulationLockType.TRANSIENT); - if (__instance.TryGetComponent(out MovementController mc)) + if (__instance.TryGetComponent(out MultiplayerMovementController mc)) { mc.SetBroadcasting(true); } diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs index 7b2e48e954..4f964968ab 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs @@ -10,7 +10,7 @@ public sealed partial class Vehicle_ShouldSetKinematic_Patch : NitroxPatch, IDyn public static bool Prefix(Vehicle __instance, ref bool __result) { - if (__instance.TryGetComponent(out MovementController movementController) && movementController.Receiving) + if (__instance.TryGetComponent(out MultiplayerMovementController movementController) && movementController.Receiving) { __result = true; return false; From 3b94bd1a101eceb08b2ec2d1eeb80a4b55186842 Mon Sep 17 00:00:00 2001 From: killzoms Date: Mon, 11 Dec 2023 19:13:19 -0500 Subject: [PATCH 15/19] Requested changes --- .../Communication/DeferredPacketReceiverTest.cs | 13 ------------- .../Packets/Processors/PacketProcessorTest.cs | 3 --- .../Packets/Processors/BasicMovementProcessor.cs | 3 ++- .../MultiplayerMovementController.cs | 15 ++++++++------- .../GameLogic/ExoSuitMovementData.cs | 4 ++-- .../Helper/VehicleMovementFactory.cs | 2 +- NitroxPatcher/Main.cs | 3 --- 7 files changed, 13 insertions(+), 30 deletions(-) diff --git a/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs b/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs index 4182c706a0..20e0d9b3c9 100644 --- a/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs +++ b/Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs @@ -1,9 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Nitrox.Test.Client.Communication; -using NitroxClient.Map; -using NitroxModel.Core; -using NitroxModel.DataStructures.GameLogic; -using NitroxModel.DataStructures.Unity; using NitroxModel.Packets; namespace NitroxClient.Communication; @@ -11,25 +7,16 @@ namespace NitroxClient.Communication; [TestClass] public class DeferredPacketReceiverTest { - private readonly VisibleCells visibleCells = new(); private PacketReceiver packetReceiver; // Test Data private const ushort PLAYER_ID = 1; - private const int CELL_LEVEL = 3; - private readonly NitroxVector3 loadedActionPosition = new(50, 50, 50); - private AbsoluteEntityCell loadedCell; [TestInitialize] public void TestInitialize() { packetReceiver = new PacketReceiver(); ClientAutoFacRegistrar registrar = new ClientAutoFacRegistrar(); - NitroxServiceLocator.InitializeDependencyContainer(registrar); - NitroxServiceLocator.BeginNewLifetimeScope(); - - loadedCell = new AbsoluteEntityCell(loadedActionPosition, CELL_LEVEL); - visibleCells.Add(loadedCell); } [TestMethod] diff --git a/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs b/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs index 175e2cc68a..773e6d9b2c 100644 --- a/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs +++ b/Nitrox.Test/Model/Packets/Processors/PacketProcessorTest.cs @@ -85,9 +85,6 @@ public void AllPacketsAreHandled() List packetTypes = typeof(DefaultServerPacketProcessor).Assembly.GetTypes() .Where(p => typeof(PacketProcessor).IsAssignableFrom(p) && p.IsClass && !p.IsAbstract) .ToList(); - ServerAutoFacRegistrar serverDependencyRegistrar = new ServerAutoFacRegistrar(); - NitroxServiceLocator.InitializeDependencyContainer(serverDependencyRegistrar); - NitroxServiceLocator.BeginNewLifetimeScope(); List abstractProcessorTypes = new(); diff --git a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs index 29a685369f..3041d75e18 100644 --- a/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs +++ b/NitroxClient/Communication/Packets/Processors/BasicMovementProcessor.cs @@ -10,7 +10,8 @@ public class BasicMovementProcessor : ClientPacketProcessor { public override void Process(BasicMovement movement) { - if (!MultiplayerMovementController.TryGetMovementControllerFrom(movement.Id, out MultiplayerMovementController mc) && NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) + if (!MultiplayerMovementController.TryGetMovementControllerFrom(movement.Id, out MultiplayerMovementController mc) && + NitroxEntity.TryGetObjectFrom(movement.Id, out GameObject gameObject)) { mc = gameObject.EnsureComponent(); } diff --git a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs index 595107b2bf..2a9cfd641e 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs @@ -55,14 +55,16 @@ public void SetReceiving(bool receiving) public static bool TryGetMovementControllerFrom(NitroxId id, out MultiplayerMovementController mc) { mc = null; - if (id == null) // Early Exit + if (id == null) { return false; } - - if (!movementControllersById.TryGetValue(id, out mc)) + if (movementControllersById.TryGetValue(id, out mc)) { + return mc; + } + if (!NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) { return false; @@ -73,14 +75,13 @@ public static bool TryGetMovementControllerFrom(NitroxId id, out MultiplayerMove movementControllersById.Add(id, mc); return true; } - } - return mc; + return false; } private static void StartedSimulatingEntity(NitroxId id) { - if (NitroxEntity.TryGetComponentFrom(id, out MultiplayerMovementController mc)) + if (TryGetMovementControllerFrom(id, out MultiplayerMovementController mc)) { mc.SetBroadcasting(true); } @@ -88,7 +89,7 @@ private static void StartedSimulatingEntity(NitroxId id) private static void StoppedSimulatingEntity(NitroxId id) { - if (NitroxEntity.TryGetComponentFrom(id, out MultiplayerMovementController mc)) + if (TryGetMovementControllerFrom(id, out MultiplayerMovementController mc)) { mc.SetReceiving(true); } diff --git a/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs b/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs index 4a85767bad..ba9b12da13 100644 --- a/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs +++ b/NitroxModel-Subnautica/DataStructures/GameLogic/ExoSuitMovementData.cs @@ -23,13 +23,13 @@ protected ExosuitMovementData() // Constructor for serialization. Has to be "protected" for json serialization. } - public ExosuitMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3 leftAimTarget, NitroxVector3 rightAimTarget, NitroxVector3 driverPosition = default, NitroxQuaternion driverRotation = default) + public ExosuitMovementData(NitroxTechType techType, NitroxId id, NitroxVector3 position, NitroxQuaternion rotation, float steeringWheelYaw, float steeringWheelPitch, bool appliedThrottle, NitroxVector3 leftAimTarget, NitroxVector3 rightAimTarget, NitroxVector3 driverPosition, NitroxQuaternion driverRotation) : base(techType, id, position, rotation, steeringWheelYaw, steeringWheelPitch, appliedThrottle, driverPosition, driverRotation) { LeftAimTarget = leftAimTarget; RightAimTarget = rightAimTarget; } - + public override string ToString() { return $"[ExosuitMovementData - {base.ToString()}, LeftAimTarget: {LeftAimTarget}, RightAimTarget: {RightAimTarget}]"; diff --git a/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs b/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs index 9f0a28189c..04a6cc044d 100644 --- a/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs +++ b/NitroxModel-Subnautica/Helper/VehicleMovementFactory.cs @@ -13,7 +13,7 @@ public static VehicleMovementData GetVehicleMovementData(TechType techType, Nitr switch (techType) { case TechType.Exosuit: - return new ExosuitMovementData(techType.ToDto(), id, position.ToDto(), rotation.ToDto(), steeringWheelYaw, steeringWheelPitch, appliedThrottle, leftAimTarget.ToDto(), rightAimTarget.ToDto()); + return new ExosuitMovementData(techType.ToDto(), id, position.ToDto(), rotation.ToDto(), steeringWheelYaw, steeringWheelPitch, appliedThrottle, leftAimTarget.ToDto(), rightAimTarget.ToDto(), default, default); default: return new BasicVehicleMovementData(techType.ToDto(), id, position.ToDto(), rotation.ToDto(), steeringWheelYaw, steeringWheelPitch, appliedThrottle); } diff --git a/NitroxPatcher/Main.cs b/NitroxPatcher/Main.cs index e47c3041f1..de74458976 100644 --- a/NitroxPatcher/Main.cs +++ b/NitroxPatcher/Main.cs @@ -107,9 +107,6 @@ private static void Init() } }; - uint forGlobalUsing = 0; - forGlobalUsing.AsByteUnitText(); // added so Code Cleanup does not nuke NitroxModel.Extensions - Log.Info($"Using Nitrox {NitroxEnvironment.ReleasePhase} V{NitroxEnvironment.Version} built on {NitroxEnvironment.BuildDate}"); try { From a8524bb156a66c72995d8844c09b3e8a0f691d6c Mon Sep 17 00:00:00 2001 From: killzoms Date: Wed, 13 Dec 2023 19:52:45 -0500 Subject: [PATCH 16/19] fix for vehicle yeet --- NitroxClient/MonoBehaviours/MultiplayerMovementController.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs index 2a9cfd641e..824b885c78 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs @@ -134,6 +134,9 @@ private void FixedUpdate() if (Broadcasting && simulationOwnership.HasAnyLockType(entity.Id)) { timeSinceLastBroadcast += Time.fixedDeltaTime; + TargetPosition = transform.position; + TargetRotation = transform.rotation; + if (timeSinceLastBroadcast >= LOCATION_BROADCAST_TIME) { timeSinceLastBroadcast = 0f; From 8e2ebf0e36ee67fdd6e9652d097a3a54ac6cdd6b Mon Sep 17 00:00:00 2001 From: killzoms Date: Wed, 13 Dec 2023 20:29:08 -0500 Subject: [PATCH 17/19] Fix Vehicle movement stutter --- .../MultiplayerMovementController.cs | 25 ++++++++++--------- .../Vehicle_ShouldSetKinematic_Patch.cs | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs index 824b885c78..0c31088271 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs @@ -54,9 +54,9 @@ public void SetReceiving(bool receiving) public static bool TryGetMovementControllerFrom(NitroxId id, out MultiplayerMovementController mc) { - mc = null; if (id == null) { + mc = null; return false; } @@ -65,16 +65,16 @@ public static bool TryGetMovementControllerFrom(NitroxId id, out MultiplayerMove return mc; } - if (!NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) - { - return false; - } + if (!NitroxEntity.TryGetObjectFrom(id, out GameObject gameObject)) + { + return false; + } - if (gameObject.TryGetComponent(out mc) && mc) - { - movementControllersById.Add(id, mc); - return true; - } + if (gameObject.TryGetComponent(out mc) && mc) + { + movementControllersById.Add(id, mc); + return true; + } return false; } @@ -120,7 +120,7 @@ private void Update() if (!rigidbody && Receiving) { Vector3 velocity = Velocity; - transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, TimeScalar * Time.deltaTime); + transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, TimeScalar * Time.deltaTime + LOCATION_BROADCAST_TIME); transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, TimeScalar * Time.deltaTime); } @@ -148,8 +148,9 @@ private void FixedUpdate() if (rigidbody && Receiving) { Vector3 velocity = Velocity; - float timing = TimeScalar * Time.fixedDeltaTime; + float timing = TimeScalar * Time.fixedDeltaTime + LOCATION_BROADCAST_TIME; Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, timing); + Velocity = velocity; if (rigidbody.isKinematic) { diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs index 4f964968ab..5b23b4e0fe 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs @@ -12,7 +12,7 @@ public static bool Prefix(Vehicle __instance, ref bool __result) { if (__instance.TryGetComponent(out MultiplayerMovementController movementController) && movementController.Receiving) { - __result = true; + __result = false; return false; } return true; From beab7d572d250f79b1740702b4735f2a35d922b7 Mon Sep 17 00:00:00 2001 From: killzoms Date: Thu, 14 Dec 2023 20:34:45 -0500 Subject: [PATCH 18/19] Null Ref fix --- NitroxClient/MonoBehaviours/NitroxEntity.cs | 11 ++++++++++- .../FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs | 16 +++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/NitroxClient/MonoBehaviours/NitroxEntity.cs b/NitroxClient/MonoBehaviours/NitroxEntity.cs index 3b5f4accd3..47e49e5e70 100644 --- a/NitroxClient/MonoBehaviours/NitroxEntity.cs +++ b/NitroxClient/MonoBehaviours/NitroxEntity.cs @@ -62,8 +62,17 @@ public static Dictionary GetObjectsFrom(HashSet public static bool TryGetObjectFrom(NitroxId id, out GameObject gameObject) { + if (id != null && gameObjectsById.TryGetValue(id, out gameObject)) + { + if (gameObject) + { + return true; + } + gameObjectsById.Remove(id); // Stale Reference + } + gameObject = null; - return id != null && gameObjectsById.TryGetValue(id, out gameObject) && gameObject; + return false; } public static bool TryGetComponentFrom(NitroxId id, out T component) diff --git a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs index 74371607c2..9938dab503 100644 --- a/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/FreezeRigidbodyWhenFar_FixedUpdate_Patch.cs @@ -13,7 +13,7 @@ public sealed partial class FreezeRigidbodyWhenFar_FixedUpdate_Patch : NitroxPat { public static readonly MethodInfo TARGET_METHOD = Reflect.Method((FreezeRigidbodyWhenFar t) => t.FixedUpdate()); - public static IEnumerable Transpiler(MethodBase original, IEnumerable instructions, ILGenerator generator) + public static IEnumerable Transpiler(IEnumerable instructions) { List instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) @@ -23,21 +23,23 @@ public static IEnumerable Transpiler(MethodBase original, IEnum if (instruction.opcode == OpCodes.Call && instruction.operand.Equals(Reflect.Method((Component c) => c.GetComponent()))) { yield return instruction; - yield return instructionList[i + 1]; + yield return instructionList[i + 1]; // Yield the found instruction and the instruction after it object jmpLabel = null; for (int j = i; j < instructionList.Count; j++) // search for branch instruction { if (instructionList[j].opcode == OpCodes.Ble_Un) { - jmpLabel = instructionList[j].operand; + jmpLabel = instructionList[j].operand; // Copy original label break; } } - yield return new CodeInstruction(OpCodes.Ldarg_0); - yield return new CodeInstruction(OpCodes.Call, Reflect.Property((Component c) => c.gameObject).GetGetMethod()); - yield return new CodeInstruction(OpCodes.Call, Reflect.Method(() => IsMoving(default))); - yield return new CodeInstruction(OpCodes.Brtrue, jmpLabel); + + yield return new(OpCodes.Ldarg_0); + yield return new(OpCodes.Call, Reflect.Property((Component c) => c.gameObject).GetGetMethod()); + yield return new(OpCodes.Call, Reflect.Method(() => IsMoving(default))); + yield return new(OpCodes.Brtrue, jmpLabel); // Put down original jmp label + i = i + 1; continue; } From 5cda5e2d0115625c1a62154307c64a3503471a3b Mon Sep 17 00:00:00 2001 From: killzoms Date: Wed, 27 Dec 2023 17:11:06 -0500 Subject: [PATCH 19/19] Last couple major bugs fixed --- .../MonoBehaviours/MultiplayerMovementController.cs | 13 +++---------- NitroxClient/MonoBehaviours/NitroxEntity.cs | 11 +---------- .../Dynamic/Vehicle_ShouldSetKinematic_Patch.cs | 2 +- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs index 0c31088271..fdacf3e32a 100644 --- a/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs +++ b/NitroxClient/MonoBehaviours/MultiplayerMovementController.cs @@ -12,8 +12,6 @@ namespace NitroxClient.MonoBehaviours; public class MultiplayerMovementController : MonoBehaviour { - public const float LOCATION_BROADCAST_TIME = 0.04f; - private static readonly Dictionary movementControllersById = new(); public float TimeScalar { get; set; } = 1f; @@ -120,7 +118,7 @@ private void Update() if (!rigidbody && Receiving) { Vector3 velocity = Velocity; - transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, TimeScalar * Time.deltaTime + LOCATION_BROADCAST_TIME); + transform.position = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, TimeScalar * Time.deltaTime); transform.rotation = Quaternion.Lerp(transform.rotation, TargetRotation, TimeScalar * Time.deltaTime); } @@ -137,18 +135,13 @@ private void FixedUpdate() TargetPosition = transform.position; TargetRotation = transform.rotation; - if (timeSinceLastBroadcast >= LOCATION_BROADCAST_TIME) - { - timeSinceLastBroadcast = 0f; - - packetSender.Send(new BasicMovement(entity.Id, transform.position.ToDto(), transform.rotation.ToDto())); - } + packetSender.Send(new BasicMovement(entity.Id, transform.position.ToDto(), transform.rotation.ToDto())); } if (rigidbody && Receiving) { Vector3 velocity = Velocity; - float timing = TimeScalar * Time.fixedDeltaTime + LOCATION_BROADCAST_TIME; + float timing = TimeScalar * Time.fixedDeltaTime; Vector3 newPos = Vector3.SmoothDamp(transform.position, TargetPosition, ref velocity, timing); Velocity = velocity; diff --git a/NitroxClient/MonoBehaviours/NitroxEntity.cs b/NitroxClient/MonoBehaviours/NitroxEntity.cs index 47e49e5e70..3b5f4accd3 100644 --- a/NitroxClient/MonoBehaviours/NitroxEntity.cs +++ b/NitroxClient/MonoBehaviours/NitroxEntity.cs @@ -62,17 +62,8 @@ public static Dictionary GetObjectsFrom(HashSet public static bool TryGetObjectFrom(NitroxId id, out GameObject gameObject) { - if (id != null && gameObjectsById.TryGetValue(id, out gameObject)) - { - if (gameObject) - { - return true; - } - gameObjectsById.Remove(id); // Stale Reference - } - gameObject = null; - return false; + return id != null && gameObjectsById.TryGetValue(id, out gameObject) && gameObject; } public static bool TryGetComponentFrom(NitroxId id, out T component) diff --git a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs index 5b23b4e0fe..1894ead235 100644 --- a/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs +++ b/NitroxPatcher/Patches/Dynamic/Vehicle_ShouldSetKinematic_Patch.cs @@ -10,7 +10,7 @@ public sealed partial class Vehicle_ShouldSetKinematic_Patch : NitroxPatch, IDyn public static bool Prefix(Vehicle __instance, ref bool __result) { - if (__instance.TryGetComponent(out MultiplayerMovementController movementController) && movementController.Receiving) + if (!__instance.GetRecentlyUndocked() && __instance.TryGetComponent(out MultiplayerMovementController movementController) && movementController.Receiving) { __result = false; return false;