public void MoveAndRotate(Vector3 moveIndicator, Vector3 rotationIndicator, MyCharacterMovementFlags movementFlags) { bool changed = CachedMovementState.MoveIndicator != moveIndicator || CachedMovementState.RotationIndicator != rotationIndicator || CachedMovementState.MovementFlags != movementFlags; if (MyMultiplayer.Static != null && MyMultiplayer.Static.FrameCounter - m_lastUpdateFrame > 60) { //Send input even if nothing changed, because clients can be moved by other forces and we need to sync them somehow at low framerate ResetUpdateTimer(); changed = true; } if (changed) { CharacterInputMsg msg = new CharacterInputMsg(); msg.CharacterEntityId = Entity.EntityId; msg.MoveIndicator = moveIndicator; msg.RotationIndicator = rotationIndicator; msg.MovementFlags = movementFlags; msg.Orientation = Quaternion.CreateFromRotationMatrix(Entity.WorldMatrix); msg.Position = Entity.WorldMatrix.Translation; CachedMovementState = msg; if (!Sync.IsServer) { Sync.Layer.SendMessageToServer(ref msg); } else { Sync.Layer.SendMessageToAll(ref msg); } } }
public void MoveAndRotate(Vector3 moveIndicator, Vector3 rotationIndicator, MyCharacterMovementFlags movementFlags) { bool changed = CachedMovementState.MoveIndicator != moveIndicator || CachedMovementState.RotationIndicator != rotationIndicator || CachedMovementState.MovementFlags != movementFlags; if (changed) { CharacterInputMsg msg = new CharacterInputMsg(); msg.CharacterEntityId = Entity.EntityId; msg.MoveIndicator = moveIndicator; msg.RotationIndicator = rotationIndicator; msg.MovementFlags = movementFlags; msg.Orientation = Quaternion.CreateFromRotationMatrix(Entity.WorldMatrix); msg.Position = Entity.WorldMatrix.Translation; CachedMovementState = msg; if (!Sync.IsServer) { Sync.Layer.SendMessageToServer(ref msg); } else { Sync.Layer.SendMessageToAll(ref msg); } } }
public MyCharacterNetState(BitStream stream) { HeadX = stream.ReadHalf(); if (HeadX.IsValid() == false) { HeadX = 0.0f; } HeadY = stream.ReadHalf(); MovementState = (MyCharacterMovementEnum)stream.ReadUInt16(); MovementFlags = (MyCharacterMovementFlags)stream.ReadUInt16(); Jetpack = stream.ReadBool(); Dampeners = stream.ReadBool(); TargetFromCamera = stream.ReadBool(); MoveIndicator = stream.ReadNormalizedSignedVector3(8); Rotation = stream.ReadQuaternion(); Valid = true; }
public void UpdateMovementAndFlags(MyCharacterMovementEnum movementState, MyCharacterMovementFlags flags) { if (m_currentMovementState != movementState && Physics != null) { this.m_movementFlags = flags; this.SwitchAnimation(movementState); this.SetCurrentMovementState(movementState); } }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); System.Diagnostics.Debug.Assert(MySession.Static != null); if (MySession.Static == null) return; // Persist current movement flags before UpdateAfterSimulation() // to safely send the client state at a later stage m_previousMovementFlags = m_movementFlags; m_previousNetworkMovementState = GetCurrentMovementState(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Update zero movement"); UpdateZeroMovement(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (m_cachedCommands != null) { if (IsUsing != null) { m_cachedCommands.Clear(); } foreach (var command in m_cachedCommands) { if (command.ExecuteBeforeMoveAndRotate) { command.Apply(); } } } if(ControllerInfo.IsLocallyControlled() || (IsUsing == null && (m_cachedCommands != null && m_cachedCommands.Count == 0))) { MoveAndRotateInternal(MoveIndicator, RotationIndicator, RollIndicator, RotationCenterIndicator); } if (m_cachedCommands != null) { if (IsUsing != null || IsDead) { m_cachedCommands.Clear(); } foreach (var command in m_cachedCommands) { if (command.ExecuteBeforeMoveAndRotate == false) { command.Apply(); } } m_cachedCommands.Clear(); } m_moveAndRotateCalled = false; m_actualUpdateFrame++; m_isInFirstPerson = (MySession.Static.CameraController == this) && IsInFirstPersonView; if (m_wasInFirstPerson != m_isInFirstPerson && m_currentMovementState != MyCharacterMovementEnum.Sitting) { MySector.MainCamera.Zoom.ApplyToFov = m_isInFirstPerson; if (!ForceFirstPersonCamera) { UpdateNearFlag(); } } m_wasInFirstPerson = m_isInFirstPerson; UpdateLightPower(); SoundComp.FindAndPlayStateSound(); SoundComp.UpdateWindSounds(); if (!IsDead && m_currentMovementState != MyCharacterMovementEnum.Sitting) { if (!MySandboxGame.IsPaused)//this update is called even in pause (jetpack, model update) { if (Physics.CharacterProxy != null) { Physics.CharacterProxy.StepSimulation(VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } } } m_currentAnimationChangeDelay += VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; if (Sync.IsServer && !IsDead && !MyEntities.IsInsideWorld(PositionComp.GetPosition())) { if (MySession.Static.SurvivalMode) DoDamage(1000, MyDamageType.Suicide, true, EntityId); } foreach (var component in Components) { var characterComponent = component as MyCharacterComponent; if (characterComponent != null && characterComponent.NeedsUpdateBeforeSimulation) { characterComponent.UpdateBeforeSimulation(); } } var jetpack = JetpackComp; if (jetpack != null && (ControllerInfo.IsLocallyControlled() || Sync.IsServer)) jetpack.UpdateBeforeSimulation(); if (MyInput.Static.IsNewGameControlReleased(Sandbox.Game.MyControlsSpace.LOOKAROUND) && MySandboxGame.Config.ReleasingAltResetsCamera) { // set rotation to 0... animated over 0.3 sec SetLocalHeadAnimation(0, 0, 0.3f); } if (m_canPlayImpact > 0f) m_canPlayImpact -= MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; }
protected override void ServerRead(VRage.Library.Collections.BitStream stream, ulong clientId, uint timestamp) { base.ServerRead(stream, clientId, timestamp); if (m_character != null) { 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(); Quaternion rotation = Quaternion.Identity; if (Jetpack == false) { rotation = stream.ReadQuaternionNorm(); } if (m_character.IsDead || 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; m_character.SetCurrentMovementState(MovementState); m_character.HeadLocalXAngle = headXAngle; m_character.HeadLocalYAngle = headYAngle; m_character.CacheMove(ref move, ref rotate, ref roll); if (Jetpack == false) { m_character.CacheRotation(ref rotation); } } }
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); } }
public void MoveAndRotate(Vector3 moveIndicator, Vector3 rotationIndicator, MyCharacterMovementFlags movementFlags) { bool changed = CachedMovementState.MoveIndicator != moveIndicator || CachedMovementState.RotationIndicator != rotationIndicator || CachedMovementState.MovementFlags != movementFlags; if (changed) { CharacterInputMsg msg = new CharacterInputMsg(); msg.CharacterEntityId = Entity.EntityId; msg.MoveIndicator = moveIndicator; msg.RotationIndicator = rotationIndicator; msg.MovementFlags = movementFlags; msg.Orientation = Quaternion.CreateFromRotationMatrix(Entity.WorldMatrix); msg.Position = Entity.WorldMatrix.Translation; CachedMovementState = msg; if (!Sync.IsServer) Sync.Layer.SendMessageToServer(ref msg); else Sync.Layer.SendMessageToAll(ref msg); } }
public unsafe void MoveAndRotate(ref Vector3 moveIndicator, ref Vector2 rotationIndicator, float roll, bool canRotate) { MyCharacterProxy characterProxy = base.Character.Physics.CharacterProxy; this.ThrustComp.ControlThrust = Vector3.Zero; base.Character.SwitchAnimation(MyCharacterMovementEnum.Flying, true); base.Character.SetCurrentMovementState(MyCharacterMovementEnum.Flying); MyCharacterMovementFlags movementFlags = base.Character.MovementFlags; MyCharacterMovementFlags flags2 = base.Character.MovementFlags; this.IsFlying = !(moveIndicator.LengthSquared() == 0f); HkCharacterStateType type = (characterProxy != null) ? characterProxy.GetState() : HkCharacterStateType.HK_CHARACTER_ON_GROUND; if ((type == HkCharacterStateType.HK_CHARACTER_IN_AIR) || (type == ((HkCharacterStateType)5))) { base.Character.PlayCharacterAnimation("Jetpack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f, 1f, false, null, false); base.Character.CanJump = true; } MatrixD worldMatrix = base.Character.WorldMatrix; if (canRotate) { MatrixD identity = MatrixD.Identity; MatrixD xd3 = MatrixD.Identity; MatrixD xd4 = MatrixD.Identity; if (Math.Abs(rotationIndicator.X) > float.Epsilon) { if (base.Character.Definition.VerticalPositionFlyingOnly) { base.Character.SetHeadLocalXAngle(base.Character.HeadLocalXAngle - (rotationIndicator.X * base.Character.RotationSpeed)); } else { identity = MatrixD.CreateFromAxisAngle(worldMatrix.Right, (double)((-rotationIndicator.X * base.Character.RotationSpeed) * 0.02f)); } } if (Math.Abs(rotationIndicator.Y) > float.Epsilon) { xd3 = MatrixD.CreateFromAxisAngle(worldMatrix.Up, (double)((-rotationIndicator.Y * base.Character.RotationSpeed) * 0.02f)); } if (!base.Character.Definition.VerticalPositionFlyingOnly && (Math.Abs(roll) > float.Epsilon)) { xd4 = MatrixD.CreateFromAxisAngle(worldMatrix.Forward, (double)(roll * 0.02f)); } float y = base.Character.ModelCollision.BoundingBoxSizeHalf.Y; MatrixD xd7 = worldMatrix.GetOrientation() * ((identity * xd3) * xd4); MatrixD *xdPtr1 = (MatrixD *)ref xd7; xdPtr1.Translation = (base.Character.Physics.GetWorldMatrix().Translation + (worldMatrix.Up * y)) - (xd7.Up * y); base.Character.WorldMatrix = xd7; base.Character.ClearShapeContactPoints(); } Vector3 position = moveIndicator; if (base.Character.Definition.VerticalPositionFlyingOnly) { float num2 = Math.Sign(base.Character.HeadLocalXAngle); double x = Math.Abs(MathHelper.ToRadians(base.Character.HeadLocalXAngle)); double y = 1.95; double num5 = Math.Pow(x, y) * (x / Math.Pow((double)MathHelper.ToRadians((float)89f), y)); position = (Vector3)Vector3D.Transform(position, MatrixD.CreateFromAxisAngle(Vector3D.Right, num2 * num5)); } if (!Vector3.IsZero(position)) { position.Normalize(); } MyJetpackThrustComponent thrustComp = this.ThrustComp; thrustComp.ControlThrust += position * this.ForceMagnitude; }
public void SetStateFromNetwork(ref MyCharacterNetState newStateFromNet) { if (IsDead) return; m_worldRealVelocity = newStateFromNet.WorldRealSpeed; SetHeadLocalXAngle(newStateFromNet.HeadX); SetHeadLocalYAngle(newStateFromNet.HeadY); if (newStateFromNet.Spine != Quaternion.Zero) SetSpineAdditionalRotation(newStateFromNet.Spine, newStateFromNet.Spine, false); SetHeadAdditionalRotation(newStateFromNet.Head, false); var jetpack = JetpackComp; if (jetpack != null) { if (newStateFromNet.Jetpack != JetpackComp.TurnedOn) { jetpack.TurnOnJetpack(newStateFromNet.Jetpack, false, false); } if (newStateFromNet.Dampeners != JetpackComp.DampenersTurnedOn) { jetpack.EnableDampeners(newStateFromNet.Dampeners, false); } } if (newStateFromNet.Lights != LightEnabled) { EnableLights(newStateFromNet.Lights); } if (newStateFromNet.Ironsight != (m_zoomMode == MyZoomModeEnum.IronSight)) { EnableIronsight(newStateFromNet.Ironsight, true, false); } if (RadioBroadcaster != null && newStateFromNet.Broadcast != RadioBroadcaster.Enabled) { EnableBroadcasting(newStateFromNet.Broadcast); } TargetFromCamera = newStateFromNet.TargetFromCamera; if (MyFakes.CHARACTER_SERVER_SYNC) { RotationIndicator = newStateFromNet.Rotation; RollIndicator = newStateFromNet.Roll; } // do it fast, dont wait for update, no time. if (GetCurrentMovementState() != newStateFromNet.MovementState && Physics != null) { this.m_movementFlags = newStateFromNet.MovementFlag; if (newStateFromNet.MovementState == MyCharacterMovementEnum.Jump) { // Simulate one frame for jump action to be triggered this.Jump(); this.MoveAndRotateInternal(MoveIndicator, RotationIndicator, RollIndicator); } this.SwitchAnimation(newStateFromNet.MovementState); this.SetCurrentMovementState(newStateFromNet.MovementState); } }
public void MoveAndRotate(Vector3 moveIndicator, Vector3 rotationIndicator, MyCharacterMovementFlags movementFlags) { bool changed = CachedMovementState.MoveIndicator != moveIndicator || CachedMovementState.RotationIndicator != rotationIndicator || CachedMovementState.MovementFlags != movementFlags; if (MyMultiplayer.Static != null && MyMultiplayer.Static.FrameCounter - m_lastUpdateFrame > 60) { //Send input even if nothing changed, because clients can be moved by other forces and we need to sync them somehow at low framerate ResetUpdateTimer(); changed = true; } if (changed) { CharacterInputMsg msg = new CharacterInputMsg(); msg.CharacterEntityId = Entity.EntityId; msg.MoveIndicator = moveIndicator; msg.RotationIndicator = rotationIndicator; msg.MovementFlags = movementFlags; msg.Orientation = Quaternion.CreateFromRotationMatrix(Entity.WorldMatrix); msg.Position = Entity.WorldMatrix.Translation; CachedMovementState = msg; if (!Sync.IsServer) Sync.Layer.SendMessageToServer(ref msg); else Sync.Layer.SendMessageToAll(ref msg); } }