예제 #1
0
        // Will be called at a later, because it is needed that the modules are installed and may need power to not immediatly be shut off
        public void SetAdvancedModes(CyclopsModel cyclopsModel)
        {
            // We need to wait till the cyclops is powered up to start all advanced modes
            // At this time all Equipment will be loaded into the cyclops, so we do not need other structures
            SubRoot root = NitroxEntity.GetObjectFrom(cyclopsModel.Id).Value.GetComponent <SubRoot>();

            UWE.Event <PowerRelay> .HandleFunction handleFunction = null;
            handleFunction = _ =>
            {
                ChangeSilentRunning(cyclopsModel.Id, cyclopsModel.SilentRunningOn);
                ChangeShieldMode(cyclopsModel.Id, cyclopsModel.ShieldOn);
                ChangeSonarMode(cyclopsModel.Id, cyclopsModel.SonarOn);

                // After registering all modes. Remove the handler
                root.powerRelay.powerUpEvent.RemoveHandler(root, handleFunction);
            };
            root.powerRelay.powerUpEvent.AddHandler(root, handleFunction);
        }
예제 #2
0
        public void SetOnPilotMode(NitroxId vehicleId, ushort playerId, bool isPiloting)
        {
            Optional <GameObject> opVehicle = NitroxEntity.GetObjectFrom(vehicleId);

            if (!opVehicle.HasValue)
            {
                return;
            }
            GameObject gameObject = opVehicle.Value;
            Vehicle    vehicle    = gameObject.GetComponent <Vehicle>();

            if (vehicle == null)
            {
                return;
            }

            vehicle.pilotId = isPiloting ? playerId.ToString() : string.Empty;
        }
        public override void Process(InitialPlayerSync packet)
        {
            using (packetSender.Suppress <ItemContainerAdd>())
            {
                foreach (EquippedItemData equippedItem in packet.EquippedItems)
                {
                    GameObject gameObject = SerializationHelper.GetGameObject(equippedItem.SerializedData);
                    NitroxEntity.SetNewId(gameObject, equippedItem.ItemId);

                    Pickupable            pickupable   = gameObject.RequireComponent <Pickupable>();
                    Optional <GameObject> opGameObject = NitroxEntity.GetObjectFrom(equippedItem.ContainerId);

                    if (opGameObject.IsPresent())
                    {
                        GameObject owner = opGameObject.Get();

                        Optional <Equipment> opEquipment = EquipmentHelper.GetBasedOnOwnersType(owner);

                        if (opEquipment.IsPresent())
                        {
                            Equipment     equipment     = opEquipment.Get();
                            InventoryItem inventoryItem = new InventoryItem(pickupable);
                            inventoryItem.container = equipment;
                            inventoryItem.item.Reparent(equipment.tr);

                            Dictionary <string, InventoryItem> itemsBySlot = (Dictionary <string, InventoryItem>)equipment.ReflectionGet("equipment");
                            itemsBySlot[equippedItem.Slot] = inventoryItem;

                            equipment.ReflectionCall("UpdateCount", false, false, new object[] { pickupable.GetTechType(), true });
                            Equipment.SendEquipmentEvent(pickupable, 0, owner, equippedItem.Slot);
                            equipment.ReflectionCall("NotifyEquip", false, false, new object[] { equippedItem.Slot, inventoryItem });
                        }
                        else
                        {
                            Log.Info("Could not find equipment type for " + gameObject.name);
                        }
                    }
                    else
                    {
                        Log.Info("Could not find Container for " + gameObject.name);
                    }
                }
            }
        }
예제 #4
0
        public RemotePlayer Create(PlayerContext playerContext, Optional <NitroxId> subRootId, List <TechType> equippedTechTypes, List <Pickupable> inventoryItems)
        {
            Validate.NotNull(playerContext);

            if (playersById.ContainsKey(playerContext.PlayerId))
            {
                throw new Exception("The playerId has already been used.");
            }

            GameObject   remotePlayerBody = CloneLocalPlayerBodyPrototype();
            RemotePlayer remotePlayer;

            using (packetSender.Suppress <ItemContainerAdd>())
            {
                remotePlayer = new RemotePlayer(remotePlayerBody, playerContext, equippedTechTypes, inventoryItems, playerModelManager);
            }

            if (subRootId.HasValue)
            {
                Optional <GameObject> sub = NitroxEntity.GetObjectFrom(subRootId.Value);
                if (sub.HasValue && sub.Value.TryGetComponent(out SubRoot subRoot))
                {
                    Log.Debug($"Found sub root for {playerContext.PlayerName}. Will add him and update animation.");
                    remotePlayer.SetSubRoot(subRoot);
                }
                else if (sub.HasValue && sub.Value.TryGetComponent(out EscapePod escapePod))
                {
                    Log.Debug($"Found EscapePod for {playerContext.PlayerName}.");
                    remotePlayer.SetEscapePod(escapePod);
                }
                else
                {
                    Log.Error($"Found neither SubRoot component nor EscapePod on {subRootId.Value} for {playerContext.PlayerName}.");
                }
            }

            playersById.Add(remotePlayer.PlayerId, remotePlayer);

            DiscordRPController.Main.UpdatePlayerCount(GetTotalPlayerCount());

            return(remotePlayer);
        }
        public override void Process(EntityTransformUpdates packet)
        {
            foreach (EntityTransformUpdate entity in packet.Updates)
            {
                Optional <GameObject> opGameObject = NitroxEntity.GetObjectFrom(entity.Id);

                if (!opGameObject.HasValue)
                {
                    continue;
                }

                RemotelyControlled remotelyControlled = opGameObject.Value.GetComponent <RemotelyControlled>();

                if (!remotelyControlled)
                {
                    remotelyControlled = opGameObject.Value.AddComponent <RemotelyControlled>();
                }

                remotelyControlled.UpdateOrientation(entity.Position.ToUnity(), entity.Rotation.ToUnity());
            }
        }
        public override IEnumerator Process(InitialPlayerSync packet, WaitScreen.ManualWaitItem waitScreenItem)
        {
            int remotePlayersSynced = 0;

            foreach (InitialRemotePlayerData playerData in packet.RemotePlayerData)
            {
                waitScreenItem.SetProgress(remotePlayersSynced, packet.RemotePlayerData.Count);

                List <TechType> equippedTechTypes = playerData.EquippedTechTypes.Select(techType => techType.ToUnity()).ToList();
                RemotePlayer    player            = remotePlayerManager.Create(playerData.PlayerContext, equippedTechTypes);

                if (playerData.SubRootId.HasValue)
                {
                    Optional <GameObject> sub = NitroxEntity.GetObjectFrom(playerData.SubRootId.Value);

                    if (sub.HasValue)
                    {
                        Log.Debug($"sub value set to {sub.Value}. Try to find subroot");
                        SubRoot subroot = null;
                        sub.Value.TryGetComponent <SubRoot>(out subroot);
                        if (subroot)
                        {
                            Log.Debug("Found subroot for player. Will add him and update animation.");
                            player.SetSubRoot(subroot);
                        }
                    }
                    else
                    {
                        Log.Error("Could not spawn remote player into subroot/escape pod with id: " + playerData.SubRootId.Value);
                    }
                }

                if (!IsSwimming(playerData.Position.ToUnity(), playerData.SubRootId))
                {
                    player.UpdateAnimation(AnimChangeType.UNDERWATER, AnimChangeState.OFF);
                }
                remotePlayersSynced++;
                yield return(null);
            }
        }
예제 #7
0
        public override IEnumerator Process(InitialPlayerSync packet, WaitScreen.ManualWaitItem waitScreenItem)
        {
            Vector3             position  = packet.PlayerSpawnData;
            Optional <NitroxId> subRootId = packet.PlayerSubRootId;

            if (position.x == 0 && position.y == 0 && position.z == 0)
            {
                position = Player.mainObject.transform.position;
            }
            Player.main.SetPosition(position);

            if (subRootId.IsPresent())
            {
                Optional <GameObject> sub = NitroxEntity.GetObjectFrom(subRootId.Get());

                if (sub.IsPresent())
                {
                    SubRoot root = sub.Get().GetComponent <SubRoot>();
                    // Player position is relative to a subroot if in a subroot
                    if (root != null && !root.isBase)
                    {
                        Player.main.SetCurrentSub(root);
                        Quaternion vehicleAngle = root.transform.rotation;
                        position = vehicleAngle * position;
                        position = position + root.transform.position;
                        Player.main.SetPosition(position);
                    }
                    else
                    {
                        Log.Error("Could not find subroot for player for subroot with id: " + subRootId.Get());
                    }
                }
                else
                {
                    Log.Error("Could not spawn player into subroot with id: " + subRootId.Get());
                }
            }

            yield return(null);
        }
예제 #8
0
        public void Spawn(List <Entity> entities)
        {
            foreach (Entity entity in entities)
            {
                LargeWorldStreamer.main.cellManager.UnloadBatchCells(ToInt3(entity.AbsoluteEntityCell.CellId)); // Just in case

                if (alreadySpawnedIds.Contains(entity.Id))
                {
                    UpdatePosition(entity);
                }
                else if (entity.ParentId != null && !alreadySpawnedIds.Contains(entity.ParentId))
                {
                    AddPendingParentEntity(entity);
                }
                else
                {
                    Optional <GameObject> parent = NitroxEntity.GetObjectFrom(entity.ParentId);
                    Spawn(entity, parent);
                    SpawnAnyPendingChildren(entity);
                }
            }
        }
예제 #9
0
파일: Vehicles.cs 프로젝트: elevir/Nitrox
        public void SetOnPilotMode(NitroxId vehicleId, ushort playerId, bool isPiloting)
        {
            Optional <GameObject> opVehicle = NitroxEntity.GetObjectFrom(vehicleId);

            if (opVehicle.IsPresent())
            {
                GameObject gameObject = opVehicle.Get();
                Vehicle    vehicle    = gameObject.GetComponent <Vehicle>();

                if (vehicle != null)
                {
                    if (isPiloting)
                    {
                        vehicle.pilotId = playerId.ToString();
                    }
                    else
                    {
                        vehicle.pilotId = string.Empty;
                    }
                }
            }
        }
        public override void Process(InitialPlayerSync packet)
        {
            foreach (InitialRemotePlayerData playerData in packet.RemotePlayerData)
            {
                List <TechType> equippedTechTypes = playerData.EquippedTechTypes.Select(techType => techType.Enum()).ToList();
                RemotePlayer    player            = remotePlayerManager.Create(playerData.PlayerContext, equippedTechTypes);

                if (playerData.SubRootId.IsPresent())
                {
                    Optional <GameObject> sub = NitroxEntity.GetObjectFrom(playerData.SubRootId.Get());

                    if (sub.IsPresent())
                    {
                        player.SetSubRoot(sub.Get().GetComponent <SubRoot>());
                    }
                    else
                    {
                        Log.Error("Could not spawn remote player into subroot with id: " + playerData.SubRootId.Get());
                    }
                }
            }
        }
예제 #11
0
        public override void Process(PlayFMODCustomEmitter packet)
        {
            Optional <GameObject> soundSource = NitroxEntity.GetObjectFrom(packet.Id);

            Validate.IsPresent(soundSource);

            FMODEmitterController fmodEmitterController = soundSource.Value.GetComponent <FMODEmitterController>();

            Validate.IsTrue(fmodEmitterController);

            using (packetSender.Suppress <PlayFMODCustomEmitter>())
            {
                if (packet.Play)
                {
                    fmodEmitterController.PlayCustomEmitter(packet.AssetPath);
                }
                else
                {
                    fmodEmitterController.StopCustomEmitter(packet.AssetPath);
                }
            }
        }
예제 #12
0
        public void AddItem(GameObject item, NitroxId containerId, bool silent = false)
        {
            Optional <GameObject> owner = NitroxEntity.GetObjectFrom(containerId);

            if (!owner.HasValue)
            {
                Log.Error("Could not place " + item.name + " in storageSlot container with id " + containerId);
                return;
            }

            // only need to watch EnergyMixin slots for now (only other type will be propulsion cannon)
            Optional <EnergyMixin> opEnergy = Optional.OfNullable(owner.Value.GetComponent <EnergyMixin>());

            if (opEnergy.HasValue)
            {
                EnergyMixin mixin = opEnergy.Value;
                StorageSlot slot  = mixin.batterySlot;

                Pickupable pickupable = item.RequireComponent <Pickupable>();

                // Suppress sound when silent is active
                // Will be used to suppress swap sound at the initialisation of the game
                bool allowedToPlaySounds = true;
                if (silent)
                {
                    allowedToPlaySounds       = mixin.allowedToPlaySounds;
                    mixin.allowedToPlaySounds = !silent;
                }
                using (packetSender.Suppress <StorageSlotItemAdd>())
                {
                    slot.AddItem(new InventoryItem(pickupable));
                }
                if (silent)
                {
                    mixin.allowedToPlaySounds = allowedToPlaySounds;
                }
            }
        }
예제 #13
0
        public override void Process(ModuleAdded packet)
        {
            EquippedItemData equippedItemData = packet.EquippedItemData;
            GameObject       gameObject       = SerializationHelper.GetGameObject(equippedItemData.SerializedData);

            Pickupable pickupable = gameObject.RequireComponent <Pickupable>();

            Optional <GameObject> opGameObject = NitroxEntity.GetObjectFrom(equippedItemData.ContainerId);

            if (opGameObject.IsPresent())
            {
                GameObject           owner       = opGameObject.Get();
                Optional <Equipment> opEquipment = EquipmentHelper.GetBasedOnOwnersType(owner);

                if (opEquipment.IsPresent())
                {
                    Equipment     equipment     = opEquipment.Get();
                    InventoryItem inventoryItem = new InventoryItem(pickupable);
                    inventoryItem.container = equipment;
                    inventoryItem.item.Reparent(equipment.tr);

                    Dictionary <string, InventoryItem> itemsBySlot = (Dictionary <string, InventoryItem>)equipment.ReflectionGet("equipment");
                    itemsBySlot[equippedItemData.Slot] = inventoryItem;

                    equipment.ReflectionCall("UpdateCount", false, false, new object[] { pickupable.GetTechType(), true });
                    Equipment.SendEquipmentEvent(pickupable, EQUIP_EVENT_TYPE_ID, owner, equippedItemData.Slot);
                    equipment.ReflectionCall("NotifyEquip", false, false, new object[] { equippedItemData.Slot, inventoryItem });
                }
                else
                {
                    Log.Error("Could not find equipment type for " + gameObject.name);
                }
            }
            else
            {
                Log.Info("Could not find Container for " + gameObject.name);
            }
        }
    public override void Process(PlayerCinematicControllerCall packet)
    {
        Optional <GameObject> opEntity = NitroxEntity.GetObjectFrom(packet.ControllerID);

        Validate.IsPresent(opEntity);

        MultiplayerCinematicReference reference = opEntity.Value.GetComponent <MultiplayerCinematicReference>();

        Validate.IsTrue(reference);

        Optional <RemotePlayer> opPlayer = playerManager.Find(packet.PlayerId);

        Validate.IsPresent(opPlayer);

        if (packet.StartPlaying)
        {
            reference.CallStartCinematicMode(packet.Key, packet.ControllerNameHash, opPlayer.Value);
        }
        else
        {
            reference.CallCinematicModeEnd(packet.Key, packet.ControllerNameHash, opPlayer.Value);
        }
    }
예제 #15
0
        public override void Process(PlayerHeldItemChanged packet)
        {
            Optional <RemotePlayer> opPlayer = playerManager.Find(packet.PlayerId);

            Validate.IsPresent(opPlayer);

            Optional <GameObject> opItem = NitroxEntity.GetObjectFrom(packet.ItemId);

            Validate.IsPresent(opItem);

            Pickupable pickupable = opItem.Value.GetComponent <Pickupable>();

            Validate.IsTrue(pickupable);

            InventoryItem inventoryItem = (InventoryItem)inventoryItemFromPickupable.GetValue(pickupable);

            Validate.NotNull(inventoryItem);

            ItemsContainer inventory = opPlayer.Value.Inventory;
            PlayerTool     tool      = opItem.Value.GetComponent <PlayerTool>();

            // Copied from QuickSlots
            switch (packet.Type)
            {
            case PlayerHeldItemChangedType.DRAW_AS_TOOL:
                Validate.IsTrue(tool);
                ModelPlug.PlugIntoSocket(tool, opPlayer.Value.ItemAttachPoint);
                Utils.SetLayerRecursively(opItem.Value, viewModelLayer);
                foreach (Animator componentsInChild in tool.GetComponentsInChildren <Animator>())
                {
                    componentsInChild.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                }
                if (tool.mainCollider)
                {
                    tool.mainCollider.enabled = false;
                }
                tool.GetComponent <Rigidbody>().isKinematic = true;
                opItem.Value.SetActive(true);
                setHandIK.Invoke(tool, new object[] { true });
                SafeAnimator.SetBool(opPlayer.Value.ArmsController.GetComponent <Animator>(), $"holding_{tool.animToolName}", true);
                opPlayer.Value.AnimationController["using_tool_first"] = packet.IsFirstTime == null;

                if (opItem.Value.TryGetComponent(out FPModel fpModelDraw))     //FPModel needs to be updated
                {
                    fpModelDraw.OnEquip(null, null);
                }
                break;

            case PlayerHeldItemChangedType.HOLSTER_AS_TOOL:
                Validate.IsTrue(tool);
                opItem.Value.SetActive(false);
                Utils.SetLayerRecursively(opItem.Value, defaultLayer);
                if (tool.mainCollider)
                {
                    tool.mainCollider.enabled = true;
                }
                tool.GetComponent <Rigidbody>().isKinematic = false;
                inventoryItem.item.Reparent(inventory.tr);
                foreach (Animator componentsInChild in tool.GetComponentsInChildren <Animator>())
                {
                    componentsInChild.cullingMode = AnimatorCullingMode.CullUpdateTransforms;
                }
                SafeAnimator.SetBool(opPlayer.Value.ArmsController.GetComponent <Animator>(), $"holding_{tool.animToolName}", false);
                opPlayer.Value.AnimationController["using_tool_first"] = false;

                if (opItem.Value.TryGetComponent(out FPModel fpModelHolster))     //FPModel needs to be updated
                {
                    fpModelHolster.OnUnequip(null, null);
                }

                break;

            case PlayerHeldItemChangedType.DRAW_AS_ITEM:
                inventoryItem.item.Reparent(opPlayer.Value.ItemAttachPoint);
                inventoryItem.item.SetVisible(true);
                Utils.SetLayerRecursively(inventoryItem.item.gameObject, viewModelLayer);
                break;

            case PlayerHeldItemChangedType.HOLSTER_AS_ITEM:
                inventoryItem.item.Reparent(inventory.tr);
                inventoryItem.item.SetVisible(false);
                Utils.SetLayerRecursively(inventoryItem.item.gameObject, defaultLayer);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #16
0
        public void UpdateVehiclePosition(VehicleMovementData vehicleModel, Optional <RemotePlayer> player)
        {
            Vector3    remotePosition  = vehicleModel.Position;
            Vector3    remoteVelocity  = vehicleModel.Velocity;
            Quaternion remoteRotation  = vehicleModel.Rotation;
            Vector3    angularVelocity = vehicleModel.AngularVelocity;

            Vehicle vehicle = null;
            SubRoot subRoot = null;

            Optional <GameObject> opGameObject = NitroxEntity.GetObjectFrom(vehicleModel.Id);

            if (opGameObject.HasValue)
            {
                GameObject gameObject = opGameObject.Value;

                vehicle = gameObject.GetComponent <Vehicle>();
                subRoot = gameObject.GetComponent <SubRoot>();

                MultiplayerVehicleControl mvc = null;

                if (subRoot != null)
                {
                    mvc = subRoot.gameObject.EnsureComponent <MultiplayerCyclops>();
                    subRoot.GetComponent <LiveMixin>().health = vehicleModel.Health;
                }
                else if (vehicle != null)
                {
                    SeaMoth seamoth = vehicle as SeaMoth;
                    Exosuit exosuit = vehicle as Exosuit;

                    if (seamoth)
                    {
                        mvc = seamoth.gameObject.EnsureComponent <MultiplayerSeaMoth>();
                    }
                    else if (exosuit)
                    {
                        mvc = exosuit.gameObject.EnsureComponent <MultiplayerExosuit>();
                        if (vehicleModel.GetType() == typeof(ExosuitMovementData))
                        {
                            ExosuitMovementData exoSuitMovement = (ExosuitMovementData)vehicleModel;
                            mvc.SetArmPositions(exoSuitMovement.LeftAimTarget, exoSuitMovement.RightAimTarget);
                        }
                        else
                        {
                            Log.Error($"{nameof(Vehicles)}: Got exosuit vehicle but no ExosuitMovementData");
                        }
                    }

                    vehicle.GetComponent <LiveMixin>().health = vehicleModel.Health;
                }

                if (mvc != null)
                {
                    mvc.SetPositionVelocityRotation(remotePosition, remoteVelocity, remoteRotation, angularVelocity);
                    mvc.SetThrottle(vehicleModel.AppliedThrottle);
                    mvc.SetSteeringWheel(vehicleModel.SteeringWheelYaw, vehicleModel.SteeringWheelPitch);
                }
            }

            if (player.HasValue)
            {
                RemotePlayer playerInstance = player.Value;
                playerInstance.SetVehicle(vehicle);
                playerInstance.SetSubRoot(subRoot);
                playerInstance.SetPilotingChair(subRoot?.GetComponentInChildren <PilotingChair>());
                playerInstance.AnimationController.UpdatePlayerAnimations = false;
            }
        }
예제 #17
0
        public void ProcessRemoteHealthChange(NitroxId id, float LifeChanged, Optional <DamageTakenData> opDamageTakenData, float totalHealth)
        {
            if (simulationOwnership.HasAnyLockType(id))
            {
                Log.Error($"Got LiveMixin change health for {id} but we have the simulation already. This should not happen!");
                return;
            }

            processingRemoteHealthChange = true;

            LiveMixin liveMixin = NitroxEntity.RequireObjectFrom(id).GetComponent <LiveMixin>();

            if (LifeChanged < 0)
            {
                DamageTakenData       damageTakenData = opDamageTakenData.OrElse(null);
                Optional <GameObject> opDealer        = damageTakenData.DealerId.HasValue ? NitroxEntity.GetObjectFrom(damageTakenData.DealerId.Value) : Optional.Empty;
                GameObject            dealer          = opDealer.HasValue ? opDealer.Value : null;
                if (!dealer && damageTakenData.DealerId.HasValue)
                {
                    Log.Warn($"Could not find entity {damageTakenData.DealerId.Value} for damage calculation. This could lead to problems.");
                }
                liveMixin.TakeDamage(-LifeChanged, damageTakenData.Position.ToUnity(), (DamageType)damageTakenData.DamageType, dealer);
            }
            else
            {
                liveMixin.AddHealth(LifeChanged);
            }

            processingRemoteHealthChange = false;

            // Check if the health calculated by the game is the same as the calculated damage from the simulator
            if (liveMixin.health != totalHealth)
            {
                Log.Warn($"Calculated health and send health for {id} do not align (Calculated: {liveMixin.health}, send:{totalHealth}). This will be correted but should be investigated");
                liveMixin.health = totalHealth;
            }
        }
예제 #18
0
        public void UpdateVehiclePosition(VehicleMovementData vehicleModel, Optional <RemotePlayer> player)
        {
            Optional <GameObject> opGameObject = NitroxEntity.GetObjectFrom(vehicleModel.Id);
            Vehicle vehicle = null;
            SubRoot subRoot = null;

            if (opGameObject.HasValue)
            {
                Rocket rocket = opGameObject.Value.GetComponent <Rocket>();
                vehicle = opGameObject.Value.GetComponent <Vehicle>();
                subRoot = opGameObject.Value.GetComponent <SubRoot>();

                MultiplayerVehicleControl mvc = null;

                if (subRoot)
                {
                    mvc = subRoot.gameObject.EnsureComponent <MultiplayerCyclops>();
                }
                else if (vehicle)
                {
                    if (vehicle.docked)
                    {
                        Log.Debug($"For vehicle {vehicleModel.Id} position update while docked, will not execute");
                        return;
                    }

                    switch (vehicle)
                    {
                    case SeaMoth seamoth:
                    {
                        mvc = seamoth.gameObject.EnsureComponent <MultiplayerSeaMoth>();
                        break;
                    }

                    case Exosuit exosuit:
                    {
                        mvc = exosuit.gameObject.EnsureComponent <MultiplayerExosuit>();

                        if (vehicleModel is ExosuitMovementData exoSuitMovement)
                        {
                            mvc.SetArmPositions(exoSuitMovement.LeftAimTarget.ToUnity(), exoSuitMovement.RightAimTarget.ToUnity());
                        }
                        else
                        {
                            Log.Error($"{nameof(Vehicles)}: Got exosuit vehicle but no ExosuitMovementData");
                        }
                        break;
                    }
                    }
                }
                else if (rocket)
                {
                    rocket.transform.position = vehicleModel.Position.ToUnity();
                    rocket.transform.rotation = vehicleModel.Rotation.ToUnity();
                }

                if (mvc)
                {
                    mvc.SetPositionVelocityRotation(
                        vehicleModel.Position.ToUnity(),
                        vehicleModel.Velocity.ToUnity(),
                        vehicleModel.Rotation.ToUnity(),
                        vehicleModel.AngularVelocity.ToUnity()
                        );
                    mvc.SetThrottle(vehicleModel.AppliedThrottle);
                    mvc.SetSteeringWheel(vehicleModel.SteeringWheelYaw, vehicleModel.SteeringWheelPitch);
                }
            }

            if (player.HasValue)
            {
                RemotePlayer playerInstance = player.Value;
                playerInstance.SetVehicle(vehicle);
                playerInstance.SetSubRoot(subRoot);
                playerInstance.SetPilotingChair(subRoot?.GetComponentInChildren <PilotingChair>());
                playerInstance.AnimationController.UpdatePlayerAnimations = false;
            }
        }