Exemple #1
0
        private void DrawPointingDirectionTriangle()
        {
            if (CurrentViewedTank == null || !CurrentViewedTank.Alive)
            {
                return;
            }
            //This code does exactly what it sounds like.
            //It draws an arrow to show which direction the cursor is pointing.
            //It's here because turning has a delayed rection (intentional) so we wanna
            //show where the turret is going to end up.

            //First, get the view rectangle
            var viewRect = ComputeDrawRectangle(CurrentViewedTank);

            //Begin drawing in that area
            //_spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, null,
            //   Matrix.CreateOrthographicOffCenter(viewRect.Left, viewRect.Right, viewRect.Bottom, viewRect.Top, -1, 1));

            var tankPos   = CurrentViewedTank.Position;
            var lookPoint = InputDriver.GetInputState().LookDirection - MathHelper.PiOver2;

            //Check if we're spectating
            if (CurrentViewedTank != Client?.Player?.Tank)
            {
                lookPoint = CurrentViewedTank.InputState.LookDirection - MathHelper.PiOver2;
            }

            //Radius of circle = 5
            //And solve the triangle
            var cursorPos = new Vector2(
                5f * (float)Math.Cos(lookPoint),
                5f * (float)Math.Sin(lookPoint)
                ) + tankPos;

            //
            //     0,.5
            //
            //-0.5,-.5|0,-0.5|.5,-.5
            //Triangle points
            var pts = new[] {
                new Vector2(0, 0.5f),
                new Vector2(-0.5f),
                new Vector2(.5f, -.5f)
            };

            pts = pts.Select(a => RotatePoint(a, lookPoint - MathHelper.PiOver2, Vector2.Zero) + cursorPos).ToArray();

            _fx.Alpha = 0.33f;
            _fx.VertexColorEnabled = true;
            _fx.World = Matrix.CreateOrthographicOffCenter(viewRect.Left, viewRect.Right, viewRect.Bottom, viewRect.Top, -1, 1);
            foreach (var pass in _fx.CurrentTechnique.Passes)
            {
                pass.Apply();
                var vpc = pts.Select(a => new VertexPositionColor(new Vector3(a, 0), Color.Red)).ToArray();
                GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vpc, 0, 1);
            }
        }
Exemple #2
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>

        protected override void Update(GameTime gameTime)
        {
            _ui.Update(gameTime);
            SoundPlayer.Update(gameTime);

            if (!_hasInitialized || _closing)
            {
                return;
            }

            if (CurrentViewedTank != null && SoundPlayer != null)
            {
                SoundPlayer.PlayerPosition = CurrentViewedTank.Position;
                SoundPlayer.PlayerVelocity = CurrentViewedTank.LinearVelocity;
            }
            SoundPlayer?.Update(gameTime);

            Diagnostics.BeginMeasurement("Base.Update() & UI Update");
            base.Update(gameTime);
            Diagnostics.EndMeasurement("Base.Update() & UI Update");

            if (_modLoader.Running)
            {
                _ui.UpdateState(new
                {
                    Header  = "Loading mods...",
                    Content = _modLoader.Status,
                    Button  = "Cancel"
                });
                return;
            }
            else if (!_hasExecutedModLoaderInit)
            {
                _hasExecutedModLoaderInit = true;
                CreateGame();
                return;
            }
            if (!_isInPauseMenu)
            {
                InputDriver.Update(gameTime);
                var state = InputDriver.GetInputState();
                if (Client?.Input != null && state != Client.Input)
                {
                    Client.Input = state;
                }
            }

            if (AOTConfig.IsGameHost)
            {
                Server.Update(gameTime);
            }

            Client.Update(gameTime);
            if (Client?.Player?.Tank != null && Client.Player.Tank.Alive)
            {
                CurrentViewedTank = Client.Player.Tank;
            }

            if (_isInPauseMenu)
            {
                return; //Don't mess with the pause menu
            }
            if (Client.IsInTankSelection)
            {
                DeactivateGameInput();
                _ui.GoToPageIfNotThere("tankselectionpromptwithcountdown", page =>
                {
                    page.Element <Button>("UnReadyButton").Click += (a, b) =>
                    {
                        page.Element <Button>("ConfirmButton").Visibility         = EmptyKeys.UserInterface.Visibility.Visible;
                        page.Element <StackPanel>("tankselectionarea").Visibility = EmptyKeys.UserInterface.Visibility.Visible;
                        page.Element <StackPanel>("readyarea").Visibility         = EmptyKeys.UserInterface.Visibility.Collapsed;
                        Client.PlayerIsReady = false;
                    };
                    page.Element <Button>("ConfirmButton").Click += (a, b) =>
                    {
                        page.Element <Button>("ConfirmButton").Visibility         = EmptyKeys.UserInterface.Visibility.Collapsed;
                        page.Element <StackPanel>("tankselectionarea").Visibility = EmptyKeys.UserInterface.Visibility.Collapsed;
                        page.Element <StackPanel>("readyarea").Visibility         = EmptyKeys.UserInterface.Visibility.Visible;

                        Client.PlayerIsReady = true;
                    };
                }, (page, state) =>
                {
                    page.Element <TextBlock>("Subscript").Text =
                        page.State <double>("RemainingCountdown").ToString("N0") + " seconds remaining " +
                        (Client.PlayerIsReady ? "until start" : "to choose");

                    //And update tank options
                    var options = page.Element <StackPanel>("tankoptions");
                    if (page.State <string[]>("TankOptions") != null)
                    {
                        foreach (var opt in page.State <string[]>("TankOptions"))
                        {
                            if (options.Children.FirstOrDefault(a => a.Name == "opt_" + opt) != null)
                            {
                                //already in there
                                //so we do nothing
                            }
                            else
                            {
                                string reflectionName = opt; //Copy to avoid problems with closures
                                var info = Engine.Helpers.ReflectionHelper.GetGameObjectInfo(reflectionName);
                                if (!info.Exists)
                                {
                                    continue;               //If the type doesn't exist, continue without showing it
                                }
                                //not in there, so make it
                                var btn = new Button();
                                //Content is a stack panel
                                var stackPnl                 = new StackPanel();
                                stackPnl.Orientation         = EmptyKeys.UserInterface.Orientation.Vertical;
                                stackPnl.HorizontalAlignment = EmptyKeys.UserInterface.HorizontalAlignment.Stretch;
                                stackPnl.Children.Add(new TextBlock
                                {
                                    FontFamily          = new EmptyKeys.UserInterface.Media.FontFamily("JHUF"),
                                    FontSize            = 20,
                                    Foreground          = EmptyKeys.UserInterface.Media.Brushes.White,
                                    Text                = info.DisplayName,
                                    Margin              = new EmptyKeys.UserInterface.Thickness(0, 5, 0, 0),
                                    Width               = 350,
                                    HorizontalAlignment = EmptyKeys.UserInterface.HorizontalAlignment.Stretch
                                });
                                stackPnl.Children.Add(new TextBlock
                                {
                                    FontFamily          = new EmptyKeys.UserInterface.Media.FontFamily("JHUF"),
                                    FontSize            = 16,
                                    Foreground          = EmptyKeys.UserInterface.Media.Brushes.White,
                                    Margin              = new EmptyKeys.UserInterface.Thickness(0, 5, 0, 5),
                                    Text                = UserInterface.SplitStringIntoLines(info.DisplayDescription, 40),
                                    HorizontalAlignment = EmptyKeys.UserInterface.HorizontalAlignment.Center
                                });

                                btn.Background          = EmptyKeys.UserInterface.Media.Brushes.Gray;
                                btn.Content             = stackPnl;
                                btn.Name                = "opt_" + reflectionName;
                                btn.HorizontalAlignment = EmptyKeys.UserInterface.HorizontalAlignment.Center;
                                btn.Width               = 400;
                                btn.Click              += (a, b) =>
                                {
                                    options.Children.Select(c => (c as Button).Background = EmptyKeys.UserInterface.Media.Brushes.Transparent);
                                    btn.Background = EmptyKeys.UserInterface.Media.Brushes.Green;

                                    Client.SelectTank(reflectionName);
                                };
                                options.Children.Add(btn);
                            }
                        }
                    }
                });
                if (Client.Player != null)
                {
                    _ui.UpdateState(new
                    {
                        TankOptions        = Client.Player.AllowedTankTypes,
                        RemainingCountdown = Client.RemainingCountdownTime.TotalSeconds
                    });
                }
            }
            else if (Client.IsInGame && !Client.Game.Ended && !_ui.IsOnEmpty())
            {
                _ui.UnwindAndEmpty();
            }
            else if (Client.IsInGame)
            {
                ActivateGameInput();

                //Handle spectating
                if (!_spectateHasSwitchedTank && CurrentViewedTank != null && !CurrentViewedTank.Alive)
                {
                    Client.Game.TimerFactory.CreateTimer((t) =>
                    {
                        SpectateRandomTank();
                        _spectateHasSwitchedTank = false;
                    },
                                                         TimeSpan.FromSeconds(3));
                    _spectateHasSwitchedTank = true;
                }
                if (Client.Game.Ended)
                {
                    _ui.GoToPageIfNotThere("gameendedpage", page => { }, (page, state) =>
                    {
                        var winningTeam = Client.Game.Gamemode.WinningTeam;
                        bool winner     = (Client.Player?.Tank.Team == winningTeam);

                        page.Element <TextBlock>("Header").Text = winner ? "You're Winner" : "You Tried";
                        if (winningTeam == Engine.Gamemodes.Team.Indeterminate)
                        {
                            page.Element <TextBlock>("Subscript").Text = "It's a draw";
                        }
                        else if (winningTeam == Engine.Gamemodes.Team.Null)
                        {
                            page.Element <TextBlock>("Subscript").Text = "This gamemode has a bug..."; //Wow, so much faith in the game's implementation
                        }
                        else
                        {
                            page.Element <TextBlock>("Subscript").Text = winningTeam.TeamName + " won";
                        }

                        page.Element <Image>("Star").Visibility =
                            winner ? EmptyKeys.UserInterface.Visibility.Collapsed :
                            EmptyKeys.UserInterface.Visibility.Visible;

                        if (winningTeam?.Players != null)
                        {
                            page.Element <TextBlock>("PlayerList").Text = string.Join("\n", winningTeam.Players.Select(a => a.Username));
                        }
                    }, new { });
                    _ui.UpdateState(new object());
                }
            }
            else
            {
                DeactivateGameInput();
                if (!_ui.IsOnPage("settingupprompt"))
                {
                    ShowSetupPrompt();
                }
                switch (Client.Status)
                {
                case NetClient.ClientStatus.Authenticating:
                    _ui.UpdateState(new
                    {
                        Header  = "Logging in...",
                        Content = "Authenticating with the ZSB servers",
                        Button  = "Cancel"
                    });
                    break;

                case NetClient.ClientStatus.Connected:
                    _ui.UpdateState(new
                    {
                        Header  = "Connected...",
                        Content = "Waiting for the server to respond",
                        Button  = "Leave server"
                    });
                    break;

                case NetClient.ClientStatus.Connecting:
                    _ui.UpdateState(new
                    {
                        Header  = "Connecting to the server...",
                        Content = Client.Message,
                        Button  = "Abort"
                    });
                    break;

                case NetClient.ClientStatus.Disconnected:
                    _closing = true;
                    _ui.ShowMessageBox("Disconnected", Client.Message, UserInterface.MessageBoxType.ErrorMessageBox,
                                       UserInterface.MessageBoxButtons.Ok, a => Exit());
                    break;

                case NetClient.ClientStatus.DownloadingMods:
                    _ui.UpdateState(new
                    {
                        Header  = "Downloading mods...",
                        Content = "This may take a a while",
                        Button  = "Leave server"
                    });
                    break;

                case NetClient.ClientStatus.Errored:
                    _ui.UpdateState(new
                    {
                        Header  = "A fatal error has occured",
                        Content = "",
                        Button  = "Set my hair on fire and leave"
                    });
                    break;

                case NetClient.ClientStatus.NotStarted:
                    _ui.UpdateState(new
                    {
                        Header  = "Waiting to connect...",
                        Content = "This shouldn't usually happen",
                        Button  = "Stare with contempt"
                    });
                    break;
                }
            }

            if (GameSettings.Instance.ForceFullGCEveryFrame)
            {
                GC.Collect(2, GCCollectionMode.Forced, true);
            }
        }