Ejemplo n.º 1
0
 public void SetDamping(bool enable)
 {
     Sandbox.Game.Entities.IMyControllableEntity control = Block.Controller as Sandbox.Game.Entities.IMyControllableEntity;
     if (control.EnabledDamping != enable)
     {
         Log.TraceLog("setting damp, EnabledDamping: " + control.EnabledDamping + ", enable: " + enable);
         MyAPIGateway.Utilities.TryInvokeOnGameThread(() => {
             if (control.EnabledDamping != enable)
             {
                 control.SwitchDamping();
             }
         });
     }
 }
        /// <summary>
        /// Reset the third person camera "head" angles.
        /// </summary>
        /// <param name="headAngle">new head angle</param>
        public bool ResetViewerAngle(Vector2?headAngle)
        {
            if (!headAngle.HasValue)
            {
                return(false);
            }

            Sandbox.Game.Entities.IMyControllableEntity controlledEntity = MySession.Static.ControlledEntity as Sandbox.Game.Entities.IMyControllableEntity;
            if (controlledEntity == null)
            {
                return(false);
            }

            controlledEntity.HeadLocalXAngle = headAngle.Value.X;
            controlledEntity.HeadLocalYAngle = headAngle.Value.Y;
            return(true);
        }
Ejemplo n.º 3
0
        public void ResetPosition(double distance, Vector2?headAngle)
        {
            if (headAngle.HasValue)
            {
                Sandbox.Game.Entities.IMyControllableEntity controlledEntity = MySession.Static.ControlledEntity as Sandbox.Game.Entities.IMyControllableEntity;
                if (controlledEntity == null)
                {
                    return;
                }

                controlledEntity.HeadLocalXAngle = headAngle.Value.X;
                controlledEntity.HeadLocalYAngle = headAngle.Value.Y;

                ResetDistance(distance);

                m_positionSafe.AssertIsValid();
            }
        }
Ejemplo n.º 4
0
        public void RecalibrateCameraPosition(bool isCharacter = false)
        {
            // if (m_lookAt != Vector3D.Zero)
            //    return;

            IMyCameraController cameraController = MySession.Static.CameraController;

            if (cameraController == null || !(cameraController is MyEntity))
            {
                return;
            }

            Sandbox.Game.Entities.IMyControllableEntity controlledEntity = MySession.Static.ControlledEntity as Sandbox.Game.Entities.IMyControllableEntity;
            if (controlledEntity == null)
            {
                return;
            }

            // get latest head matrix
            if (!isCharacter)
            {
                var headMatrix = controlledEntity.GetHeadMatrix(true);
                m_targetOrientation = (Matrix)headMatrix.GetOrientation();
                m_target            = headMatrix.Translation;
            }

            // parent of hierarchy
            MyEntity topControlledEntity = ((MyEntity)cameraController).GetTopMostParent();

            if (topControlledEntity.Closed)
            {
                return;
            }

            // calculate controlled object coordinates in parent space
            var      worldToLocal       = topControlledEntity.PositionComp.WorldMatrixNormalizedInv;
            Vector3D targetInLocal      = Vector3D.Transform(m_target, worldToLocal);
            MatrixD  orientationInLocal = m_targetOrientation * worldToLocal;
            var      localAABBHr        = topControlledEntity.PositionComp.LocalAABBHr;
            Vector3D centerToTarget     = targetInLocal - localAABBHr.Center;
            Vector3D backVec            = Vector3D.Normalize(orientationInLocal.Backward);

            // calculate offset for the
            double projectedCenterToTarget = Vector3D.Dot(centerToTarget, backVec);
            double projectedHalfExtent     = Math.Abs(Vector3D.Dot(localAABBHr.HalfExtents, backVec));
            double finalLength             = projectedHalfExtent - projectedCenterToTarget;

            Vector3D targetWithOffset = centerToTarget + (finalLength * backVec);

            double width = LOOK_AT_DEFAULT_LENGTH; // some default value

            if (Math.Abs(backVec.Z) > 0.0001)
            {
                width = localAABBHr.HalfExtents.X * 1.5f;
            }
            else if (Math.Abs(backVec.X) > 0.0001)
            {
                width = localAABBHr.HalfExtents.Z * 1.5f;
            }

            // calculate complete offset for controlled object
            double halfFovTan = Math.Tan(MySector.MainCamera.FieldOfView * 0.5);
            double offset     = width / (2 * halfFovTan);

            offset += finalLength;

            double clampDist = MathHelper.Clamp(offset, GetMinDistance(), MAX_DISTANCE);

            Vector3D lookAt = LOOK_AT_DIRECTION * clampDist;

            SetPositionAndLookAt(lookAt);
        }
Ejemplo n.º 5
0
        // Updates spectator position (spring connected to desired position)
        public override void UpdateAfterSimulation()
        {
            Sandbox.Game.Entities.IMyControllableEntity controlledEntity = MySession.Static.ControlledEntity as Sandbox.Game.Entities.IMyControllableEntity;
            if (controlledEntity == null)
            {
                return;
            }

            var headMatrix = controlledEntity.GetHeadMatrix(true);

            if (controlledEntity is MyCharacter)
            {
                var character = controlledEntity as MyCharacter;
                headMatrix = character.Get3rdBoneMatrix(true, true);
            }

            m_targetOrientation = (Matrix)headMatrix.GetOrientation();
            m_target            = headMatrix.Translation;


            //VRageRender.MyRenderProxy.DebugDrawAxis(headMatrix, 1, false);

            UpdateCurrentSpring();

            m_transformedLookAt = Vector3D.Transform(m_lookAt, m_targetOrientation);
            m_desiredPosition   = m_target + m_transformedLookAt;

            //m_position = m_desiredPosition;
            //m_velocity = Vector3.Zero;
            // Calculate spring force
            Vector3D stretch = m_position - m_desiredPosition;

            Vector3D force = -m_currentSpring.Stiffness * stretch - m_currentSpring.Damping * m_velocity;

            force.AssertIsValid();

            // Apply acceleration
            Vector3 acceleration = (Vector3)force / m_currentSpring.Mass;

            m_velocity += acceleration * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            m_velocity.AssertIsValid();

            // Apply velocity
            if (!Sandbox.Game.Multiplayer.Sync.IsServer)
            {  //We are not able to interpolate camera correctly if position is updated through server
                m_position = m_desiredPosition;
            }
            else
            {
                m_position += m_velocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            }
            m_position.AssertIsValid();

            // Limit backward distance from target
            double backward = Vector3D.Dot((Vector3D)m_targetOrientation.Backward, (m_target - m_position));

            if (backward > -BACKWARD_CUTOFF)
            {
                m_position += (Vector3D)m_targetOrientation.Backward * (backward + BACKWARD_CUTOFF);
            }

            // Roll spring
            Quaternion targetOrientation = Quaternion.CreateFromRotationMatrix(m_targetOrientation);

            // Computes angle difference between current and target orientation
            var angleDifference = (float)Math.Acos(MathHelper.Clamp(Quaternion.Dot(m_orientation, targetOrientation), -1, 1));

            // Normalize angle
            angleDifference = angleDifference > MathHelper.PiOver2 ? MathHelper.Pi - angleDifference : angleDifference;

            // Compute spring physics
            float angleForce = -AngleSpring.Stiffness * angleDifference - AngleSpring.Damping * m_angleVelocity;

            m_angleVelocity += angleForce / AngleSpring.Mass * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            if (angleDifference > 0)
            {
                float factor = Math.Abs(m_angleVelocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS / angleDifference);
                if (angleDifference > MathHelper.PiOver4)
                {
                    factor = Math.Max(factor, 1.0f - MathHelper.PiOver4 / angleDifference);
                }
                factor              = MathHelper.Clamp(factor, 0, 1);
                m_orientation       = Quaternion.Slerp(m_orientation, targetOrientation, factor);
                m_orientationMatrix = Matrix.CreateFromQuaternion(m_orientation);
            }

            if ((m_position - m_desiredPosition).LengthSquared() > MAX_DISTANCE * MAX_DISTANCE)
            {
                RecalibrateCameraPosition();
            }

            if (m_saveSettings)
            {
                MySession.Static.SaveControlledEntityCameraSettings(false);
                m_saveSettings = false;
            }

            ++m_updateCount;
        }
        // Updates spectator position (spring connected to desired position)
        public override void UpdateAfterSimulation()
        {
            IMyControllableEntity genericControlledEntity = MySession.Static.ControlledEntity;

            if (genericControlledEntity == null)
            {
                return;
            }

            if (genericControlledEntity != m_lastControllerEntity)
            {
                m_disableSpringThisFrame = true;
                m_lastControllerEntity   = genericControlledEntity;
            }

            // ----------- gather viewer position and target ------------------
            var remotelyControlledEntity = genericControlledEntity as MyRemoteControl;
            var controlledEntity         = remotelyControlledEntity != null ? remotelyControlledEntity.Pilot : genericControlledEntity.Entity;

            while (controlledEntity.Parent is MyCockpit)
            {
                controlledEntity = controlledEntity.Parent;
            }
            if (controlledEntity != null && controlledEntity.PositionComp != null)
            {
                var      positionComp = controlledEntity.PositionComp;
                float    localY       = positionComp.LocalAABB.Max.Y - positionComp.LocalAABB.Min.Y;
                Vector3D lastTarget   = m_target;
                var      headMatrix   = remotelyControlledEntity == null?genericControlledEntity.GetHeadMatrix(true) : remotelyControlledEntity.Pilot.GetHeadMatrix(true);

                m_target            = controlledEntity is MyCharacter ? ((positionComp.GetPosition() + (localY + m_lookAtOffsetY) * 1.2f * positionComp.WorldMatrix.Up)) : headMatrix.Translation;
                m_targetOrientation = headMatrix.GetOrientation();
                m_targetUpVec       = m_positionCurrentIsSafe ? (Vector3D)m_targetOrientation.Up : positionComp.WorldMatrix.Up; // this is right and prevents z-rotation if in invalid position (during timeout before switching to 1st person)
                m_transformedLookAt = Vector3D.Transform(m_clampedlookAt, m_targetOrientation);
                m_desiredPosition   = m_target + m_transformedLookAt;

                m_position += m_target - lastTarget; // compensate character movement
            }
            else
            {
                var headMatrix = genericControlledEntity.GetHeadMatrix(true);
                m_target            = headMatrix.Translation;
                m_targetOrientation = headMatrix.GetOrientation();
                m_targetUpVec       = m_targetOrientation.Up;

                m_transformedLookAt = Vector3D.Transform(m_clampedlookAt, m_targetOrientation);
                m_desiredPosition   = m_target + m_transformedLookAt;
                m_position          = m_desiredPosition;
            }

            // --------- camera spring ------------------------
            Vector3D backup_mPosition = m_position;

            if (m_disableSpringThisFrame)
            {
                m_position = m_desiredPosition;
                m_velocity = Vector3.Zero;
            }
            else
            {
                ProcessSpringCalculation();
            }

            // -------- raycast, prevent camera being inside things ------
            if (controlledEntity != null)
            {
                if (!controlledEntity.Closed)
                {
                    HandleIntersection(controlledEntity);
                }
                else
                {
                    m_positionCurrentIsSafe = false;
                }
            }

            // ------- save current settings -------
            if (m_saveSettings)
            {
                MySession.Static.SaveControlledEntityCameraSettings(false);
                m_saveSettings = false;
            }

            // ------- in case spring is disabled - quickly lerp in new desired position ----------------
            if (m_disableSpringThisFrame)
            {
                double smoothCoeff = 0.8;
                m_position = Vector3D.Lerp(backup_mPosition, m_desiredPosition, smoothCoeff);
                m_velocity = Vector3.Zero;
                m_disableSpringThisFrame = Vector3D.DistanceSquared(m_position, m_desiredPosition) >
                                           CAMERA_RADIUS * CAMERA_RADIUS;
            }

            // ------- draw trail if debug draw is enabled --------------------------------------
            DebugDrawTrail();
        }
        // Updates spectator position (spring connected to desired position)
        public override void UpdateAfterSimulation()
        {
            IMyControllableEntity genericControlledEntity = MySession.Static.ControlledEntity;
            if (genericControlledEntity == null)
                return;

            if (genericControlledEntity != m_lastControllerEntity)
            {
                m_disableSpringThisFrame = true;
                m_lastControllerEntity = genericControlledEntity;
            }

            // ----------- gather viewer position and target ------------------
            var remotelyControlledEntity = genericControlledEntity as MyRemoteControl;
            var controlledEntity = remotelyControlledEntity != null ? remotelyControlledEntity.Pilot : genericControlledEntity.Entity;
            while (controlledEntity.Parent is MyCockpit)
            {
                controlledEntity = controlledEntity.Parent;
            }
            if (controlledEntity != null && controlledEntity.PositionComp != null)
            {
                var positionComp = controlledEntity.PositionComp;
                float localY = positionComp.LocalAABB.Max.Y - positionComp.LocalAABB.Min.Y;
                Vector3D lastTarget = m_target;
                var headMatrix = remotelyControlledEntity == null ? genericControlledEntity.GetHeadMatrix(true) : remotelyControlledEntity.Pilot.GetHeadMatrix(true);
                m_target = controlledEntity is MyCharacter ? ((positionComp.GetPosition() + (localY + m_lookAtOffsetY) * 1.2f * positionComp.WorldMatrix.Up)) : headMatrix.Translation;
                m_targetOrientation = headMatrix.GetOrientation();
                m_targetUpVec = m_positionCurrentIsSafe ? (Vector3D)m_targetOrientation.Up : positionComp.WorldMatrix.Up; // this is right and prevents z-rotation if in invalid position (during timeout before switching to 1st person)
                m_transformedLookAt = Vector3D.Transform(m_clampedlookAt, m_targetOrientation);
                m_desiredPosition = m_target + m_transformedLookAt;

                m_position += m_target - lastTarget; // compensate character movement
            }
            else
            {
                var headMatrix = genericControlledEntity.GetHeadMatrix(true);
                m_target = headMatrix.Translation;
                m_targetOrientation = headMatrix.GetOrientation();
                m_targetUpVec = m_targetOrientation.Up;

                m_transformedLookAt = Vector3D.Transform(m_clampedlookAt, m_targetOrientation);
                m_desiredPosition = m_target + m_transformedLookAt;
                m_position = m_desiredPosition;
            }

            // --------- camera spring ------------------------
            Vector3D backup_mPosition = m_position;
            if (m_disableSpringThisFrame)
            {
                m_position = m_desiredPosition;
                m_velocity = Vector3.Zero;
            }
            else
            {
                ProcessSpringCalculation();
            }

            // -------- raycast, prevent camera being inside things ------
            if (controlledEntity != null)
            {
                if (!controlledEntity.Closed)
                {
                    HandleIntersection(controlledEntity);
                }
                else
                {
                    m_positionCurrentIsSafe = false;
                }
            }

            // ------- save current settings -------
            if (m_saveSettings)
            {
                MySession.Static.SaveControlledEntityCameraSettings(false);
                m_saveSettings = false;
            }

            // ------- in case spring is disabled - quickly lerp in new desired position ----------------
            if (m_disableSpringThisFrame)
            {
                double smoothCoeff = 0.8;
                m_position = Vector3D.Lerp(backup_mPosition, m_desiredPosition, smoothCoeff);
                m_velocity = Vector3.Zero;
                m_disableSpringThisFrame = Vector3D.DistanceSquared(m_position, m_desiredPosition) >
                                               CAMERA_RADIUS * CAMERA_RADIUS;
            }

            // ------- draw trail if debug draw is enabled --------------------------------------
            DebugDrawTrail();
        }
Ejemplo n.º 8
0
        /*
         * public override void HandleInput()
         * {
         *  try
         *  {
         *      if (MyAPIGateway.Utilities.IsDedicated || MyAPIGateway.Gui.IsCursorVisible || MyAPIGateway.Gui.ChatEntryVisible)
         *          return;
         *
         *      CamAlignHandler();
         *  }
         *  catch (Exception e)
         *  {
         *      //... hm?
         *  }
         * }
         */

        public void CamAlignHandler()
        {
            try
            {
                if (MyAPIGateway.Input.IsGameControlPressed(MyControlsSpace.LOOKAROUND))
                {
                    if (MyAPIGateway.Input.IsGameControlReleased(MyControlsSpace.CAMERA_MODE))
                    {
                        CameraAutoAlignEnabled = !CameraAutoAlignEnabled;
                        if (CameraAutoAlignEnabled)
                        {
                            MyAPIGateway.Utilities.ShowNotification("Camera auto-align enabled.");
                        }
                        else
                        {
                            MyAPIGateway.Utilities.ShowNotification("Camera auto-align disabled.");
                        }
                    }
                }

                if (!CameraAutoAlignEnabled)
                {
                    alignTick = 60;
                    return;
                }

                var camCtrl    = MyAPIGateway.Session.CameraController;
                var controller = MyAPIGateway.Session.ControlledObject as Sandbox.Game.Entities.IMyControllableEntity; // Avoiding ambiguity.

                if (camCtrl == null || controller == null)
                {
                    return;
                }

                if (isInFirstPersonView != camCtrl.IsInFirstPersonView)
                {
                    isInFirstPersonView = camCtrl.IsInFirstPersonView;
                    alignTick           = 60;
                }

                if (ControlledObject != controller)
                {
                    ControlledObject = controller;
                    alignTick        = 60;
                }

                if (MyAPIGateway.Input.IsNewGameControlPressed(MyControlsSpace.LOOKAROUND))
                {
                    alignTick = -1;
                }
                else if (MyAPIGateway.Input.IsGameControlReleased(MyControlsSpace.LOOKAROUND))
                {
                    alignTick = 0;
                }

                if (alignTick != -1)
                {
                    alignTick++;

                    if (alignTick > alignAfter)
                    {
                        alignTick = -1;

                        // Slight change, only allow auto-align on cockpits and characters thrid person.
                        if (controller is IMyRemoteControl)
                        {
                            /*
                             * if (RefController == null)
                             *  return;
                             *
                             * var shipController = controller as IMyShipController;
                             * if (shipController.GetShipSpeed() < 0.1)
                             * {
                             *  alignTick = 0;
                             *  return;
                             * }
                             *
                             * MyAPIGateway.Utilities.ShowNotification("LULZ");
                             * // HACK this is how MyCockpit.Rotate() does things so I kinda have to use these magic numbers.
                             * var num = MyAPIGateway.Input.GetMouseSensitivity() * 0.13f;
                             *
                             * if (camCtrl.IsInFirstPersonView)
                             *  camCtrl.Rotate(new Vector2(RefController.HeadLocalXAngle / num, RefController.HeadLocalYAngle / num), 0);
                             * else
                             *  camCtrl.Rotate(new Vector2((RefController.HeadLocalXAngle + shipCamHeightOffset) / num, (RefController.HeadLocalYAngle) / num), 0);
                             */
                        }
                        else if (controller is IMyShipController)
                        {
                            //RefController = controller;

                            var shipController = controller as IMyShipController;

                            if (!shipController.CanControlShip)
                            {
                                alignTick = -1;
                                return;
                            }

                            if (shipController.GetShipSpeed() < 0.1)
                            {
                                alignTick = 0;
                                return;
                            }

                            // HACK this is how MyCockpit.Rotate() does things so I kinda have to use these magic numbers.
                            var num = MyAPIGateway.Input.GetMouseSensitivity() * 0.13f;

                            if (camCtrl.IsInFirstPersonView)
                            {
                                camCtrl.Rotate(new Vector2(controller.HeadLocalXAngle / num, controller.HeadLocalYAngle / num), 0);
                            }
                            else
                            {
                                camCtrl.Rotate(new Vector2((controller.HeadLocalXAngle + shipCamHeightOffset) / num, (controller.HeadLocalYAngle) / num), 0);
                            }
                        }
                        else if (controller is IMyCharacter)
                        {
                            var playerChar = controller as IMyCharacter;
                            if (playerChar.Physics.Speed < 0.1)
                            {
                                alignTick = 0;
                                return;
                            }

                            // HACK this is how MyCharacter.RotateHead() does things so I kinda have to use these magic numbers.
                            if (!camCtrl.IsInFirstPersonView)
                            {
                                camCtrl.Rotate(new Vector2(controller.HeadLocalXAngle * 2, controller.HeadLocalYAngle * 2), 0);
                            }
                        }
                        else
                        {
                            /*
                             * // HACK this is how MyCharacter.RotateHead() does things so I kinda have to use these magic numbers.
                             * if (!camCtrl.IsInFirstPersonView)
                             *  camCtrl.Rotate(new Vector2(controller.HeadLocalXAngle * 2, controller.HeadLocalYAngle * 2), 0);
                             */
                        }
                    }
                }
            }
            catch (Exception e)
            {
                //MyAPIGateway.Utilities.ShowNotification("NOPE\n" + e.ToString(), 16);
                // I should log. A proper log. Oh well...
            }
        }
        // Updates spectator position (spring connected to desired position)
        public override void UpdateAfterSimulation()
        {
            Sandbox.Game.Entities.IMyControllableEntity genericControlledEntity = MySession.Static.ControlledEntity as Sandbox.Game.Entities.IMyControllableEntity;
            if (genericControlledEntity == null)
            {
                return;
            }
            var remotelyControlledEntity = genericControlledEntity as MyRemoteControl;
            var controlledEntity         = remotelyControlledEntity != null ? remotelyControlledEntity.Pilot : genericControlledEntity.Entity;

            if (controlledEntity != null && controlledEntity.PositionComp != null)
            {
                var      positionComp = controlledEntity.PositionComp;
                float    localY       = positionComp.LocalAABB.Max.Y - positionComp.LocalAABB.Min.Y;
                Vector3D lastTarget   = m_target;
                var      headMatrix   = remotelyControlledEntity == null?genericControlledEntity.GetHeadMatrix(true) : remotelyControlledEntity.Pilot.GetHeadMatrix(true);

                m_target            = controlledEntity is MyCharacter ? ((positionComp.GetPosition() + (localY + LOOK_AT_OFFSET_Y) * positionComp.WorldMatrix.Up)) : headMatrix.Translation;
                m_targetOrientation = headMatrix.GetOrientation();
                m_targetUpVec       = m_positionCurrentIsSafe ? (Vector3D)m_targetOrientation.Up : positionComp.WorldMatrix.Up;
                m_transformedLookAt = Vector3D.Transform(m_lookAt, m_targetOrientation);
                m_desiredPosition   = m_target + m_transformedLookAt;

                m_position += m_target - lastTarget; // compensate character movement

                //m_position = m_desiredPosition;
            }
            else
            {
                var headMatrix = genericControlledEntity.GetHeadMatrix(true);
                m_target            = headMatrix.Translation;
                m_targetOrientation = headMatrix.GetOrientation();
                m_targetUpVec       = m_targetOrientation.Up;

                m_transformedLookAt = Vector3D.Transform(m_lookAt, m_targetOrientation);
                m_desiredPosition   = m_target + m_transformedLookAt;
                m_position          = m_desiredPosition;
            }

            Vector3D stretch = m_position - m_desiredPosition;

            Vector3D force = -m_currentSpring.Stiffness * stretch - m_currentSpring.Dampening * m_velocity;

            force.AssertIsValid();

            // Apply acceleration
            Vector3 acceleration = (Vector3)force / m_currentSpring.Mass;

            m_velocity += acceleration * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            m_velocity.AssertIsValid();

            // Apply velocity
            m_position += m_velocity * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS;
            m_position.AssertIsValid();

            // Limit backward distance from target
            double backward = Vector3D.Dot((Vector3D)m_targetOrientation.Backward, (m_target - m_position));

            if (backward > -BACKWARD_CUTOFF)
            {
                m_position += (Vector3D)m_targetOrientation.Backward * (backward + BACKWARD_CUTOFF);
            }

            // -------- raycast, prevent camera being inside things ------
            if (controlledEntity != null)
            {
                if (!controlledEntity.Closed)
                {
                    HandleIntersection(controlledEntity);
                }
                else
                {
                    m_positionCurrentIsSafe = false;
                }
            }

            // ------- save current settings -------
            if (m_saveSettings)
            {
                MySession.Static.SaveControlledEntityCameraSettings(false);
                m_saveSettings = false;
            }
            ++m_updateCount;
        }
Ejemplo n.º 10
0
 public override UseActionResult CanUse(UseActionEnum actionEnum, Sandbox.Game.Entities.IMyControllableEntity user) =>
 (base.IsFunctional ? (base.IsWorking ? ((base.m_pilot == null) ? base.CanUse(actionEnum, user) : UseActionResult.UsedBySomeoneElse) : UseActionResult.Unpowered) : UseActionResult.CockpitDamaged);