private void UpdateAnimationNewSystem() { var variableStorage = AnimationController.Variables; // character speed if (Physics != null && Physics.CharacterProxy != null) { Vector3 localSpeedWorldRotUnfiltered = (Physics.CharacterProxy.LinearVelocity - Physics.CharacterProxy.CharacterRigidBody.GroundVelocity) / Sync.RelativeSimulationRatio; var localSpeedWorldRot = FilterLocalSpeed(localSpeedWorldRotUnfiltered); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeed, localSpeedWorldRot.Length()); float localSpeedX = localSpeedWorldRot.Dot(PositionComp.WorldMatrix.Right); float localSpeedY = localSpeedWorldRot.Dot(PositionComp.WorldMatrix.Up); float localSpeedZ = localSpeedWorldRot.Dot(PositionComp.WorldMatrix.Forward); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedX, localSpeedX); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedY, localSpeedY); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedZ, localSpeedZ); const float speedThreshold2 = 0.1f * 0.1f; float speedangle = localSpeedWorldRot.LengthSquared() > speedThreshold2 ? (float)(-Math.Atan2(localSpeedZ, localSpeedX) * 180.0f / Math.PI) + 90.0f : 0.0f; while (speedangle < 0.0f) { speedangle += 360.0f; } variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedAngle, speedangle); if (ControllerInfo.IsLocallyControlled()) { m_animTurningSpeed.Value = RotationIndicator.Y * 180.0f / (float)Math.PI; } variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdTurningSpeed, m_animTurningSpeed); if (OxygenComponent != null) { variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdHelmetOpen, OxygenComponent.HelmetEnabled ? 0.0f : 1.0f); } if (Parent is MyCockpit) { variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdLean, 0); } else { variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdLean, m_animLeaning); } } if (JetpackComp != null) { AnimationController.Variables.SetValue(MyAnimationVariableStorageHints.StrIdFlying, JetpackComp.Running ? 1.0f : 0.0f); } AnimationController.Variables.SetValue(MyAnimationVariableStorageHints.StrIdFalling, GetCurrentMovementState() == MyCharacterMovementEnum.Falling ? 1.0f : 0.0f); MyCharacterMovementEnum movementState = GetCurrentMovementState(); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdFlying, movementState == MyCharacterMovementEnum.Flying ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdFalling, movementState == MyCharacterMovementEnum.Falling ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdCrouch, (WantsCrouch && !WantsSprint) ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSitting, movementState == MyCharacterMovementEnum.Sitting ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdFirstPerson, m_isInFirstPerson ? 1.0f : 0.0f); }
private void characterMovementStateCombo_ItemSelected() { MyCharacter playerCharacter = MySession.LocalCharacter; MyCharacterMovementEnum selected = (MyCharacterMovementEnum)characterMovementStateCombo.GetSelectedKey(); MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_MOVEMENT_STATE = selected; if (!playerCharacter.Definition.FeetIKSettings.TryGetValue(selected, out ikSettings)) { ikSettings = new MyFeetIKSettings(); ikSettings.Enabled = false; ikSettings.AboveReachableDistance = 0.1f; ikSettings.BelowReachableDistance = 0.1f; ikSettings.VerticalShiftDownGain = 0.1f; ikSettings.VerticalShiftUpGain = 0.1f; ikSettings.FootSize = new Vector3(0.1f, 0.1f, 0.2f); } updating = true; enabledIKState.IsChecked = ikSettings.Enabled; belowReachableDistance.Value = ikSettings.BelowReachableDistance; aboveReachableDistance.Value = ikSettings.AboveReachableDistance; verticalChangeUpGain.Value = ikSettings.VerticalShiftUpGain; verticalChangeDownGain.Value = ikSettings.VerticalShiftDownGain; ankleHeight.Value = ikSettings.FootSize.Y; footWidth.Value = ikSettings.FootSize.X; footLength.Value = ikSettings.FootSize.Z; updating = false; }
public void Recalculate(IMyPlayer player) { MyCharacterMovementEnum currMovementState = player.Character.CurrentMovementState; // If character died, then reset stats and skip further calculations, so // they're not potentially negative on re-spawn. if (currMovementState == MyCharacterMovementEnum.Died) { Stamina = 0.5f; // TODO: configurable! prevMovementState = MyCharacterMovementEnum.Died; return; } float staminaDelta; if (prevMovementState != MyCharacterMovementEnum.Jump) { staminaDelta = MovementCosts.Map[currMovementState]; } else { // Character falls soon after jumping; dupe cost on first recalc after that // so the stamina change doesn't look too inconsistent from jump to jump. staminaDelta = MovementCosts.Map[MyCharacterMovementEnum.Jump]; } // DEBUG //var msg = $"{currMovementState} {prevMovementState} {player.Character.Integrity}"; //MyLog.Default.WriteLineAndConsole(msg); //MyAPIGateway.Utilities.ShowNotification(msg, 1000); float gravityInfluence; if (staminaDelta < 0.0f) { // MAGICNUM 0.1f: arbitrary non-negative to limit bonus in low-gravity (TODO: configurable!). gravityInfluence = Math.Max(0.1f, player.Character.Physics.Gravity.Length() / gravityConstant); } else { // MAGICNUM 1.0f: for simplicity, stamina recovery doesn't get affected by gravity. gravityInfluence = 1.0f; } Stamina += staminaDelta * gravityInfluence; // Apply negative stamina as damage, with some scaling. if (Stamina < 0.0f) { // MAGICNUM 5.0f: chosen arbitrarily (TODO: configurable!). player.Character.DoDamage(-Stamina * 5.0f, fatigueDamage, true); } // Clamp stamina between -100% (unattainable enough) and current health. Stamina = Math.Max(-1.0f, Math.Min(Stamina, player.Character.Integrity / 100.0f)); // Update for next time. prevMovementState = currMovementState; }
void MovementStateChanged(MyCharacterMovementEnum oldState, MyCharacterMovementEnum newState) { if (newState == MyCharacterMovementEnum.Died) { Alive = false; } }
public override void OnAddedToContainer() { base.OnAddedToContainer(); m_character = Entity as MyCharacter; foreach (var soundEmitter in m_soundEmitters) { soundEmitter.Entity = Entity as MyEntity; } m_lastUpdateMovementState = m_character.GetCurrentMovementState(); InitSounds(); }
public void ChangeMovementState(MyCharacterMovementEnum state) { if (ResponsibleForUpdate(this)) { var msg = new ChangeMovementStateMsg(); msg.CharacterEntityId = Entity.EntityId; msg.MovementState = state; Sync.Layer.SendMessageToAll(ref msg); } }
private bool CanManipulate(MyCharacterMovementEnum characterMovementState) { if (characterMovementState == MyCharacterMovementEnum.Standing || characterMovementState == MyCharacterMovementEnum.RotatingLeft || characterMovementState == MyCharacterMovementEnum.RotatingRight || characterMovementState == MyCharacterMovementEnum.Crouching || characterMovementState == MyCharacterMovementEnum.Flying) { return(true); } return(false); }
/// <summary> /// Called on <see cref="IMyCharacter.MovementStateChanged" /> event. Used to check if we leave a cockpit. /// </summary> /// <param name="character">The character who triggered this event.</param> /// <param name="oldState">The old movement state.</param> /// <param name="newState">The new movement state.</param> private void OnMovementStateChanged(IMyCharacter character, MyCharacterMovementEnum oldState, MyCharacterMovementEnum newState) { if (Mod.Static.Settings.DisableAutoDampener == DisableAutoDampenerOption.All && (newState == MyCharacterMovementEnum.Sitting || newState == MyCharacterMovementEnum.Died)) { _lastDampenerState = character.EnabledDamping; } _isFlying = newState == MyCharacterMovementEnum.Flying; switch (oldState) { case MyCharacterMovementEnum.Ladder: case MyCharacterMovementEnum.LadderOut: case MyCharacterMovementEnum.LadderDown: case MyCharacterMovementEnum.LadderUp: switch (newState) { case MyCharacterMovementEnum.Ladder: case MyCharacterMovementEnum.LadderOut: case MyCharacterMovementEnum.LadderDown: case MyCharacterMovementEnum.LadderUp: break; default: var position = character.GetPosition(); var sphere = character.PositionComp.WorldVolume; var entities = MyAPIGateway.Entities.GetTopMostEntitiesInSphere(ref sphere).OfType <IMyCubeGrid>().ToList(); var cubeGrid = entities.OrderBy(x => Vector3.Distance(x.GetPosition(), position)).FirstOrDefault(); _workQueue.Enqueue(new Work(ToggleJetpackAndDampenersIfNeeded, new ThrusterWorkData(cubeGrid, leavedLadder: oldState == MyCharacterMovementEnum.LadderOut))); break; } break; case MyCharacterMovementEnum.Sitting: _workQueue.Enqueue(new Work(ToggleHelmetIfNeeded)); if (!Mod.Static.RemoveAutomaticJetpackActivation) { var cockpit = MyAPIGateway.Session.ControlledObject as IMyCockpit; if (cockpit == null) { return; } _workQueue.Enqueue(new Work(ToggleJetpackAndDampenersIfNeeded, new ThrusterWorkData(cockpit))); } break; } }
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 override void OnAddedToContainer() { base.OnAddedToContainer(); m_character = Entity as MyCharacter; foreach (var soundEmitter in m_soundEmitters) { soundEmitter.Entity = Entity as MyEntity; } if (m_windEmitter != null) { m_windEmitter.Entity = Entity as MyEntity; } if (m_oxygenEmitter != null) { m_oxygenEmitter.Entity = Entity as MyEntity; } m_lastUpdateMovementState = m_character.GetCurrentMovementState(); m_characterPhysicalMaterial = MyStringHash.GetOrCompute(m_character.Definition.PhysicalMaterial); InitSounds(); }
void ItemChanged(MyGuiControlSlider slider) { if (updating) { return; } ikSettings.Enabled = enabledIKState.IsChecked; ikSettings.BelowReachableDistance = belowReachableDistance.Value; ikSettings.AboveReachableDistance = aboveReachableDistance.Value; ikSettings.VerticalShiftUpGain = verticalChangeUpGain.Value; ikSettings.VerticalShiftDownGain = verticalChangeDownGain.Value; ikSettings.FootSize.Y = ankleHeight.Value; ikSettings.FootSize.X = footWidth.Value; ikSettings.FootSize.Z = footLength.Value; MyCharacter playerCharacter = MySession.LocalCharacter; MyCharacterMovementEnum selected = (MyCharacterMovementEnum)characterMovementStateCombo.GetSelectedKey(); playerCharacter.Definition.FeetIKSettings[selected] = ikSettings; }
private void characterEntity_OnMovementStateChanged(MyCharacterMovementEnum oldState, MyCharacterMovementEnum newState) { if (oldState == MyCharacterMovementEnum.Sitting) { } if ((oldState == MyCharacterMovementEnum.Flying) || (newState == MyCharacterMovementEnum.Flying)) { MyEntityComponentContainer playercontainer = characterEntity.Components; MyCharacterJetpackComponent JetpackComp = playercontainer.Get <MyCharacterJetpackComponent>(); if (JetpackComp != null) { if ((oldState == MyCharacterMovementEnum.Flying) && (newState == MyCharacterMovementEnum.Sitting)) { skipNextActivation = true; } else { if (!MyAPIGateway.Input.IsNewGameControlPressed(MyControlsSpace.THRUSTS)) { if (JetpackComp.TurnedOn) { if (skipNextActivation) { skipNextActivation = false; } else { JetpackComp.TurnOnJetpack(false); //turn the jetpack off } } } } } } }
public void ChangeMovementState(MyCharacterMovementEnum state) { if (ResponsibleForUpdate(this)) { var msg = new ChangeMovementStateMsg(); msg.CharacterEntityId = Entity.EntityId; msg.MovementState = state; Sync.Layer.SendMessageToAll(ref msg); } }
private void IKFeetStepSounds(MyEntity3DSoundEmitter walkEmitter, MySoundPair cueEnum) { var movementState = m_character.GetCurrentMovementState(); if (movementState.GetMode() == MyCharacterMovement.Flying) return; if (movementState.GetSpeed() != m_lastUpdateMovementState.GetSpeed()) { walkEmitter.StopSound(true); m_lastStepTime = 0; } int usedMinimumDelay = int.MaxValue; if (movementState.GetDirection() != MyCharacterMovement.NoDirection) { switch (movementState.GetSpeed()) { case MyCharacterMovement.NormalSpeed: usedMinimumDelay = m_stepMinimumDelayWalk; break; case MyCharacterMovement.Fast: usedMinimumDelay = m_stepMinimumDelayRun; break; case MyCharacterMovement.VeryFast: usedMinimumDelay = m_stepMinimumDelaySprint; break; } } bool minimumDelayExceeded = false; minimumDelayExceeded = (MySandboxGame.TotalGamePlayTimeInMilliseconds - m_lastStepTime) >= usedMinimumDelay; //MyRenderProxy.DebugDrawAABB(m_character.PositionComp.WorldAABB, Color.White); if (minimumDelayExceeded) { int leftAnkleBoneIndex, rightAnkleBoneIndex; MyCharacterBone leftAnkleBone = m_character.AnimationController != null ? m_character.AnimationController.FindBone(m_character.Definition.LeftAnkleBoneName, out leftAnkleBoneIndex) : null; MyCharacterBone rightAnkleBone = m_character.AnimationController != null ? m_character.AnimationController.FindBone(m_character.Definition.RightAnkleBoneName, out rightAnkleBoneIndex) : null; Vector3 posLeftFoot = leftAnkleBone != null ? leftAnkleBone.AbsoluteTransform.Translation : m_character.PositionComp.LocalAABB.Center; Vector3 posRightFoot = rightAnkleBone != null ? rightAnkleBone.AbsoluteTransform.Translation : m_character.PositionComp.LocalAABB.Center; float ankleHeight; MyFeetIKSettings settingsIK; if (m_character.Definition.FeetIKSettings != null && m_character.Definition.FeetIKSettings.TryGetValue(MyCharacterMovementEnum.Standing, out settingsIK)) { ankleHeight = settingsIK.FootSize.Y; } else { ankleHeight = DEFAULT_ANKLE_HEIGHT; } float charSpeed = 0f; if (m_character.AnimationController != null) m_character.AnimationController.Variables.GetValue(MyAnimationVariableStorageHints.StrIdSpeed, out charSpeed); if (posLeftFoot.Y - ankleHeight < m_character.PositionComp.LocalAABB.Min.Y || posRightFoot.Y - ankleHeight < m_character.PositionComp.LocalAABB.Min.Y) { if(charSpeed > 0.05f) walkEmitter.PlaySound(cueEnum); m_lastStepTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; } } m_lastUpdateMovementState = movementState; }
public void UpdateMovementAndFlags(MyCharacterMovementEnum movementState, MyCharacterMovementFlags flags) { if (m_currentMovementState != movementState && Physics != null) { this.m_movementFlags = flags; this.SwitchAnimation(movementState); this.SetCurrentMovementState(movementState); } }
internal void SwitchAnimation(MyCharacterMovementEnum movementState, bool checkState = true) { if (MySandboxGame.IsDedicated && MyPerGameSettings.DisableAnimationsOnDS) return; if (checkState && m_currentMovementState == movementState) return; bool oldIsWalkingState = IsWalkingState(m_currentMovementState); bool newIsWalkingState = IsWalkingState(movementState); if (oldIsWalkingState != newIsWalkingState) { m_currentHandItemWalkingBlend = 0; } switch (movementState) { case MyCharacterMovementEnum.Walking: PlayCharacterAnimation("Walk", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.1f)); break; case MyCharacterMovementEnum.BackWalking: PlayCharacterAnimation("WalkBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.WalkingLeftBack: PlayCharacterAnimation("WalkLeftBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.WalkingRightBack: PlayCharacterAnimation("WalkRightBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.WalkStrafingLeft: PlayCharacterAnimation("StrafeLeft", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.WalkStrafingRight: PlayCharacterAnimation("StrafeRight", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.WalkingLeftFront: PlayCharacterAnimation("WalkLeftFront", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.WalkingRightFront: PlayCharacterAnimation("WalkRightFront", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.Running: PlayCharacterAnimation("Run", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.Backrunning: PlayCharacterAnimation("RunBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RunningLeftBack: PlayCharacterAnimation("RunLeftBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RunningRightBack: PlayCharacterAnimation("RunRightBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RunStrafingLeft: PlayCharacterAnimation("RunLeft", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RunStrafingRight: PlayCharacterAnimation("RunRight", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RunningLeftFront: PlayCharacterAnimation("RunLeftFront", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RunningRightFront: PlayCharacterAnimation("RunRightFront", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchWalking: PlayCharacterAnimation("CrouchWalk", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchWalkingLeftFront: PlayCharacterAnimation("CrouchWalkLeftFront", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchWalkingRightFront: PlayCharacterAnimation("CrouchWalkRightFront", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchBackWalking: PlayCharacterAnimation("CrouchWalkBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchWalkingLeftBack: PlayCharacterAnimation("CrouchWalkLeftBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchWalkingRightBack: PlayCharacterAnimation("CrouchWalkRightBack", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchStrafingLeft: PlayCharacterAnimation("CrouchStrafeLeft", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchStrafingRight: PlayCharacterAnimation("CrouchStrafeRight", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.Sprinting: PlayCharacterAnimation("Sprint", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.1f)); break; case MyCharacterMovementEnum.Standing: PlayCharacterAnimation("Idle", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.Crouching: PlayCharacterAnimation("CrouchIdle", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.1f)); break; case MyCharacterMovementEnum.Flying: PlayCharacterAnimation("Jetpack", AdjustSafeAnimationEnd(MyBlendOption.Immediate), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.0f)); break; //Multiplayer case MyCharacterMovementEnum.Jump: PlayCharacterAnimation("Jump", AdjustSafeAnimationEnd(MyBlendOption.Immediate), MyFrameOption.Default, AdjustSafeAnimationBlend(0.0f), 1.3f); break; case MyCharacterMovementEnum.Falling: PlayCharacterAnimation("FreeFall", AdjustSafeAnimationEnd(MyBlendOption.Immediate), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchRotatingLeft: PlayCharacterAnimation("CrouchLeftTurn", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.CrouchRotatingRight: PlayCharacterAnimation("CrouchRightTurn", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RotatingLeft: PlayCharacterAnimation("StandLeftTurn", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.RotatingRight: PlayCharacterAnimation("StandRightTurn", AdjustSafeAnimationEnd(MyBlendOption.WaitForPreviousEnd), MyFrameOption.Loop, AdjustSafeAnimationBlend(0.2f)); break; case MyCharacterMovementEnum.Died: PlayCharacterAnimation("Died", AdjustSafeAnimationEnd(MyBlendOption.Immediate), MyFrameOption.Default, AdjustSafeAnimationBlend(0.5f)); break; case MyCharacterMovementEnum.Sitting: break; default: System.Diagnostics.Debug.Assert(false, "Unknown movement state"); break; } }
private void updateFoodLogic() { float elapsedMinutes = (float)(mTimer.Elapsed.Seconds / 60); //float CurPlayerHealth = -1f; bool ChangedStance = false; MyObjectBuilder_Character character; MyCharacterMovementEnum curmove = MyCharacterMovementEnum.Sitting; foreach (var player in _players) { if (String.IsNullOrWhiteSpace(player.Controller?.ControlledEntity?.Entity?.DisplayName)) { PlayerData playerData = _playerDataStorage.Retrieve(player); Logging.Instance.WriteLine(playerData.ToString() + "Loaded to Server"); IMyEntity entity = player.Controller.ControlledEntity.Entity; entity = GetCharacterEntity(entity); // //MyAPIGateway.Utilities.ShowMessage("DEBUG", "Character: " + entity.DisplayName); // gets me player name float currentModifier = 1f; float fatigueRate = 0f; bool dead = false; bool forceEating = false; float recycleBonus = 1f; bool fatigueBonus = false; bool hungerBonus = false; bool thirstBonus = false; // if we were under the effects of a bonus, keep it until we no longer are fatigueBonus = playerData.fatigue > Config.MaxValue; thirstBonus = playerData.thirst > Config.MaxValue; hungerBonus = playerData.hunger > Config.MaxValue; if (entity is IMyCharacter) { character = entity.GetObjectBuilder() as MyObjectBuilder_Character; //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState); if (playerData.Entity == null || playerData.Entity.Closed || playerData.Entity.EntityId != entity.EntityId) { bool bReset = false; if (!playerData.loaded) { bReset = true; playerData.loaded = true; } else if ((playerData.Entity != null) && (playerData.Entity != entity)) { bReset = true; } if (bReset) { playerData.hunger = Config.StartingHunger; playerData.thirst = Config.StartingThirst; playerData.fatigue = Config.StartingFatigue; } playerData.Entity = entity; } //MyAPIGateway.Utilities.ShowMessage("DEBUG", "State: " + character.MovementState + ":" + playerData.LastMovement); ChangedStance = playerData.LastMovement != character.MovementState; curmove = character.MovementState; switch (character.MovementState) // this should be all of them.... { case MyCharacterMovementEnum.Sitting: IMyCubeBlock cb = player.Controller.ControlledEntity.Entity as IMyCubeBlock; //cb.DisplayNameText is name of individual block, cb.DefinitionDisplayNameText is name of block type currentModifier = Config.DefaultModifier; fatigueRate = Config.FatigueSitting; // special case: we may be interacting with a bed, a lunchroom seat or treadmill, so let's String seatmodel = cb.DefinitionDisplayNameText.ToLower(); String seatname = cb.DisplayNameText.ToLower(); if (seatmodel.Contains("cryo")) // you're in a cryopd not an oxygen bed { currentModifier = 0.0000125f; fatigueRate = 0.0000125f; } else if (seatmodel.Contains("treadmill")) { currentModifier = RUNNING_MODIFIER; // jog... fatigueRate = FATIGUE_RUNNING / 2.5f; // but pace yourself } else if (seatmodel.Contains("bed") || seatmodel.Contains("bunk")) { currentModifier = DEFAULT_MODIFIER / 2f; // nap time! Needs are reduced. fatigueRate = FATIGUE_SITTING * 3f; // nap time! Rest is greatly sped up. fatigueBonus |= !ChangedStance; // longer nap? OK, allow for extra resting } else if (seatmodel.Contains("toilet") && ChangedStance) { forceEating = true; // also forces defecation, so this makes sense. but use changedstance to do it only once. recycleBonus = 1.5f; } else if (seatname.Contains("noms")) { forceEating = true; // also forces crapping, fortunately the suit takes care of it. Eat continuously while sitting. hungerBonus |= playerData.hunger > Config.MaxValue * 0.99; // get to 100% first, then apply bonus. thirstBonus |= playerData.thirst > Config.MaxValue * 0.99; // get to 100% first, then apply bonus. } break; case MyCharacterMovementEnum.Flying: currentModifier = FLYING_MODIFIER; fatigueRate = FATIGUE_FLYING; // operating a jetpack is surprisingly hard break; case MyCharacterMovementEnum.Falling: currentModifier = FLYING_MODIFIER; fatigueRate = FATIGUE_WALKING; // change nothing for the first iteration (prevents jump exploit) if (!ChangedStance) { fatigueRate = FATIGUE_STANDING; // freefall is actually relaxing when you are used to it. A professional space engineer would be. } break; case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.CrouchRotatingLeft: case MyCharacterMovementEnum.CrouchRotatingRight: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_CROUCHING; break; case MyCharacterMovementEnum.Standing: case MyCharacterMovementEnum.RotatingLeft: case MyCharacterMovementEnum.RotatingRight: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_STANDING; break; case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingLeftBack: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; // doing the duckwalk is more tiring than walking: try it if you don't believe me break; case MyCharacterMovementEnum.Walking: case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.WalkStrafingRight: case MyCharacterMovementEnum.WalkingRightFront: case MyCharacterMovementEnum.WalkingRightBack: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingLeftBack: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_WALKING; break; case MyCharacterMovementEnum.LadderUp: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; break; case MyCharacterMovementEnum.LadderDown: currentModifier = DEFAULT_MODIFIER; fatigueRate = FATIGUE_WALKING; break; case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: currentModifier = RUNNING_MODIFIER; fatigueRate = FATIGUE_RUNNING; break; case MyCharacterMovementEnum.Sprinting: case MyCharacterMovementEnum.Jump: currentModifier = SPRINTING_MODIFIER; fatigueRate = FATIGUE_SPRINTING; break; case MyCharacterMovementEnum.Died: currentModifier = DEFAULT_MODIFIER; // unused, but let's have them fatigueRate = FATIGUE_STANDING; // unused, but let's have them dead = true; // for death recovery logic break; } playerData.LastMovement = character.MovementState; // track delta } else if (playerData.Entity != null || !playerData.Entity.Closed) { entity = playerData.Entity; } // Sanity checks if (hungerBonus) { if (playerData.hunger > Config.MaxValue * FOOD_BONUS) { playerData.hunger = Config.MaxValue * FOOD_BONUS; } } else { if (playerData.hunger > Config.MaxValue) { playerData.hunger = Config.MaxValue; } } if (thirstBonus) { if (playerData.thirst > Config.MaxValue * DRINK_BONUS) { playerData.thirst = Config.MaxValue * DRINK_BONUS; } } else { if (playerData.thirst > Config.MaxValue) { playerData.thirst = Config.MaxValue; } } // Cause needs if (FATIGUE_ENABLED) { playerData.fatigue += (fatigueRate * FOOD_LOGIC_SKIP_TICKS / 60 * 20); // / 15); playerData.fatigue = Math.Max(playerData.fatigue, MIN_VALUE); if (fatigueBonus) { playerData.fatigue = Math.Min(playerData.fatigue, Config.MaxValue * REST_BONUS); } else { playerData.fatigue = Math.Min(playerData.fatigue, Config.MaxValue); } } else { playerData.fatigue = 9001f; } if (playerData.fatigue <= 0) { // fatigue consequences // at 0, start causing extra thirst // at specified, force walk instead of run (unless overriding by sprinting) // at specified, force crouch, and do damage flashes // at specified, breathing reflex / mess with helmet, and do a bit of actual damage (just in case thirst isn't already causing it) // at specified, cause heart attack if (playerData.fatigue <= (0.00f * MIN_VALUE)) { if (EXTRA_THIRST_FROM_FATIGUE > 0) { // positive: pile on to thirst, per second playerData.thirst -= (EXTRA_THIRST_FROM_FATIGUE * FOOD_LOGIC_SKIP_TICKS / 60); } else // negative: multiply modifier { currentModifier *= -EXTRA_THIRST_FROM_FATIGUE; } } if (playerData.fatigue <= (FATIGUE_LEVEL_FORCEWALK * MIN_VALUE)) { // force player to walk if they were running switch (curmove) { case MyCharacterMovementEnum.Sprinting: case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.SwitchWalk(); break; } } if (playerData.fatigue <= (FATIGUE_LEVEL_FORCECROUCH * MIN_VALUE)) { bool iscrouching = false; switch (curmove) { case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingLeftBack: iscrouching = true; break; } if (!iscrouching) { VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.Crouch(); // force player to crouch } } if (playerData.fatigue <= (FATIGUE_LEVEL_HELMET * MIN_VALUE)) { VRage.Game.ModAPI.Interfaces.IMyControllableEntity ce = player.Controller.ControlledEntity.Entity as VRage.Game.ModAPI.Interfaces.IMyControllableEntity; ce.SwitchHelmet(); // force player to switch helmet, panic reaction from trying to catch breath var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(0.001f, MyStringHash.GetOrCompute("Fatigue"), true); // starting to hurt } if (playerData.fatigue <= (FATIGUE_LEVEL_NOHEALING * MIN_VALUE)) { var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(0.001f, MyStringHash.GetOrCompute("Fatigue"), true); // starting to hurt if (IsAutohealingOn) // fatigued? no autohealing, either. { const float HealthTick = 100f / 240f * FOOD_LOGIC_SKIP_TICKS / 60f; destroyable.DoDamage(HealthTick, MyStringHash.GetOrCompute("Testing"), false); } } if (playerData.fatigue <= (FATIGUE_LEVEL_HEARTATTACK * MIN_VALUE)) { var destroyable = entity as IMyDestroyableObject; destroyable.DoDamage(1000f, MyStringHash.GetOrCompute("Fatigue"), true); // sudden, but very avoidable, heart attack ;) } } if (playerData.thirst > MIN_VALUE) { playerData.thirst -= elapsedMinutes * mThirstPerMinute * currentModifier; playerData.thirst = Math.Max(playerData.thirst, MIN_VALUE); } if (playerData.hunger > MIN_VALUE) { playerData.hunger -= elapsedMinutes * mHungerPerMinute * currentModifier; playerData.hunger = Math.Max(playerData.hunger, MIN_VALUE); } // Try to meet needs if (playerData.hunger < (Config.MaxValue * HUNGRY_WHEN) || forceEating) { playerEatSomething(entity, playerData, hungerBonus?Config.MaxValue * 1.25f:Config.MaxValue, recycleBonus); } if (playerData.thirst < (Config.MaxValue * THIRSTY_WHEN) || forceEating) { playerDrinkSomething(entity, playerData, thirstBonus?Config.MaxValue * 1.25f:Config.MaxValue, recycleBonus); } // Cause damage if needs are unmet if (playerData.thirst <= 0) { var destroyable = entity as IMyDestroyableObject; if (DAMAGE_SPEED_THIRST > 0) { destroyable.DoDamage((IsAutohealingOn ? (DAMAGE_SPEED_THIRST + 1f) : DAMAGE_SPEED_THIRST), MyStringHash.GetOrCompute("Thirst"), true); } else { destroyable.DoDamage(((IsAutohealingOn ? (-DAMAGE_SPEED_THIRST + 1f) : -DAMAGE_SPEED_THIRST) + DAMAGE_SPEED_THIRST * playerData.thirst), MyStringHash.GetOrCompute("Thirst"), true); } } if (playerData.hunger <= 0) { var destroyable = entity as IMyDestroyableObject; if (DAMAGE_SPEED_HUNGER > 0) { destroyable.DoDamage((IsAutohealingOn ? (DAMAGE_SPEED_HUNGER + 1f) : DAMAGE_SPEED_HUNGER), MyStringHash.GetOrCompute("Hunger"), true); } else { destroyable.DoDamage(((IsAutohealingOn ? (-DAMAGE_SPEED_HUNGER + 1f) : -DAMAGE_SPEED_HUNGER) + DAMAGE_SPEED_HUNGER * playerData.hunger), MyStringHash.GetOrCompute("Hunger"), true); } } /* * * * character = entity.GetObjectBuilder(false) as MyObjectBuilder_Character; * if (character.Health == null) // ok, so the variable exists, but it's always null for some reason? * CurPlayerHealth = 101f; * else * CurPlayerHealth = (float) (character.Health); * * if (IsAutohealingOn && CurPlayerHealth < 70f) * { * const float HealthTick = 100f / 240f * FOOD_LOGIC_SKIP_TICKS / 60f; * var destroyable = entity as IMyDestroyableObject; * destroyable.DoDamage(HealthTick, MyStringHash.GetOrCompute("Testing"), false); * } */ if (dead && DEATH_RECOVERY > 0.0) { MyInventoryBase inventory = ((MyEntity)entity).GetInventoryBase(); if (playerData.hunger > 0) { inventory.AddItems((MyFixedPoint)((1f / Config.MaxValue) * DEATH_RECOVERY * (playerData.hunger)), new MyObjectBuilder_Ore() { SubtypeName = "Organic" }); } if (playerData.thirst > 0) { inventory.AddItems((MyFixedPoint)((1f / Config.MaxValue) * DEATH_RECOVERY * (playerData.thirst)), new MyObjectBuilder_Ingot() { SubtypeName = "GreyWater" }); } } //Sends data from Server.cs to Client.cs string message = MyAPIGateway.Utilities.SerializeToXML <PlayerData>(playerData); Logging.Instance.WriteLine(("Message sent from Server.cs to Client.cs: " + message)); MyAPIGateway.Multiplayer.SendMessageTo( 1337, Encoding.Unicode.GetBytes(message), player.SteamUserId ); } } // Reinitialize the timer mTimer = new MyGameTimer(); }
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); } } }
public void StartManipulation(MyState state, MyEntity otherEntity, Vector3D hitPosition, ref MatrixD ownerWorldHeadMatrix, bool fromServer = false) { Debug.Assert(m_constraintInitialized == false); // Commenting this out to allow picking up dead bodies and characters if (otherEntity is MyCharacter) { return; } if (Owner == null) { Debug.Assert(!fromServer, "Desync!"); return; } if (otherEntity.Physics == null) { return; } m_otherRigidBody = otherEntity.Physics.RigidBody; m_otherPhysicsBody = otherEntity.Physics; if (otherEntity is MyCharacter) { if (!(otherEntity as MyCharacter).IsDead || !((otherEntity as MyCharacter).Components.Has <MyCharacterRagdollComponent>() && (otherEntity as MyCharacter).Components.Get <MyCharacterRagdollComponent>().IsRagdollActivated)) { Debug.Assert(!fromServer, "Desync!"); return; } m_otherRigidBody = (otherEntity as MyCharacter).Physics.Ragdoll.GetRootRigidBody(); } // else (!otherEntity.Physics.RigidBody.InWorld) // Do we need to check if the body is in the world when this was returned byt RayCast ? Commenting this out for now.. var characterMovementState = Owner.GetCurrentMovementState(); if (!CanManipulate(characterMovementState)) { Debug.Assert(!fromServer, "Desync!"); return; } if (!CanManipulateEntity(otherEntity)) { Debug.Assert(!fromServer, "Desync!"); return; } m_otherRigidBody.Activate(); Vector3D hitUp = Vector3D.Up; Vector3D hitRight; double dot = Vector3D.Dot(ownerWorldHeadMatrix.Forward, hitUp); if (dot == 1 || dot == -1) { hitRight = ownerWorldHeadMatrix.Right; } else { hitRight = Vector3D.Cross(ownerWorldHeadMatrix.Forward, hitUp); hitRight.Normalize(); } Vector3D hitForward = Vector3D.Cross(hitUp, hitRight); hitForward.Normalize(); // Matrix of constraint for other body in world MatrixD otherWorldMatrix = MatrixD.Identity; otherWorldMatrix.Forward = hitForward; otherWorldMatrix.Right = hitRight; otherWorldMatrix.Up = hitUp; otherWorldMatrix.Translation = hitPosition; const float headPivotOffset = 1.5f; MatrixD headPivotWorldMatrix = ownerWorldHeadMatrix; headPivotWorldMatrix.Translation = ownerWorldHeadMatrix.Translation + headPivotOffset * ownerWorldHeadMatrix.Forward; //float distanceToHead = (float)(headPivotWorldMatrix.Translation - otherWorldMatrix.Translation).Length(); //distanceToHead = MathHelper.Clamp(distanceToHead, 0.6f, 2.5f); // Matrix of constraint for other body in local m_otherLocalPivotMatrix = (Matrix)(otherWorldMatrix * otherEntity.PositionComp.WorldMatrixNormalizedInv); m_otherWorldPivotOrigin = otherWorldMatrix.Translation; MatrixD ownerWorldMatrixInverse = MatrixD.Normalize(MatrixD.Invert(ownerWorldHeadMatrix)); m_headLocalPivotMatrix = Matrix.Identity; m_headLocalPivotMatrix.Translation = Vector3D.Transform(headPivotWorldMatrix.Translation, ownerWorldMatrixInverse); HkConstraintData data; if (state == MyState.HOLD) { if (!fromServer) { float mass = 0; if (otherEntity is MyCubeGrid) { var group = MyCubeGridGroups.Static.Physical.GetGroup((otherEntity as MyCubeGrid)); foreach (var node in group.Nodes) { if (node.NodeData.IsStatic) //fixed constraint on part connected to static grid isnt good idea { return; } mass += node.NodeData.Physics.Mass; } mass = GetRealMass(mass); } else if (otherEntity is MyCharacter) { mass = (otherEntity as MyCharacter).Definition.Mass; } else { mass = GetRealMass(m_otherRigidBody.Mass); } // Player can hold large projectile (~222kg) if ((mass > 210) || ((otherEntity is MyCharacter) && (otherEntity.Physics.Mass > 210))) { return; } } if (!CreateOwnerVirtualPhysics()) { return; } if (IsOwnerLocalPlayer()) { var controllingPlayer = Sync.Players.GetControllingPlayer(otherEntity); if (controllingPlayer != null) { RemoveOwnerVirtualPhysics(); return; } if (!(otherEntity is MyCharacter)) // this would cause to start controlling the dead body.. { Sync.Players.TrySetControlledEntity(Owner.ControllerInfo.Controller.Player.Id, otherEntity); } } SetMotionOnClient(otherEntity, HkMotionType.Dynamic); data = CreateFixedConstraintData(ref m_otherLocalPivotMatrix, headPivotOffset); if (otherEntity is MyCharacter) { if (MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { HkMalleableConstraintData mcData = data as HkMalleableConstraintData; mcData.Strength = 0.005f; } else { HkFixedConstraintData fcData = data as HkFixedConstraintData; fcData.MaximumAngularImpulse = 0.0005f; fcData.MaximumLinearImpulse = 0.0005f; fcData.BreachImpulse = 0.0004f; } } } else { if (!CreateOwnerVirtualPhysics()) { return; } data = CreateBallAndSocketConstraintData(ref m_otherLocalPivotMatrix, ref m_headLocalPivotMatrix); if (otherEntity is MyCharacter) { HkMalleableConstraintData mcData = data as HkMalleableConstraintData; mcData.Strength = 0.005f; } } m_otherEntity = otherEntity; m_otherEntity.OnClosing += OtherEntity_OnClosing; //m_otherAngularDamping = m_otherRigidBody.AngularDamping; //m_otherLinearDamping = m_otherRigidBody.LinearDamping; m_otherRestitution = m_otherRigidBody.Restitution; m_otherMaxLinearVelocity = m_otherRigidBody.MaxLinearVelocity; m_otherMaxAngularVelocity = m_otherRigidBody.MaxAngularVelocity; SetManipulated(m_otherEntity, true); if (state == MyState.HOLD) { if (m_otherEntity is MyCharacter) { foreach (var body in m_otherEntity.Physics.Ragdoll.RigidBodies) { //body.AngularDamping = TARGET_ANGULAR_DAMPING; //body.LinearDamping = TARGET_LINEAR_DAMPING; //body.Mass = 5; body.Restitution = TARGET_RESTITUTION; body.MaxLinearVelocity = m_limitingLinearVelocity; body.MaxAngularVelocity = (float)Math.PI * 0.1f; } } else { m_massChange = HkMassChangerUtil.Create(m_otherRigidBody, int.MaxValue, 1, 0.001f); //m_otherRigidBody.AngularDamping = TARGET_ANGULAR_DAMPING; //m_otherRigidBody.LinearDamping = TARGET_LINEAR_DAMPING; m_otherRigidBody.Restitution = TARGET_RESTITUTION; m_otherRigidBody.MaxLinearVelocity = m_limitingLinearVelocity; m_otherRigidBody.MaxAngularVelocity = (float)Math.PI; } const float holdingTransparency = 0.4f; SetTransparent(otherEntity, holdingTransparency); } m_constraint = new HkConstraint(m_otherRigidBody, OwnerVirtualPhysics.RigidBody, data); OwnerVirtualPhysics.AddConstraint(m_constraint); m_constraintCreationTime = MySandboxGame.Static.UpdateTime; m_state = state; m_previousCharacterMovementState = Owner.GetCurrentMovementState(); if (m_state == MyState.HOLD) { Owner.PlayCharacterAnimation("PickLumber", MyBlendOption.Immediate, MyFrameOption.PlayOnce, 0.2f, 1f); } else { Owner.PlayCharacterAnimation("PullLumber", MyBlendOption.Immediate, MyFrameOption.PlayOnce, 0.2f, 1f); } m_manipulatedEntitites.Add(m_otherEntity); Owner.ManipulatedEntity = m_otherEntity; var handler = ManipulationStarted; if (handler != null) { handler(m_otherEntity); } }
public override void OnAddedToContainer() { base.OnAddedToContainer(); m_character = Entity as MyCharacter; foreach(var soundEmitter in m_soundEmitters) { soundEmitter.Entity = Entity as MyEntity; } m_lastUpdateMovementState = m_character.GetCurrentMovementState(); InitSounds(); }
private void character_OnMovementStateChanged(MyCharacterMovementEnum oldState, MyCharacterMovementEnum newState) { m_currentState = newState; }
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); } }
private void UpdateManipulation() { if (m_state != MyState.NONE && SafeConstraint != null) { const float fixedConstraintMaxValue = 1000; const float fixedConstraintMaxDistance = 2f; const float ballAndSocketMaxDistance = 2f; MyTimeSpan constraintPrepareTime = MyTimeSpan.FromSeconds(1.0f); MyTimeSpan currentTimeDelta = MySandboxGame.Static.UpdateTime - m_constraintCreationTime; MatrixD headWorldMatrix = Owner.GetHeadMatrix(false, true, false, true); MatrixD worldHeadPivotMatrix = m_headLocalPivotMatrix * headWorldMatrix; MatrixD worldOtherPivotMatrix = m_otherLocalPivotMatrix * m_otherEntity.PositionComp.WorldMatrix; double length = (worldOtherPivotMatrix.Translation - worldHeadPivotMatrix.Translation).Length(); double checkDst = m_fixedConstraintData != null ? fixedConstraintMaxDistance : ballAndSocketMaxDistance; if (currentTimeDelta > constraintPrepareTime) { var characterMovementState = Owner.GetCurrentMovementState(); bool currentCanUseIdle = CanManipulate(characterMovementState); bool previousCanUseIdle = CanManipulate(m_previousCharacterMovementState); if ((!m_constraintInitialized && currentCanUseIdle) || (currentCanUseIdle && !previousCanUseIdle)) { if (m_state == MyState.HOLD) { Owner.PlayCharacterAnimation("PickLumberIdle", true, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f); } else { Owner.PlayCharacterAnimation("PullLumberIdle", true, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f); } } m_previousCharacterMovementState = characterMovementState; m_constraintInitialized = true; if (m_otherRigidBody != null && !MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { m_otherRigidBody.MaxLinearVelocity = m_otherMaxLinearVelocity; m_otherRigidBody.MaxAngularVelocity = m_otherMaxAngularVelocity; } if (m_fixedConstraintData != null && !MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { m_fixedConstraintData.MaximumAngularImpulse = fixedConstraintMaxValue; m_fixedConstraintData.MaximumLinearImpulse = fixedConstraintMaxValue; // Check angle between pivots float upDot = Math.Abs(Vector3.Dot(worldHeadPivotMatrix.Up, worldOtherPivotMatrix.Up)); float rightDot = Math.Abs(Vector3.Dot(worldHeadPivotMatrix.Right, worldOtherPivotMatrix.Right)); if (upDot < 0.5f || rightDot < 0.5f) { if (!(m_otherEntity is MyCharacter)) { SyncTool.StopManipulation(); } return; } } // Check length between pivots if (length > checkDst) { if (!(m_otherEntity is MyCharacter)) { SyncTool.StopManipulation(); } return; } } else { if (m_fixedConstraintData != null && !MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { float t = (float)(currentTimeDelta.Miliseconds / constraintPrepareTime.Miliseconds); t *= t; t *= t; //pow4 float value = t * fixedConstraintMaxValue; m_fixedConstraintData.MaximumAngularImpulse = value; m_fixedConstraintData.MaximumLinearImpulse = value; if (length > checkDst) { var characterMovementState = Owner.GetCurrentMovementState(); if (!CanManipulate(characterMovementState)) { if (!(m_otherEntity is MyCharacter)) { SyncTool.StopManipulation(); } return; } } } } } }
public void MoveAndRotate(ref Vector3 moveIndicator, ref Vector2 rotationIndicator, bool canRotate) { var characterPhysics = Character.Physics; var characterProxy = characterPhysics.CharacterProxy; ThrustComp.ControlThrust = Vector3.Zero; const MyCharacterMovementEnum newMovementState = MyCharacterMovementEnum.Flying; Character.SwitchAnimation(newMovementState); Character.SetCurrentMovementState(newMovementState); bool wantsFlyDown = (Character.MovementFlags & MyCharacterMovementFlags.FlyDown) == MyCharacterMovementFlags.FlyDown; bool wantsFlyUp = (Character.MovementFlags & MyCharacterMovementFlags.FlyUp) == MyCharacterMovementFlags.FlyUp; IsFlying = moveIndicator.LengthSquared() != 0; var proxyState = characterProxy != null?characterProxy.GetState() : 0; if ((proxyState == HkCharacterStateType.HK_CHARACTER_IN_AIR || (int)proxyState == MyCharacter.HK_CHARACTER_FLYING)) { Character.PlayCharacterAnimation("Jetpack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f); Character.CanJump = true; } if (canRotate && rotationIndicator.X != 0) { MatrixD rotationMatrix = Character.WorldMatrix.GetOrientation(); Vector3D translation = Character.WorldMatrix.Translation + Character.WorldMatrix.Up; if (Character.Definition.VerticalPositionFlyingOnly) { Character.SetHeadLocalXAngle(MathHelper.Clamp(Character.HeadLocalXAngle - rotationIndicator.X * Character.RotationSpeed, MyCharacter.MIN_HEAD_LOCAL_X_ANGLE, MyCharacter.MAX_HEAD_LOCAL_X_ANGLE)); } else { rotationMatrix = rotationMatrix * MatrixD.CreateFromAxisAngle(Character.WorldMatrix.Right, rotationIndicator.X * -0.02 * Character.RotationSpeed); } rotationMatrix.Translation = translation - rotationMatrix.Up; //Enable if we want limit character rotation in collisions //if (m_shapeContactPoints.Count < 2) { Character.WorldMatrix = rotationMatrix; Character.ClearShapeContactPoints(); } } Vector3 moveDirection = moveIndicator; if (Character.Definition.VerticalPositionFlyingOnly) { float angleSign = Math.Sign(Character.HeadLocalXAngle); double headAngle = Math.Abs(MathHelper.ToRadians(Character.HeadLocalXAngle)); double exponent = 1.95; double smoothedAngle = Math.Pow(headAngle, exponent); smoothedAngle *= headAngle / Math.Pow(MathHelper.ToRadians(MyCharacter.MAX_HEAD_LOCAL_X_ANGLE), exponent); MatrixD rotationMatrix = MatrixD.CreateFromAxisAngle(Vector3D.Right, angleSign * smoothedAngle); moveDirection = Vector3D.Transform(moveDirection, rotationMatrix); } if (wantsFlyUp || wantsFlyDown) { moveDirection += (wantsFlyUp ? 1 : -1) * Vector3.Up; } if (!Vector3.IsZero(moveDirection)) { moveDirection.Normalize(); } ThrustComp.ControlThrust = moveDirection * ForceMagnitude; }
public void TurnOnJetpack(bool newState, bool fromLoad = false, bool updateSync = true, bool fromInit = false) { bool originalNewState = newState; newState = newState && MySession.Static.Settings.EnableJetpack; newState = newState && Character.Definition.Jetpack != null; newState = newState && (!MySession.Static.SurvivalMode || MyFakes.ENABLE_JETPACK_IN_SURVIVAL || MySession.Static.IsAdminModeEnabled); bool valueChanged = TurnedOn != newState; TurnedOn = newState; ThrustComp.Enabled = newState; ThrustComp.ControlThrust = Vector3.Zero; ThrustComp.MarkDirty(); ThrustComp.UpdateBeforeSimulation(); if (!ThrustComp.Enabled) { ThrustComp.SetRequiredFuelInput(ref FuelDefinition.Id, 0f, null); } ThrustComp.ResourceSink(Character).Update(); if (!Character.ControllerInfo.IsLocallyControlled() && !fromInit && !Sync.IsServer && !MyFakes.CHARACTER_SERVER_SYNC) { return; } MyCharacterMovementEnum currentMovementState = Character.GetCurrentMovementState(); if (currentMovementState == MyCharacterMovementEnum.Sitting) { return; } Character.StopFalling(); bool noHydrogen = false; bool canUseJetpack = newState; if (!IsPowered && canUseJetpack && (MySession.Static.IsAdminModeEnabled == false || MySession.Static.LocalCharacter != Character)) { canUseJetpack = false; noHydrogen = true; } if (canUseJetpack) { Character.IsUsing = null; } if (MySession.Static.ControlledEntity == Character && valueChanged && !fromLoad) { m_jetpackToggleNotification.Text = (noHydrogen) ? MySpaceTexts.NotificationJetpackOffNoHydrogen : (canUseJetpack || (originalNewState)) ? MySpaceTexts.NotificationJetpackOn : MySpaceTexts.NotificationJetpackOff; MyHud.Notifications.Add(m_jetpackToggleNotification); if (canUseJetpack) { MyAnalyticsHelper.ReportActivityStart(Character, "jetpack", "character", string.Empty, string.Empty); } else { MyAnalyticsHelper.ReportActivityEnd(Character, "jetpack"); } //unable sound + turn off jetpack if (noHydrogen) { MyGuiAudio.PlaySound(MyGuiSounds.HudUnable); TurnedOn = false; ThrustComp.Enabled = false; ThrustComp.ControlThrust = Vector3.Zero; ThrustComp.MarkDirty(); ThrustComp.UpdateBeforeSimulation(); ThrustComp.SetRequiredFuelInput(ref FuelDefinition.Id, 0f, null); ThrustComp.ResourceSink(Character).Update(); } } var characterProxy = Character.Physics.CharacterProxy; if (characterProxy != null) { characterProxy.Forward = Character.WorldMatrix.Forward; characterProxy.Up = Character.WorldMatrix.Up; characterProxy.EnableFlyingState(Running); if (currentMovementState != MyCharacterMovementEnum.Died) { if (!Running && (characterProxy.GetState() == HkCharacterStateType.HK_CHARACTER_IN_AIR || (int)characterProxy.GetState() == MyCharacter.HK_CHARACTER_FLYING)) { Character.StartFalling(); } //If we are in any state but not standing and new state is to be flying, dont change to standing. Else is probably ok? else if (currentMovementState != MyCharacterMovementEnum.Standing && !newState) { Character.PlayCharacterAnimation("Idle", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f); Character.SetCurrentMovementState(MyCharacterMovementEnum.Standing); currentMovementState = Character.GetCurrentMovementState(); } } if (Running && currentMovementState != MyCharacterMovementEnum.Died) { Character.PlayCharacterAnimation("Jetpack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.0f); Character.SetCurrentMovementState(MyCharacterMovementEnum.Flying); Character.SetLocalHeadAnimation(0, 0, 0.3f); // If the character is running when enabling the jetpack, these will keep making him fly in the same direction always if not zeroed characterProxy.PosX = 0; characterProxy.PosY = 0; } // When disabling the jetpack normally during the game in zero-G, disable jetpack autoenable if (!fromLoad && !newState && characterProxy.Gravity.LengthSquared() <= 0.1f) { CurrentAutoEnableDelay = -1; } } }
private void CheckChangesOnCharacter() { MyCharacter character = base.Character; if (MyPerGameSettings.EnableRagdollInJetpack) { if (!ReferenceEquals(character.Physics, this.m_previousPhysics)) { this.UpdateCharacterPhysics(); this.m_previousPhysics = character.Physics; } if (Sync.IsServer) { goto TR_001B; } else if (character.ClosestParentId == 0) { goto TR_001B; } else { this.DeactivateJetpackRagdoll(); } } TR_0004: if ((character.IsDead && !this.IsRagdollActivated) && character.Physics.Enabled) { this.InitDeadBodyPhysics(); } return; TR_001B: if (!ReferenceEquals(character.CurrentWeapon, this.m_previousWeapon)) { this.DeactivateJetpackRagdoll(); this.ActivateJetpackRagdoll(); this.m_previousWeapon = character.CurrentWeapon; } MyCharacterJetpackComponent jetpackComp = character.JetpackComp; MyCharacterMovementEnum currentMovementState = character.GetCurrentMovementState(); if ((((jetpackComp == null) || !jetpackComp.TurnedOn) || (currentMovementState != MyCharacterMovementEnum.Flying)) && ((currentMovementState != MyCharacterMovementEnum.Falling) || !character.Physics.Enabled)) { if ((this.RagdollMapper != null) && this.RagdollMapper.IsPartiallySimulated) { this.DeactivateJetpackRagdoll(); } } else if (!this.IsRagdollActivated || !this.RagdollMapper.IsActive) { this.DeactivateJetpackRagdoll(); this.ActivateJetpackRagdoll(); } if (this.IsRagdollActivated && (character.Physics.Ragdoll != null)) { bool isDead = character.IsDead; using (List <HkRigidBody> .Enumerator enumerator = character.Physics.Ragdoll.RigidBodies.GetEnumerator()) { while (enumerator.MoveNext()) { enumerator.Current.EnableDeactivation = isDead; } } } goto TR_0004; }
float GetMovementAcceleration(MyCharacterMovementEnum movement) { switch (movement) { case MyCharacterMovementEnum.Standing: case MyCharacterMovementEnum.Crouching: { return MyPerGameSettings.CharacterMovement.WalkAcceleration; } case MyCharacterMovementEnum.Walking: case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkingLeftBack: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingRightBack: case MyCharacterMovementEnum.WalkingRightFront: case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningLeftFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchWalkingLeftBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingRightFront: { return MyPerGameSettings.CharacterMovement.WalkAcceleration; } case MyCharacterMovementEnum.Sprinting: { return MyPerGameSettings.CharacterMovement.SprintAcceleration; } case MyCharacterMovementEnum.Jump: { return 0; } case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingLeft: { return MyPerGameSettings.CharacterMovement.WalkAcceleration; } case MyCharacterMovementEnum.WalkStrafingRight: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.CrouchStrafingRight: { return MyPerGameSettings.CharacterMovement.WalkAcceleration; } default: System.Diagnostics.Debug.Assert(false, "Unknown walking state"); break; } return 0; }
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; }
public void MoveAndRotate(ref Vector3 moveIndicator, ref Vector2 rotationIndicator, float roll, bool canRotate) { var characterPhysics = Character.Physics; var characterProxy = characterPhysics.CharacterProxy; ThrustComp.ControlThrust = Vector3.Zero; const MyCharacterMovementEnum newMovementState = MyCharacterMovementEnum.Flying; Character.SwitchAnimation(newMovementState); Character.SetCurrentMovementState(newMovementState); bool wantsFlyDown = (Character.MovementFlags & MyCharacterMovementFlags.FlyDown) == MyCharacterMovementFlags.FlyDown; bool wantsFlyUp = (Character.MovementFlags & MyCharacterMovementFlags.FlyUp) == MyCharacterMovementFlags.FlyUp; IsFlying = moveIndicator.LengthSquared() != 0; var proxyState = characterProxy != null?characterProxy.GetState() : 0; if ((proxyState == HkCharacterStateType.HK_CHARACTER_IN_AIR || (int)proxyState == MyCharacter.HK_CHARACTER_FLYING)) { Character.PlayCharacterAnimation("Jetpack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f); Character.CanJump = true; } MatrixD WorldMatrix = Character.WorldMatrix; float RotationSpeed = Character.RotationSpeed; float RotationFactor = 0.02f; if (canRotate) { MatrixD rotationXMatrix = MatrixD.Identity; MatrixD rotationYMatrix = MatrixD.Identity; MatrixD rotationZMatrix = MatrixD.Identity; if (Math.Abs(rotationIndicator.X) > float.Epsilon) { if (Character.Definition.VerticalPositionFlyingOnly) { Character.SetHeadLocalXAngle(Character.HeadLocalXAngle - rotationIndicator.X * Character.RotationSpeed); } else { rotationXMatrix = MatrixD.CreateFromAxisAngle(WorldMatrix.Right, -rotationIndicator.X * RotationSpeed * RotationFactor); } } if (Math.Abs(rotationIndicator.Y) > float.Epsilon) { rotationYMatrix = MatrixD.CreateFromAxisAngle(WorldMatrix.Up, -rotationIndicator.Y * RotationSpeed * RotationFactor); } if (!Character.Definition.VerticalPositionFlyingOnly) { if (Math.Abs(roll) > float.Epsilon) { rotationZMatrix = MatrixD.CreateFromAxisAngle(WorldMatrix.Forward, roll * RotationFactor); } } // Rotation center is at the middle of the character, who is 2 meters high. float rotationHeight = Character.ModelCollision.BoundingBoxSizeHalf.Y; MatrixD physicsMatrix = Character.Physics.GetWorldMatrix(); Vector3D translation = physicsMatrix.Translation + WorldMatrix.Up * rotationHeight; // Compute rotation MatrixD fullRotation = rotationXMatrix * rotationYMatrix * rotationZMatrix; MatrixD rotatedMatrix = WorldMatrix.GetOrientation(); rotatedMatrix = rotatedMatrix * fullRotation; rotatedMatrix.Translation = translation - rotatedMatrix.Up * rotationHeight; // Update game character Character.WorldMatrix = rotatedMatrix; // Update physics character rotatedMatrix.Translation = physicsMatrix.Translation; Character.PositionComp.SetWorldMatrix(rotatedMatrix, Character.Physics); Character.ClearShapeContactPoints(); } Vector3 moveDirection = moveIndicator; if (Character.Definition.VerticalPositionFlyingOnly) { float angleSign = Math.Sign(Character.HeadLocalXAngle); double headAngle = Math.Abs(MathHelper.ToRadians(Character.HeadLocalXAngle)); double exponent = 1.95; double smoothedAngle = Math.Pow(headAngle, exponent); smoothedAngle *= headAngle / Math.Pow(MathHelper.ToRadians(MyCharacter.MAX_HEAD_LOCAL_X_ANGLE), exponent); MatrixD rotationMatrix = MatrixD.CreateFromAxisAngle(Vector3D.Right, angleSign * smoothedAngle); moveDirection = Vector3D.Transform(moveDirection, rotationMatrix); } if (!Vector3.IsZero(moveDirection)) { moveDirection.Normalize(); } ThrustComp.ControlThrust += moveDirection * ForceMagnitude; ThrustComp.ControlThrustMagnitude += Vector3.One; }
private void UpdateManipulation() { if (m_state != MyState.NONE && SafeConstraint != null) { const float fixedConstraintMaxValue = 1000; const float fixedConstraintMaxDistance = 2f; const float ballAndSocketMaxDistance = 2f; MyTimeSpan constraintPrepareTime = MyTimeSpan.FromSeconds(1.0f); MyTimeSpan currentTimeDelta = MySandboxGame.Static.UpdateTime - m_constraintCreationTime; MatrixD headWorldMatrix = Owner.GetHeadMatrix(false, forceHeadBone: true); MatrixD worldHeadPivotMatrix = m_headLocalPivotMatrix * headWorldMatrix; MatrixD worldOtherPivotMatrix = m_otherLocalPivotMatrix * m_otherEntity.PositionComp.WorldMatrix; double length = (worldOtherPivotMatrix.Translation - worldHeadPivotMatrix.Translation).Length(); double checkDst = m_fixedConstraintData != null ? fixedConstraintMaxDistance : ballAndSocketMaxDistance; if (currentTimeDelta > constraintPrepareTime) { var characterMovementState = Owner.GetCurrentMovementState(); bool currentCanUseIdle = CanManipulate(characterMovementState); bool previousCanUseIdle = CanManipulate(m_previousCharacterMovementState); if ((!m_constraintInitialized && currentCanUseIdle) || (currentCanUseIdle && !previousCanUseIdle)) { if (m_state == MyState.HOLD) { Owner.PlayCharacterAnimation("PickLumberIdle", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f, 1f); } else { Owner.PlayCharacterAnimation("PullLumberIdle", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f, 1f); } } m_previousCharacterMovementState = characterMovementState; m_constraintInitialized = true; if (m_otherRigidBody != null && !MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { m_otherRigidBody.MaxLinearVelocity = m_otherMaxLinearVelocity; m_otherRigidBody.MaxAngularVelocity = m_otherMaxAngularVelocity; } if (m_fixedConstraintData != null && (MyScreenManager.GetScreenWithFocus() is MyGuiScreenGamePlay)) { float rotationSpeed = MyInput.Static.IsAnyShiftKeyPressed() ? -0.01f : 0.01f; var tran = m_otherLocalPivotMatrix.Translation; if (MyInput.Static.IsKeyPress(MyKeys.E)) { m_otherLocalPivotMatrix = m_otherLocalPivotMatrix * Matrix.CreateFromAxisAngle(Vector3.Up, rotationSpeed); m_otherLocalPivotMatrix.Translation = tran; m_fixedConstraintData.SetInBodySpace(m_otherLocalPivotMatrix, m_headLocalPivotMatrix, m_otherPhysicsBody, OwnerVirtualPhysics); } if (MyInput.Static.IsKeyPress(MyKeys.Q)) { m_otherLocalPivotMatrix = m_otherLocalPivotMatrix * Matrix.CreateFromAxisAngle(Vector3.Forward, rotationSpeed); m_otherLocalPivotMatrix.Translation = tran; m_fixedConstraintData.SetInBodySpace(m_otherLocalPivotMatrix, m_headLocalPivotMatrix, m_otherPhysicsBody, OwnerVirtualPhysics); } if (MyInput.Static.IsKeyPress(MyKeys.R)) { m_otherLocalPivotMatrix = m_otherLocalPivotMatrix * Matrix.CreateFromAxisAngle(Vector3.Right, rotationSpeed); m_otherLocalPivotMatrix.Translation = tran; m_fixedConstraintData.SetInBodySpace(m_otherLocalPivotMatrix, m_headLocalPivotMatrix, m_otherPhysicsBody, OwnerVirtualPhysics); } } if (m_fixedConstraintData != null && !MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { m_fixedConstraintData.MaximumAngularImpulse = fixedConstraintMaxValue; m_fixedConstraintData.MaximumLinearImpulse = fixedConstraintMaxValue; // Check angle between pivots float upDot = Math.Abs(Vector3.Dot(worldHeadPivotMatrix.Up, worldOtherPivotMatrix.Up)); float rightDot = Math.Abs(Vector3.Dot(worldHeadPivotMatrix.Right, worldOtherPivotMatrix.Right)); if (upDot < 0.5f || rightDot < 0.5f) { // Synced from local player because lagged server can drop manipulated items with fast moves if (!(m_otherEntity is MyCharacter) && IsOwnerLocalPlayer()) { SyncTool.StopManipulation(); } return; } } // Check length between pivots if (length > checkDst) { // Synced from local player because lagged server can drop manipulated items with fast moves if (!(m_otherEntity is MyCharacter) && IsOwnerLocalPlayer()) { SyncTool.StopManipulation(); } return; } } else { if (m_fixedConstraintData != null && !MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { float t = (float)(currentTimeDelta.Miliseconds / constraintPrepareTime.Miliseconds); t *= t; t *= t; //pow4 float value = t * fixedConstraintMaxValue; m_fixedConstraintData.MaximumAngularImpulse = value; m_fixedConstraintData.MaximumLinearImpulse = value; if (length > checkDst) { var characterMovementState = Owner.GetCurrentMovementState(); if (!CanManipulate(characterMovementState)) { // Synced from local player because lagged server can drop manipulated items with fast moves if (!(m_otherEntity is MyCharacter) && IsOwnerLocalPlayer()) { SyncTool.StopManipulation(); } return; } } } } } }
public void SetPreviousMovementState(MyCharacterMovementEnum previousMovementState) { m_previousMovementState = previousMovementState; }
public void FindAndPlayStateSound() { m_character.Breath.Update(); var cueEnum = SelectSound(); var primaryEmitter = m_soundEmitters[(int)MySoundEmitterEnum.PrimaryState]; var walkEmitter = m_soundEmitters[(int)MySoundEmitterEnum.WalkState]; bool sameSoundAlreadyPlaying = (cueEnum.Arcade == primaryEmitter.SoundId || (MyFakes.ENABLE_NEW_SOUNDS && cueEnum.Realistic == primaryEmitter.SoundId)); if (primaryEmitter.Sound != null) primaryEmitter.Sound.SetVolume(MathHelper.Clamp(m_character.Physics.LinearAcceleration.Length() / 3.0f, 0.6f, 1)); if (!sameSoundAlreadyPlaying) { bool skipIntro = cueEnum == CharacterSounds[(int) CharacterSoundsEnum.JETPACK_RUN_SOUND] || cueEnum == CharacterSounds[(int) CharacterSoundsEnum.JETPACK_IDLE_SOUND]; if (cueEnum == CharacterSounds[(int)CharacterSoundsEnum.JETPACK_RUN_SOUND]) { if (primaryEmitter.Loop) primaryEmitter.StopSound(false); primaryEmitter.PlaySound(cueEnum, false, skipIntro); } else if (cueEnum == CharacterSounds[(int)CharacterSoundsEnum.JETPACK_IDLE_SOUND] && m_soundEmitters[(int)MySoundEmitterEnum.PrimaryState].SoundId == CharacterSounds[(int)CharacterSoundsEnum.JETPACK_RUN_SOUND].SoundId) { primaryEmitter.StopSound(false); } else if (cueEnum == CharacterSounds[(int)CharacterSoundsEnum.NONE_SOUND]) { foreach(var soundEmitter in m_soundEmitters) { if (soundEmitter.Loop) soundEmitter.StopSound(false); } } else { if (primaryEmitter.Loop) primaryEmitter.StopSound(false); primaryEmitter.PlaySound(cueEnum, true, skipIntro); } } else if (MyPerGameSettings.NonloopingCharacterFootsteps) { var movementState = m_character.GetCurrentMovementState(); if (movementState.GetMode() == MyCharacterMovement.Flying) return; if (movementState.GetSpeed() != m_lastUpdateMovementState.GetSpeed()) walkEmitter.StopSound(true); bool playSound = false; int usedDelay = int.MaxValue; if (movementState.GetDirection() != MyCharacterMovement.NoDirection) { switch (movementState.GetSpeed()) { case MyCharacterMovement.NormalSpeed: usedDelay = m_stepDelayWalk; break; case MyCharacterMovement.Fast: usedDelay = m_stepDelayRun; break; case MyCharacterMovement.VeryFast: usedDelay = m_stepDelaySprint; break; } } playSound = (MySandboxGame.TotalGamePlayTimeInMilliseconds - m_lastStepTime) >= usedDelay; if (playSound) { walkEmitter.PlaySound(cueEnum); m_lastStepTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; } m_lastUpdateMovementState = movementState; } }
public void ChangeMovementState(MyCharacterMovementEnum state) { //if (!MyFakes.CHARACTER_SERVER_SYNC) //{ // if (ResponsibleForUpdate(this)) // { // var msg = new ChangeMovementStateMsg(); // msg.CharacterEntityId = Entity.EntityId; // msg.MovementState = state; // Sync.Layer.SendMessageToAll(ref msg); // } //} }
public void CharacterMovementStateChanged(MyCharacterMovementEnum oldState, MyCharacterMovementEnum newState) { characterMovementState = newState; }
private void UpdateAnimationNewSystem() { var variableStorage = AnimationController.Variables; // character speed if (Physics != null && Physics.CharacterProxy != null) { Vector3 localSpeedWorldRotUnfiltered = (Physics.CharacterProxy.LinearVelocity - Physics.CharacterProxy.GroundVelocity); //Minimize walking bug during standing on floating object if ((GetCurrentMovementState() == MyCharacterMovementEnum.Standing) /*&& Physics.CharacterProxy.CharacterRigidBody.IsSupportedByFloatingObject()*/) { float r = Physics.CharacterProxy.Up.Dot(localSpeedWorldRotUnfiltered); if (r < 0.0f) { localSpeedWorldRotUnfiltered -= Physics.CharacterProxy.Up * r; } } var localSpeedWorldRot = FilterLocalSpeed(localSpeedWorldRotUnfiltered); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeed, localSpeedWorldRot.Length()); float localSpeedX = localSpeedWorldRot.Dot(PositionComp.WorldMatrix.Right); float localSpeedY = localSpeedWorldRot.Dot(PositionComp.WorldMatrix.Up); float localSpeedZ = localSpeedWorldRot.Dot(PositionComp.WorldMatrix.Forward); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedX, localSpeedX); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedY, localSpeedY); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedZ, localSpeedZ); const float speedThreshold2 = 0.1f * 0.1f; float speedangle = localSpeedWorldRot.LengthSquared() > speedThreshold2 ? (float)(-Math.Atan2(localSpeedZ, localSpeedX) * 180.0f / Math.PI) + 90.0f : 0.0f; while (speedangle < 0.0f) { speedangle += 360.0f; } variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSpeedAngle, speedangle); Quaternion currentRotation = this.GetRotation(); m_animTurningSpeed = (Quaternion.Inverse(currentRotation) * m_lastRotation).Y / (CHARACTER_X_ROTATION_SPEED * CHARACTER_Y_ROTATION_FACTOR / 2) * 180.0f / (float)Math.PI; variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdTurningSpeed, m_animTurningSpeed); m_lastRotation = currentRotation; if (OxygenComponent != null) { variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdHelmetOpen, OxygenComponent.HelmetEnabled ? 0.0f : 1.0f); } if (Parent is MyCockpit) { variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdLean, 0); } else { variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdLean, m_animLeaning); } } if (JetpackComp != null) { AnimationController.Variables.SetValue(MyAnimationVariableStorageHints.StrIdFlying, JetpackComp.Running ? 1.0f : 0.0f); } MyCharacterMovementEnum movementState = GetCurrentMovementState(); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdFlying, movementState == MyCharacterMovementEnum.Flying ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdFalling, IsFalling || movementState == MyCharacterMovementEnum.Falling ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdCrouch, (WantsCrouch && !WantsSprint) ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdSitting, movementState == MyCharacterMovementEnum.Sitting ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdJumping, movementState == MyCharacterMovementEnum.Jump ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdFirstPerson, m_isInFirstPerson ? 1.0f : 0.0f); variableStorage.SetValue(MyAnimationVariableStorageHints.StrIdHoldingTool, m_currentWeapon != null ? 1.0f : 0.0f); }
public void CurrentMovementState(MyCharacterMovementEnum state) { m_currentMovementState = state; }
internal void TrySpawnWalkingParticles() { if (MyFakes.ENABLE_WALKING_PARTICLES) { int lastWalkParticleCheckTime = this.m_lastWalkParticleCheckTime; this.m_lastWalkParticleCheckTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; this.m_walkParticleSpawnCounterMs -= this.m_lastWalkParticleCheckTime - lastWalkParticleCheckTime; if (this.m_walkParticleSpawnCounterMs <= 0) { if (MyGravityProviderSystem.CalculateHighestNaturalGravityMultiplierInPoint(base.Entity.PositionComp.WorldMatrix.Translation) <= 0f) { this.m_walkParticleSpawnCounterMs = 0x2710; } else { MyCharacter entity = base.Entity as MyCharacter; if (entity.JetpackRunning) { this.m_walkParticleSpawnCounterMs = 0x7d0; } else { MyCharacterMovementEnum currentMovementState = entity.GetCurrentMovementState(); if ((currentMovementState.GetDirection() == 0) || (currentMovementState == MyCharacterMovementEnum.Falling)) { this.m_walkParticleSpawnCounterMs = 0x3e8; } else { Vector3D up = base.Entity.PositionComp.WorldMatrix.Up; Vector3D from = base.Entity.PositionComp.WorldMatrix.Translation + (0.2 * up); MyPhysics.HitInfo?nullable = MyPhysics.CastRay(from, (base.Entity.PositionComp.WorldMatrix.Translation + (0.2 * up)) - (0.5 * up), 0x1c); if (nullable != null) { MyVoxelPhysicsBody physics = nullable.Value.HkHitInfo.GetHitEntity().Physics as MyVoxelPhysicsBody; if (physics != null) { MyStringId walk; ushort speed = currentMovementState.GetSpeed(); if (speed == 0) { walk = MyMaterialPropertiesHelper.CollisionType.Walk; this.m_walkParticleSpawnCounterMs = 500; } else if (speed == 0x400) { walk = MyMaterialPropertiesHelper.CollisionType.Run; this.m_walkParticleSpawnCounterMs = 0x113; } else if (speed != 0x800) { walk = MyMaterialPropertiesHelper.CollisionType.Walk; this.m_walkParticleSpawnCounterMs = 0x3e8; } else { walk = MyMaterialPropertiesHelper.CollisionType.Sprint; this.m_walkParticleSpawnCounterMs = 250; } Vector3D position = nullable.Value.Position; MyVoxelMaterialDefinition materialAt = physics.m_voxelMap.GetMaterialAt(ref position); if (materialAt != null) { MyMaterialPropertiesHelper.Static.TryCreateCollisionEffect(walk, position, (Vector3)up, ID_CHARACTER, materialAt.MaterialTypeNameHash, null); } } } } } } } } }
internal void SetCurrentMovementState(MyCharacterMovementEnum state) { System.Diagnostics.Debug.Assert(m_currentMovementState != MyCharacterMovementEnum.Died || m_currentMovementState == state, "Trying to set a new movement state, but character is in dead state!"); if (m_currentMovementState == state) return; if (Physics.CharacterProxy != null) { switch (state) { case MyCharacterMovementEnum.Crouching: Physics.CharacterProxy.SetShapeForCrouch(Physics.HavokWorld, true); break; case MyCharacterMovementEnum.CrouchRotatingLeft: case MyCharacterMovementEnum.CrouchRotatingRight: case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchWalkingLeftBack: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: Physics.CharacterProxy.SetShapeForCrouch(Physics.HavokWorld, true); break; default: Physics.CharacterProxy.SetShapeForCrouch(Physics.HavokWorld, false); break; } } m_previousMovementState = m_currentMovementState; m_currentMovementState = state; if (OnMovementStateChanged != null) OnMovementStateChanged(m_previousMovementState, m_currentMovementState); }
internal void TrySpawnWalkingParticles(ref HkContactPointEvent value) { if (MyFakes.ENABLE_WALKING_PARTICLES) { int lastWalkParticleCheckTime = this.m_lastWalkParticleCheckTime; this.m_lastWalkParticleCheckTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; this.m_walkParticleSpawnCounterMs -= this.m_lastWalkParticleCheckTime - lastWalkParticleCheckTime; if (this.m_walkParticleSpawnCounterMs <= 0) { if (MyGravityProviderSystem.CalculateHighestNaturalGravityMultiplierInPoint(base.Entity.PositionComp.WorldMatrix.Translation) <= 0f) { this.m_walkParticleSpawnCounterMs = 0x2710; } else { MyCharacter entity = base.Entity as MyCharacter; if (entity.JetpackRunning) { this.m_walkParticleSpawnCounterMs = 0x7d0; } else { MyCharacterMovementEnum currentMovementState = entity.GetCurrentMovementState(); if ((currentMovementState.GetDirection() == 0) || (currentMovementState == MyCharacterMovementEnum.Falling)) { this.m_walkParticleSpawnCounterMs = 0x3e8; } else { MyVoxelPhysicsBody physics = value.GetOtherEntity(entity).Physics as MyVoxelPhysicsBody; if (physics != null) { MyStringId walk; ushort speed = currentMovementState.GetSpeed(); if (speed == 0) { walk = MyMaterialPropertiesHelper.CollisionType.Walk; this.m_walkParticleSpawnCounterMs = 500; } else if (speed == 0x400) { walk = MyMaterialPropertiesHelper.CollisionType.Run; this.m_walkParticleSpawnCounterMs = 0x113; } else if (speed != 0x800) { walk = MyMaterialPropertiesHelper.CollisionType.Walk; this.m_walkParticleSpawnCounterMs = 0x3e8; } else { walk = MyMaterialPropertiesHelper.CollisionType.Sprint; this.m_walkParticleSpawnCounterMs = 250; } Vector3D worldPosition = physics.ClusterToWorld(value.ContactPoint.Position); MyVoxelMaterialDefinition materialAt = physics.m_voxelMap.GetMaterialAt(ref worldPosition); if (materialAt != null) { MyMaterialPropertiesHelper.Static.TryCreateCollisionEffect(walk, worldPosition, value.ContactPoint.Normal, ID_CHARACTER, materialAt.MaterialTypeNameHash, null); } } } } } } } }
public static bool IsRunningState(MyCharacterMovementEnum state) { switch (state) { case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningLeftFront: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.Sprinting: return true; break; default: return false; } }
public static ushort GetMode(this MyCharacterMovementEnum value) { return((ushort)((ushort)value & MovementTypeMask)); }
internal float LimitMaxSpeed(float currentSpeed, MyCharacterMovementEnum movementState, float serverRatio) { float limitedSpeed = currentSpeed; switch (movementState) { case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Flying: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxRunSpeed * serverRatio, Definition.MaxRunSpeed * serverRatio); break; } case MyCharacterMovementEnum.Walking: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxWalkSpeed * serverRatio, Definition.MaxWalkSpeed * serverRatio); break; } case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkingLeftBack: case MyCharacterMovementEnum.WalkingRightBack: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxBackwalkSpeed * serverRatio, Definition.MaxBackwalkSpeed * serverRatio); break; } case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.WalkStrafingRight: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingRightFront: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxWalkStrafingSpeed * serverRatio, Definition.MaxWalkStrafingSpeed * serverRatio); break; } case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunningLeftBack: case MyCharacterMovementEnum.RunningRightBack: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxBackrunSpeed * serverRatio, Definition.MaxBackrunSpeed * serverRatio); break; } case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningLeftFront: case MyCharacterMovementEnum.RunningRightFront: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxRunStrafingSpeed * serverRatio, Definition.MaxRunStrafingSpeed * serverRatio); break; } case MyCharacterMovementEnum.CrouchWalking: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxCrouchWalkSpeed * serverRatio, Definition.MaxCrouchWalkSpeed * serverRatio); break; } case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingRightFront: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxCrouchStrafingSpeed * serverRatio, Definition.MaxCrouchStrafingSpeed * serverRatio); break; } case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchWalkingLeftBack: case MyCharacterMovementEnum.CrouchWalkingRightBack: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxCrouchBackwalkSpeed * serverRatio, Definition.MaxCrouchBackwalkSpeed * serverRatio); break; } case MyCharacterMovementEnum.Sprinting: { limitedSpeed = MathHelper.Clamp(currentSpeed, -Definition.MaxSprintSpeed * serverRatio, Definition.MaxSprintSpeed * serverRatio); break; } case MyCharacterMovementEnum.Jump: { break; } case MyCharacterMovementEnum.Standing: case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.Sitting: case MyCharacterMovementEnum.RotatingLeft: case MyCharacterMovementEnum.RotatingRight: case MyCharacterMovementEnum.CrouchRotatingLeft: case MyCharacterMovementEnum.CrouchRotatingRight: case MyCharacterMovementEnum.Falling: break; default: { System.Diagnostics.Debug.Assert(false); break; } } return limitedSpeed; }
public static ushort GetDirection(this MyCharacterMovementEnum value) { return((ushort)((ushort)value & MovementDirectionMask)); }
public override void Init(MyObjectBuilder_EntityBase objectBuilder) { SyncFlag = true; /// Wee need to get the character subtype, before passing init to base classes so the components can be properly initialized.. MyObjectBuilder_Character characterOb = (MyObjectBuilder_Character)objectBuilder; Render.ColorMaskHsv = characterOb.ColorMaskHSV; Vector3 colorMask = Render.ColorMaskHsv; /// This will retrieve definition and set the subtype for the character GetModelAndDefinition(characterOb, out m_characterModel, out m_characterDefinition, ref colorMask); base.UseNewAnimationSystem = m_characterDefinition.UseNewAnimationSystem; if (UseNewAnimationSystem) { //// Create default layer. //AnimationController.Controller.DeleteAllLayers(); //var animationLayer = AnimationController.Controller.CreateLayer("Body"); //// Build an animation node for each animation subtype. //// VRAGE TODO: this is just temporary for testing the new animation system //foreach (var animationNameSubType in m_characterDefinition.AnimationNameToSubtypeName) //{ // string animSubType = animationNameSubType.Value; // MyAnimationDefinition animationDefinition = null; // if (animationLayer.FindNode(animSubType) == null && TryGetAnimationDefinition(animSubType, out animationDefinition)) // { // MyModel modelAnimation = VRage.Game.Models.MyModels.GetModelOnlyAnimationData(animationDefinition.AnimationModel); // if (modelAnimation != null && animationDefinition.ClipIndex < modelAnimation.Animations.Clips.Count) // { // VRage.Animations.MyAnimationClip clip = modelAnimation.Animations.Clips[animationDefinition.ClipIndex]; // var animationState = new VRage.Animations.MyAnimationStateMachineNode(animSubType, clip); // animationLayer.AddNode(animationState); // } // } //} AnimationController.Clear(); MyStringHash animSubtypeNameHash = MyStringHash.GetOrCompute(m_characterDefinition.AnimationController); MyAnimationControllerDefinition animControllerDef = MyDefinitionManager.Static.GetDefinition<MyAnimationControllerDefinition>(animSubtypeNameHash); if (animControllerDef != null) { AnimationController.InitFromDefinition(animControllerDef); } } if (Render.ColorMaskHsv != colorMask) // color mask is set by definition of model Render.ColorMaskHsv = colorMask; /// Set the subtype from the definition characterOb.SubtypeName = m_characterDefinition.Id.SubtypeName; base.Init(objectBuilder); SyncObject.MarkPhysicsDirty(); m_currentAnimationChangeDelay = 0; SoundComp = new MyCharacterSoundComponent(); RadioBroadcaster.WantsToBeEnabled = characterOb.EnableBroadcasting && Definition.VisibleOnHud; Init(new StringBuilder(characterOb.DisplayName), m_characterDefinition.Model, null, null); NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME | MyEntityUpdateEnum.EACH_10TH_FRAME | MyEntityUpdateEnum.EACH_100TH_FRAME; PositionComp.LocalAABB = new BoundingBox(-new Vector3(0.3f, 0.0f, 0.3f), new Vector3(0.3f, 1.8f, 0.3f)); m_currentLootingCounter = characterOb.LootingCounter; if (m_currentLootingCounter <= 0) UpdateCharacterPhysics(!characterOb.AIMode); m_currentMovementState = characterOb.MovementState; if (Physics != null && Physics.CharacterProxy != null) { switch (m_currentMovementState) { case MyCharacterMovementEnum.Falling: case MyCharacterMovementEnum.Flying: Physics.CharacterProxy.SetState(HkCharacterStateType.HK_CHARACTER_IN_AIR); break; case MyCharacterMovementEnum.Jump: Physics.CharacterProxy.SetState(HkCharacterStateType.HK_CHARACTER_JUMPING); break; case MyCharacterMovementEnum.Ladder: case MyCharacterMovementEnum.LadderDown: case MyCharacterMovementEnum.LadderUp: Physics.CharacterProxy.SetState(HkCharacterStateType.HK_CHARACTER_CLIMBING); break; default: Physics.CharacterProxy.SetState(HkCharacterStateType.HK_CHARACTER_ON_GROUND); break; } } InitAnimations(); ValidateBonesProperties(); CalculateTransforms(0); if (m_currentLootingCounter > 0) { InitDeadBodyPhysics(); if (m_currentMovementState != MyCharacterMovementEnum.Died) SetCurrentMovementState(MyCharacterMovementEnum.Died); SwitchAnimation(MyCharacterMovementEnum.Died, false); } InitInventory(characterOb); Physics.Enabled = true; SetHeadLocalXAngle(characterOb.HeadAngle.X); SetHeadLocalYAngle(characterOb.HeadAngle.Y); Render.InitLight(m_characterDefinition); Render.InitJetpackThrusts(m_characterDefinition); m_useAnimationForWeapon = MyPerGameSettings.CheckUseAnimationInsteadOfIK(); m_lightEnabled = characterOb.LightEnabled; Physics.LinearVelocity = characterOb.LinearVelocity; if (Physics.CharacterProxy != null) { Physics.CharacterProxy.ContactPointCallbackEnabled = true; Physics.CharacterProxy.ContactPointCallback += RigidBody_ContactPointCallback; } Render.UpdateLightProperties(m_currentLightPower); // Setup first person view for local player from previous state before die. IsInFirstPersonView = MySession.Static.Settings.Enable3rdPersonView == false || (m_localCharacterWasInThirdPerson != null ? characterOb.IsInFirstPersonView && !m_localCharacterWasInThirdPerson.Value : characterOb.IsInFirstPersonView); m_breath = new MyCharacterBreath(this); Debug.Assert(m_currentLootingCounter <= 0 || m_currentLootingCounter > 0); m_broadcastingNotification = new MyHudNotification(); m_notEnoughStatNotification = new MyHudNotification(MyCommonTexts.NotificationStatNotEnough, disappearTimeMs: 1000, font: MyFontEnum.Red, level: MyNotificationLevel.Important); if (InventoryAggregate != null) InventoryAggregate.Init(); UseDamageSystem = true; if (characterOb.EnabledComponents == null) { characterOb.EnabledComponents = new List<string>(); } foreach (var componentName in m_characterDefinition.EnabledComponents) { if (characterOb.EnabledComponents.All(x => x != componentName)) characterOb.EnabledComponents.Add(componentName); } foreach (var componentName in characterOb.EnabledComponents) { Tuple<Type, Type> componentType; if (MyCharacterComponentTypes.CharacterComponents.TryGetValue(MyStringId.GetOrCompute(componentName), out componentType)) { MyEntityComponentBase component = Activator.CreateInstance(componentType.Item1) as MyEntityComponentBase; Components.Add(componentType.Item2, component); } } if (m_characterDefinition.UsesAtmosphereDetector) { AtmosphereDetectorComp = new MyAtmosphereDetectorComponent(); AtmosphereDetectorComp.InitComponent(true, this); } bool hasGases = Definition.SuitResourceStorage.Count > 0; var sinkData = new List<MyResourceSinkInfo>(); var sourceData = new List<MyResourceSourceInfo>(); if (hasGases) { OxygenComponent = new MyCharacterOxygenComponent(); Components.Add(OxygenComponent); OxygenComponent.Init(characterOb); OxygenComponent.AppendSinkData(sinkData); OxygenComponent.AppendSourceData(sourceData); } m_suitBattery = new MyBattery(this); m_suitBattery.Init(characterOb.Battery, sinkData, sourceData); if (hasGases) { OxygenComponent.CharacterGasSink = m_suitBattery.ResourceSink; OxygenComponent.CharacterGasSource = m_suitBattery.ResourceSource; } sinkData.Clear(); sinkData.Add( new MyResourceSinkInfo { ResourceTypeId = MyResourceDistributorComponent.ElectricityId, MaxRequiredInput = MyEnergyConstants.REQUIRED_INPUT_LIFE_SUPPORT + MyEnergyConstants.REQUIRED_INPUT_CHARACTER_LIGHT, RequiredInputFunc = ComputeRequiredPower }); if (hasGases) { sinkData.Add(new MyResourceSinkInfo { ResourceTypeId = MyCharacterOxygenComponent.OxygenId, MaxRequiredInput = (OxygenComponent.OxygenCapacity + (!OxygenComponent.NeedsOxygenFromSuit ? Definition.OxygenConsumption : 0f)) * Definition.OxygenConsumptionMultiplier * VRage.Game.MyEngineConstants.UPDATE_STEPS_PER_SECOND / 100f, RequiredInputFunc = () => (OxygenComponent.HelmetEnabled ? Definition.OxygenConsumption : 0f) * Definition.OxygenConsumptionMultiplier * VRage.Game.MyEngineConstants.UPDATE_STEPS_PER_SECOND / 100f }); } SinkComp.Init( MyStringHash.GetOrCompute("Utility"), sinkData); SinkComp.CurrentInputChanged += delegate { SetPowerInput(SinkComp.CurrentInputByType(MyResourceDistributorComponent.ElectricityId)); }; SinkComp.TemporaryConnectedEntity = this; SuitRechargeDistributor = new MyResourceDistributorComponent(); SuitRechargeDistributor.AddSource(m_suitBattery.ResourceSource); SuitRechargeDistributor.AddSink(SinkComp); SinkComp.Update(); bool isJetpackAvailable = !MySession.Static.Battle; isJetpackAvailable = isJetpackAvailable && (m_characterDefinition.Jetpack != null); if (isJetpackAvailable) { JetpackComp = new MyCharacterJetpackComponent(); JetpackComp.Init(characterOb); } WeaponPosition = new MyCharacterWeaponPositionComponent(); Components.Add(WeaponPosition); WeaponPosition.Init(characterOb); InitWeapon(characterOb.HandWeapon); if (Definition.RagdollBonesMappings.Count > 0) CreateBodyCapsulesForHits(Definition.RagdollBonesMappings); else m_bodyCapsuleInfo.Clear(); PlayCharacterAnimation(Definition.InitialAnimation, MyBlendOption.Immediate, MyFrameOption.JustFirstFrame, 0.0f); m_savedHealth = characterOb.Health; m_savedPlayer = new Sandbox.Game.World.MyPlayer.PlayerId(characterOb.PlayerSteamId, characterOb.PlayerSerialId); NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; // TODO: Get rid of after after the character will be initialized properly from objectBuilder IsPromoted = characterOb.IsPromoted; m_previousLinearVelocity = characterOb.LinearVelocity; if (ControllerInfo.IsLocallyControlled()) { m_localHeadTransform.Value = new MyTransform(Vector3.Zero); m_localHeadTransformTool.Value = new MyTransform(Vector3.Zero); } CheckExistingStatComponent(); }
public static ushort GetSpeed(this MyCharacterMovementEnum value) { return((ushort)((ushort)value & MovementSpeedMask)); }
public override void OnAddedToContainer() { base.OnAddedToContainer(); m_character = Entity as MyCharacter; foreach(var soundEmitter in m_soundEmitters) { soundEmitter.Entity = Entity as MyEntity; } if(m_windEmitter != null) m_windEmitter.Entity = Entity as MyEntity; if (m_oxygenEmitter != null) m_oxygenEmitter.Entity = Entity as MyEntity; m_lastUpdateMovementState = m_character.GetCurrentMovementState(); m_characterPhysicalMaterial = MyStringHash.GetOrCompute(m_character.Definition.PhysicalMaterial); InitSounds(); }
private void IKFeetStepSounds(MyEntity3DSoundEmitter walkEmitter, MySoundPair cueEnum) { var movementState = m_character.GetCurrentMovementState(); if (movementState.GetMode() == MyCharacterMovement.Flying) { return; } if (movementState.GetSpeed() != m_lastUpdateMovementState.GetSpeed()) { walkEmitter.StopSound(true); m_lastStepTime = 0; } int usedMinimumDelay = int.MaxValue; if (movementState.GetDirection() != MyCharacterMovement.NoDirection) { switch (movementState.GetSpeed()) { case MyCharacterMovement.NormalSpeed: usedMinimumDelay = m_stepMinimumDelayWalk; break; case MyCharacterMovement.Fast: usedMinimumDelay = m_stepMinimumDelayRun; break; case MyCharacterMovement.VeryFast: usedMinimumDelay = m_stepMinimumDelaySprint; break; } } bool minimumDelayExceeded = false; minimumDelayExceeded = (MySandboxGame.TotalGamePlayTimeInMilliseconds - m_lastStepTime) >= usedMinimumDelay; //MyRenderProxy.DebugDrawAABB(m_character.PositionComp.WorldAABB, Color.White); if (minimumDelayExceeded) { int leftAnkleBoneIndex, rightAnkleBoneIndex; MyCharacterBone leftAnkleBone = m_character.AnimationController != null ? m_character.AnimationController.FindBone(m_character.Definition.LeftAnkleBoneName, out leftAnkleBoneIndex) : null; MyCharacterBone rightAnkleBone = m_character.AnimationController != null ? m_character.AnimationController.FindBone(m_character.Definition.RightAnkleBoneName, out rightAnkleBoneIndex) : null; Vector3 posLeftFoot = leftAnkleBone != null ? leftAnkleBone.AbsoluteTransform.Translation : m_character.PositionComp.LocalAABB.Center; Vector3 posRightFoot = rightAnkleBone != null ? rightAnkleBone.AbsoluteTransform.Translation : m_character.PositionComp.LocalAABB.Center; float ankleHeight; MyFeetIKSettings settingsIK; if (m_character.Definition.FeetIKSettings != null && m_character.Definition.FeetIKSettings.TryGetValue(MyCharacterMovementEnum.Standing, out settingsIK)) { ankleHeight = settingsIK.FootSize.Y; } else { ankleHeight = DEFAULT_ANKLE_HEIGHT; } float charSpeed = 0f; if (m_character.AnimationController != null) { m_character.AnimationController.Variables.GetValue(MyAnimationVariableStorageHints.StrIdSpeed, out charSpeed); } if (posLeftFoot.Y - ankleHeight < m_character.PositionComp.LocalAABB.Min.Y || posRightFoot.Y - ankleHeight < m_character.PositionComp.LocalAABB.Min.Y) { if (charSpeed > 0.05f) { walkEmitter.PlaySound(cueEnum); } m_lastStepTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; } } m_lastUpdateMovementState = movementState; }
private MySoundPair SelectSound() { MySoundPair soundPair = EmptySoundPair; MyCharacterDefinition myCharDefinition = m_character.Definition; MyStringHash physMaterial = MyStringHash.GetOrCompute(myCharDefinition.PhysicalMaterial); m_isWalking = false; bool updateEmitterSounds = false; MyCharacterMovementEnum movementState = m_character.GetCurrentMovementState(); switch (movementState) { case MyCharacterMovementEnum.Walking: case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingRightFront: case MyCharacterMovementEnum.WalkingLeftBack: case MyCharacterMovementEnum.WalkingRightBack: case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.WalkStrafingRight: { if (m_character.Breath != null) { m_character.Breath.CurrentState = MyCharacterBreath.State.Calm; } soundPair = MyMaterialPropertiesHelper.Static.GetCollisionCue(MovementSoundType.Walk, physMaterial, RayCastGround()); m_isWalking = true; } break; case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftFront: case MyCharacterMovementEnum.RunningLeftBack: { if (m_character.Breath != null) { m_character.Breath.CurrentState = MyCharacterBreath.State.Heated; } soundPair = MyMaterialPropertiesHelper.Static.GetCollisionCue(MovementSoundType.Run, physMaterial, RayCastGround()); m_isWalking = true; } break; case MyCharacterMovementEnum.CrouchWalking: case MyCharacterMovementEnum.CrouchBackWalking: case MyCharacterMovementEnum.CrouchWalkingLeftFront: case MyCharacterMovementEnum.CrouchWalkingRightFront: case MyCharacterMovementEnum.CrouchWalkingLeftBack: case MyCharacterMovementEnum.CrouchWalkingRightBack: case MyCharacterMovementEnum.CrouchStrafingLeft: case MyCharacterMovementEnum.CrouchStrafingRight: { if (m_character.Breath != null) { m_character.Breath.CurrentState = MyCharacterBreath.State.Calm; } soundPair = MyMaterialPropertiesHelper.Static.GetCollisionCue(MovementSoundType.CrouchWalk, physMaterial, RayCastGround()); m_isWalking = true; } break; case MyCharacterMovementEnum.Crouching: case MyCharacterMovementEnum.Standing: { if (m_character.Breath != null) { m_character.Breath.CurrentState = MyCharacterBreath.State.Calm; } var previousMovementState = m_character.GetPreviousMovementState(); var currentMovementState = m_character.GetCurrentMovementState(); if (previousMovementState != currentMovementState && (previousMovementState == MyCharacterMovementEnum.Standing || previousMovementState == MyCharacterMovementEnum.Crouching)) { soundPair = (currentMovementState == MyCharacterMovementEnum.Standing) ? CharacterSounds[(int)CharacterSoundsEnum.CROUCH_UP_SOUND] : CharacterSounds[(int)CharacterSoundsEnum.CROUCH_DOWN_SOUND]; } } break; case MyCharacterMovementEnum.Sprinting: { if (m_character.Breath != null) { m_character.Breath.CurrentState = MyCharacterBreath.State.VeryHeated; } soundPair = MyMaterialPropertiesHelper.Static.GetCollisionCue(MovementSoundType.Sprint, physMaterial, RayCastGround()); m_isWalking = true; } break; case MyCharacterMovementEnum.Jump: { if (!m_jumpReady) { break; } m_jumpReady = false; m_character.SetPreviousMovementState(m_character.GetCurrentMovementState()); var emitter = MyAudioComponent.TryGetSoundEmitter(); // We need to use another emitter otherwise the sound would be cut by silence next frame if (emitter != null) { emitter.Entity = m_character; emitter.PlaySingleSound(CharacterSounds[(int)CharacterSoundsEnum.JUMP_SOUND]); } if ((m_standingOnGrid != null || m_standingOnVoxel != null) && ShouldUpdateSoundEmitters) { updateEmitterSounds = true; } m_standingOnGrid = null; m_standingOnVoxel = null; } break; case MyCharacterMovementEnum.Flying: { if (m_character.Breath != null) { m_character.Breath.CurrentState = MyCharacterBreath.State.Calm; } if (m_character.JetpackComp != null && m_jetpackMinIdleTime <= 0f && m_character.JetpackComp.FinalThrust.LengthSquared() >= 50000f) { soundPair = CharacterSounds[(int)CharacterSoundsEnum.JETPACK_RUN_SOUND]; m_jetpackSustainTimer = Math.Min(JETPACK_TIME_BETWEEN_SOUNDS, m_jetpackSustainTimer + MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } else { soundPair = CharacterSounds[(int)CharacterSoundsEnum.JETPACK_IDLE_SOUND]; m_jetpackSustainTimer = Math.Max(0f, m_jetpackSustainTimer - MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } m_jetpackMinIdleTime -= MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; if ((m_standingOnGrid != null || m_standingOnVoxel != null) && ShouldUpdateSoundEmitters) { updateEmitterSounds = true; } m_standingOnGrid = null; m_standingOnVoxel = null; } break; case MyCharacterMovementEnum.Falling: { if (m_character.Breath != null) { m_character.Breath.CurrentState = MyCharacterBreath.State.Calm; } if ((m_standingOnGrid != null || m_standingOnVoxel != null) && ShouldUpdateSoundEmitters) { updateEmitterSounds = true; } m_standingOnGrid = null; m_standingOnVoxel = null; } break; default: { } break; } //MyRenderProxy.DebugDrawText2D(Vector2.Zero, movementState.ToString(), Color.Red, 1.0f); if (movementState != MyCharacterMovementEnum.Flying) { m_jetpackSustainTimer = 0f; m_jetpackMinIdleTime = 0.5f; } if (updateEmitterSounds) { MyEntity3DSoundEmitter.UpdateEntityEmitters(true, true, false); } return(soundPair); }
void MovementStateChanged(MyCharacterMovementEnum oldState, MyCharacterMovementEnum newState) { if (newState == MyCharacterMovementEnum.Died) { Alive = false; } }