public override void ClientUpdate(uint timestamp)
        {
            base.ClientUpdate(timestamp);

            if (MySession.Static.ControlledEntity != m_character)
            {
                if (m_supportTimeStamp != null)
                {
                    m_supportTimeStamp.Clear();
                }
                return;
            }

            MyEntity support = MySupportHelper.FindSupportForCharacterAABB(m_character);

            if (support != null)
            {
                if (m_supportTimeStamp == null)
                {
                    m_supportTimeStamp = new MyTimestampHelper(null);
                }

                m_supportTimeStamp.SetEntity(support);
                m_supportTimeStamp.Update(timestamp);
            }
            else
            {
                if (m_supportTimeStamp != null)
                {
                    m_supportTimeStamp.Clear();
                }
            }
        }
        protected override void CustomServerWrite(uint timeStamp, ulong clientId, VRage.Library.Collections.BitStream stream)
        {
            MyEntity support = MySupportHelper.FindSupportForCharacterAABB(m_character);

            stream.WriteBool(support != null);
            if (support != null)
            {
                stream.WriteInt64(support.EntityId);
                stream.Write(support.PositionComp.GetPosition());
            }
        }
Ejemplo n.º 3
0
        protected override void ServerRead(VRage.Library.Collections.BitStream stream, ulong clientId, uint timestamp)
        {
            base.ServerRead(stream, clientId, timestamp);
            bool clientHasCharacter = stream.ReadBool();

            if (clientHasCharacter)
            {
                MyEntity support;
                bool     hasSupport      = stream.ReadBool();
                Vector3D supportPosition = Vector3D.Zero;

                if (m_character != null)
                {
                    var physGroup = MyExternalReplicable.FindByObject(m_character).FindStateGroup <MyCharacterPhysicsStateGroup>();
                    if (physGroup != null)
                    {
                        m_support = MySupportHelper.FindSupportForCharacterAABB(m_character);
                        physGroup.SetSupport(MySupportHelper.FindPhysics(m_support));
                    }
                }

                if (hasSupport)
                {
                    long supportId = stream.ReadInt64();
                    bool apply     = MyEntities.TryGetEntityById(supportId, out support);
                    supportPosition = stream.ReadVector3D();
                }


                if (m_additionalServerClientData == null)
                {
                    m_additionalServerClientData = new Dictionary <ulong, ClientData>();
                }

                m_additionalServerClientData[clientId] = new ClientData()
                {
                    HasSupport = hasSupport, SupportPosition = supportPosition
                };

                Vector3 move = new Vector3();
                move.X = stream.ReadHalf();
                move.Y = stream.ReadHalf();
                move.Z = stream.ReadHalf();

                Vector2 rotate = new Vector2();
                rotate.X = stream.ReadFloat();
                rotate.Y = stream.ReadFloat();

                float roll = stream.ReadFloat();

                MyCharacterMovementEnum  MovementState = (MyCharacterMovementEnum)stream.ReadUInt16();
                MyCharacterMovementFlags MovementFlag  = (MyCharacterMovementFlags)stream.ReadUInt16();

                bool  Jetpack          = stream.ReadBool();
                bool  Dampeners        = stream.ReadBool();
                bool  Lights           = stream.ReadBool(); // TODO: Remove
                bool  Ironsight        = stream.ReadBool();
                bool  Broadcast        = stream.ReadBool(); // TODO: Remove
                bool  TargetFromCamera = stream.ReadBool();
                float headXAngle       = stream.ReadFloat();
                float headYAngle       = stream.ReadFloat();

                if (m_character == null)
                {
                    return;
                }

                if (m_character.IsUsing != null)
                {
                    return;
                }

                var jetpack = m_character.JetpackComp;
                if (jetpack != null)
                {
                    if (Jetpack != jetpack.TurnedOn)
                    {
                        jetpack.TurnOnJetpack(Jetpack, true);
                    }
                    if (Dampeners != jetpack.DampenersTurnedOn)
                    {
                        jetpack.EnableDampeners(Dampeners, false);
                    }
                }

                if (Lights != m_character.LightEnabled)
                {
                    m_character.EnableLights(Lights);
                }

                if (m_character.RadioBroadcaster != null && Broadcast != m_character.RadioBroadcaster.Enabled)
                {
                    m_character.EnableBroadcasting(Broadcast);
                }

                m_character.TargetFromCamera = TargetFromCamera;

                // Set client movement state directly and don't perform other operations
                // that may have side-effects to let server side Character.UpdateAfterSimulation()
                // perform exactly same operations as on client
                m_character.MovementFlags = MovementFlag;
                if (m_character.IsDead == false)
                {
                    m_character.SetCurrentMovementState(MovementState);
                }
                m_character.HeadLocalXAngle = headXAngle;
                m_character.HeadLocalYAngle = headYAngle;
                if (m_commandsApplied == null)
                {
                    m_commandsApplied = new Dictionary <ulong, bool>();
                }

                if (Vector3.IsZero(move, 0.01f) == false || Vector2.IsZero(ref rotate, 0.01f) == false || Math.Abs(roll - 0.0) > 0.01f)
                {
                    m_commandsApplied[clientId] = true;
                }

                m_character.CacheMove(ref move, ref rotate, ref roll);
            }
        }
        protected override void CalculatePositionDifference(ulong clientId, out bool isValid, out bool correctServer, out Vector3D delta)
        {
            delta         = Vector3D.Zero;
            isValid       = true;
            correctServer = false;

            ClientData clientData  = m_additionalServerClientData[clientId];
            MatrixD    worldMatrix = Entity.PositionComp.WorldMatrix;

            float maxCharacterSpeedRelativeToShip = Math.Max(m_character.Definition.MaxSprintSpeed, Math.Max(m_character.Definition.MaxRunSpeed, m_character.Definition.MaxBackrunSpeed));
            float maxSpeed = 1.04f * (MyGridPhysics.ShipMaxLinearVelocity() + maxCharacterSpeedRelativeToShip);

            if (m_haveJetpack == false)
            {
                maxSpeed = 1.04f * maxCharacterSpeedRelativeToShip;
            }

            float maxMoveDistance = (float)((maxSpeed * maxSpeed) / (60f * 60f));

            if (clientData.HasSupport)
            {
                MyEntity support = MySupportHelper.FindSupportForCharacterAABB(m_character);
                if (support != null)
                {
                    Vector3D characterDelta = m_serverClientData[clientId].Transform.Position - m_character.PositionComp.GetPosition();
                    Vector3D supportDelta   = clientData.SupportPosition - support.PositionComp.GetPosition();
                    delta = characterDelta - supportDelta;
                }
                else
                {
                    isValid = false;
                }
            }
            else
            {
                correctServer = true;
                delta         = m_serverClientData[clientId].Transform.Position - worldMatrix.Translation;
                return;
            }

            double deltaL = delta.LengthSquared();

            if (deltaL > 1.3f * (maxMoveDistance + 0.0001))
            {
                isValid       = true;
                correctServer = true;
                //  delta = Vector3D.Zero;
            }
            else if (deltaL > 0.05 * 0.05)
            {
                if (m_commandsApplied.ContainsKey(clientId) == false || m_commandsApplied[clientId] == false)
                {
                    isValid = false;
                    delta   = Vector3D.Zero;
                }
                else
                {
                    correctServer = true;
                }
            }
            m_commandsApplied[clientId] = false;
        }