/// <summary> /// The OpenXR plug-in uses extensions to expose all possible data, which might be surfaced through multiple input devices. /// This method is overridden to account for multiple input devices and reuse MRTK controllers if a match is found. /// </summary> protected override void RemoveController(InputDevice inputDevice) { using (RemoveControllerPerfMarker.Auto()) { foreach (InputDevice device in ActiveControllers.Keys) { if (device != inputDevice && ((device.characteristics.HasFlag(InputDeviceCharacteristics.Controller) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Controller)) || (device.characteristics.HasFlag(InputDeviceCharacteristics.HandTracking) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.HandTracking))) && ((device.characteristics.HasFlag(InputDeviceCharacteristics.Left) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Left)) || (device.characteristics.HasFlag(InputDeviceCharacteristics.Right) && inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.Right)))) { ActiveControllers.Remove(inputDevice); // Since an additional device exists, return so a lost source isn't reported return; } } base.RemoveController(inputDevice); } }
public override void Update(GameTime time) { var elapsedSeconds = (float)time.ElapsedGameTime.TotalSeconds; Session.GameTime += elapsedSeconds; Session.FocussedEntity = null; // Remove finished graphics events var graphicsEffects = Session.World.GraphicsEvents.Where(e => e.End < Session.GameTime).ToArray(); foreach (var e in graphicsEffects) { Session.World.GraphicsEvents.Remove(e); } if (Session.UsePlayerTurns) { if (Session.ActivePlayer == null) { Session.ActivePlayer = Session.Players[0]; } Session.TurnTime += elapsedSeconds; if (Session.TurnTime > Session.SecondsPerTurn && Session.TurnState == TurnState.Running) { EndTurn(); } // End the turn if the turn is over and MinSecondsBetweenTurns have passed. // Wait for all entities to stand still, but at most MaxSecondsBetweenTurns. if (Session.TurnState == TurnState.WaitingForEnd && (Session.TurnTime > Session.MaxSecondsBetweenTurns || (Session.TurnTime > Session.MinSecondsBetweenTurns && !Session.World.IsSomethingMoving)) ) { StartNextTurn(); } } var worldState = Session.World; if (Game.Match.State == SessionState.Running && !Session.IsRemoteControlled) { // Update all active balls var currentControllers = ActiveControllers.Values.ToArray(); foreach (var controller in currentControllers) { if (controller != null && controller.Ball.Player.IsLocal && (controller.Ball.Player == Session.ActivePlayer || !Session.UsePlayerTurns)) { var playerMadeAction = controller.Update(elapsedSeconds, worldState); if (playerMadeAction) { EndTurn(); } } } // Check for dead balls List <Player> alivePlayers = new List <Player>(); Player winner = null; var ballControllers = BallControllers.Values.ToArray(); foreach (var controller in ballControllers) { if (controller.Ball.Disposed || !controller.Ball.IsAlive) { controller.Ball.Player.OwnedBalls.Remove(controller.Ball); if (controller.Ball.Player == Session.ActivePlayer) { StartNextTurn(); } ActiveControllers.Remove(controller.Ball.Player); BallControllers.Remove(controller.Ball); } else if (controller.Ball.IsAlive) { if (!alivePlayers.Contains(controller.Ball.Player)) { alivePlayers.Add(controller.Ball.Player); } winner = controller.Ball.Player; } } //TODO: find proper game finished condition, this one is not always correct if (alivePlayers.Count < 2) { Game.Match.State = SessionState.Finished; //TODO: find proper condition to determine the winner, this one is not always correct if (alivePlayers.Count == 1) { Game.Match.Winner = winner; Game.Services.GetService <Sound.SoundControl>().PlaySound(Sound.SoundControl.WinnerSounds[winner.TeamName]); } } } }