Exemplo n.º 1
0
        ///
        /// <summary>
        ///		Performs an update tick on the game object.
        /// </summary>
        ///
        /// <param name="gameTime">Time passed since the last call to Update.</param>
        ///
        protected override void Update(GameTime gameTime)
        {
            // Get the keyboard/mouse states.
            k = Keyboard.GetState();
            m = Mouse.GetState();

            IsMouseVisible = !mouseLocked;

            // Make sure the game switches to an unfocused state when not active.

            if (!this.IsActive)
            {
                if (this.gameState.Equals(GameState.Running))
                {
                    this.gameState = GameState.Unfocused;
                }
            }


            handleNetworkMessages();

            switch (this.gameState)
            {
            // The client and server has connected successfully, now waiting for the game data to be loaded over.
            case GameState.ConnectingLoading:

                if (world != null)
                {
                    gameState = GameState.Running;
                }

                break;


            // After many attempts, the connection to the server has failed.
            case GameState.ConnectionFailed: break;


            // Attempts are being made to connect to the server.
            case GameState.Connecting:

                if (client.ConnectionStatus.Equals(NetConnectionStatus.Connected))
                {
                    Thread.Sleep(750);

                    // Get the world from the server.
                    NetOutgoingMessage refreshRequest = client.CreateMessage();
                    refreshRequest.Write(NETWORK_REFRESH_REQUEST);
                    client.SendMessage(refreshRequest, NetDeliveryMethod.ReliableOrdered);

                    gameState = GameState.ConnectingLoading;
                }
                else
                {
                    if (connectionAttemptTimer >= 70)
                    {
                        // Discover the server...
                        Console.WriteLine("Attempting connection with server at {0}:{1}...", serverIP, 1945, client.ConnectionStatus, client.Status);
                        client.DiscoverKnownPeer(serverIP, 1945);
                        handleNetworkMessages();

                        connectionAttempts++;


                        if (connectionAttempts >= 10)
                        {
                            gameState = GameState.ConnectionFailed;
                        }

                        connectionAttemptTimer = 0;
                    }
                    else
                    {
                        connectionAttemptTimer++;
                    }
                }

                break;


            // The game is running normally.
            case GameState.Running:
            case GameState.RunningInventory:

                switch (gameState)
                {
                case GameState.Running:
                case GameState.RunningInventory:

                    // Find out how far the mouse has moved since the last upate.
                    Vector2 lookMovement = Vector2.Zero;
                    if (mouseLocked && gameState.Equals(GameState.Running))
                    {
                        lookMovement = new Vector2(
                            m.X - (graphics.PreferredBackBufferWidth / 2),
                            m.Y - (graphics.PreferredBackBufferHeight / 2));
                    }


                    // Update the world.
                    if (world != null)
                    {
                        world.update(GameSide.Client, k, lookMovement);
                    }

                    // Update the current action.
                    if (currentAction != null)
                    {
                        if (currentAction.tick())
                        {
                            currentAction.perform(client, world, world.player.skills, ref notifications);
                            currentAction = null;
                        }
                    }

                    break;
                }


                #region 3D View

                // Move the camera with the player.
                if (world != null)
                {
                    camera.position = world.player.position + new Vector3(0.0F, world.player.height * 0.90F, 0.0F);
                    camera.target   = world.player.lookTarget;
                }

                #endregion


                #region Tile Cursor

                if (contextMenu == null)
                {
                    // Determine if there are any tile cursors.
                    Vector3 rayStart     = camera.position;
                    Vector3 rayDirection = camera.target - camera.position;
                    rayDirection.Normalize();
                    Point?currentTile = world.getSelectedTile(camera);

                    if (currentTile.HasValue)
                    {
                        tileCursorEnabled  = true;
                        tileCursorPosition = currentTile.Value;
                    }
                    else
                    {
                        tileCursorEnabled = false;
                    }
                }

                // Move the tile name indicator back & forth.
                if (tileCursorEnabled)
                {
                    indicatorOffset += (50.0F - indicatorOffset) / 10.0F;
                }
                else
                {
                    indicatorOffset += (0.0F - indicatorOffset) / 10.0F;
                }


                // Allow the context menu to be opened
                if (gameState.Equals(GameState.Running) ||
                    gameState.Equals(GameState.RunningInventory))
                {
                    if (m.RightButton.Equals(ButtonState.Pressed) &&
                        canOpenContextMenu &&
                        tileCursorEnabled)
                    {
                        contextMenu = new ContextMenu(
                            world.player.skills,
                            tileCursorPosition,
                            world,
                            null);

                        mouseLocked        = false;
                        canOpenContextMenu = false;
                    }


                    if (contextMenu == null &&
                        m.RightButton.Equals(ButtonState.Released))
                    {
                        canOpenContextMenu = true;
                    }


                    // Allow the context menu to be closed, if clicked away from.
                    // Also, update the context menu.
                    if (contextMenu != null)
                    {
                        // Update the context menu.
                        int result = contextMenu.update(m, graphics);

                        if (result >= 0)
                        {
                            if (currentAction == null)
                            {
                                currentAction = new TimedAction(contextMenu.actionList[result], world.player.skills);

                                contextMenu = null;

                                if (gameState.Equals(GameState.Running))
                                {
                                    mouseLocked = true;
                                }
                            }
                            else
                            {
                                //TODO: Allow actions to stack.
                            }
                        }
                        else
                        {
                            // Then allow the menu to be closed.
                            Rectangle contextMenuRectangle = contextMenu.calculateSize(FontResources.interfaceFont, graphics);
                            if (m.LeftButton.Equals(ButtonState.Pressed)
                                &&
                                (
                                    m.X < contextMenuRectangle.Left ||
                                    m.X > contextMenuRectangle.Right ||
                                    m.Y < contextMenuRectangle.Top ||
                                    m.Y > contextMenuRectangle.Bottom
                                ))
                            {
                                contextMenu = null;

                                if (gameState.Equals(GameState.Running))
                                {
                                    mouseLocked = true;
                                }
                            }
                        }
                    }
                }

                #endregion


                #region Mouse Looking

                // Reset the mouse to the middle of the screen.
                if (mouseLocked && gameState.Equals(GameState.Running))
                {
                    Mouse.SetPosition(
                        graphics.PreferredBackBufferWidth / 2,
                        graphics.PreferredBackBufferHeight / 2);
                }

                #endregion


                #region Notifications

                // Update the first notification.
                if (notifications.Count >= 1)
                {
                    if (notifications[0].update())
                    {
                        notifications.RemoveAt(0);
                    }
                }

                #endregion

                break;


            // The game is not the active window.
            case GameState.Unfocused:

                // Allow the player to resume the game.
                if (this.IsActive && m.LeftButton.Equals(ButtonState.Pressed))
                {
                    this.gameState = GameState.Running;
                }

                break;


            // The game wants to quit.
            case GameState.Quitting:

                // Quit the game.
                Console.WriteLine("Game is currently in 'Quitting' state; closing.");

                client.Disconnect("Game closed");

                this.Exit();

                break;


            // Where the current Game State is unknown.
            default:

                Console.WriteLine("Error! - Unhandled Game State: " + this.gameState.ToString());
                this.Exit();

                break;
            }



            #region Inventory Window & Such

            if (gameState.Equals(GameState.RunningInventory))
            {
                world.player.inventory.update(
                    Container.WindowStyle.Inventory,
                    graphics,
                    k,
                    m,
                    ref canSelectItem,
                    world,
                    client,
                    ref contextMenu);
            }

            if (world != null)
            {
                inventoryOffset += ((gameState.Equals(GameState.RunningInventory) ? 0.0F : 700.0F) - inventoryOffset) / 4.0F;
                world.player.inventory.slideOffset = inventoryOffset;
            }

            #endregion



            // Allow the inventory to be toggled.
            #region Inventory Toggling

            if (gameState.Equals(GameState.RunningInventory) ||
                gameState.Equals(GameState.Running))
            {
                if (canToggleInventory && k.IsKeyDown(Keys.Tab))
                {
                    gameState = (gameState.Equals(GameState.Running) ? GameState.RunningInventory : GameState.Running);

                    mouseLocked = !gameState.Equals(GameState.RunningInventory);

                    contextMenu = null;

                    Mouse.SetPosition(graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight / 2);

                    canToggleInventory = false;
                }
                else if (!canToggleInventory && k.IsKeyUp(Keys.Tab))
                {
                    canToggleInventory = true;
                }
            }

            #endregion

            // Allow the game to exit.
            if (k.IsKeyDown(Keys.Escape))
            {
                gameState = GameState.Quitting;
            }


            // Update the 'old' mouse and keyboard states.
            mOld = m;
            kOld = k;


            base.Update(gameTime);
        }