0
\$\begingroup\$

I am creating an inventory system. I have it working well, but for some reason when I pick up an item from a slot(lets say slot 2 of 20) and drop it into that same slot(slot 2) the mouse state fails to update correctly, resulting in the item being dropped and picked back up in the same cycle. I feel like I am missing something here, but would appreciate any help. Below is my code.

The method that controls the Item being Dropped into the inventory:

    public void ItemDropped(Vector2 pos, Item item)
    {
        for (int intlc = 0; intlc < InvBoxes.Count; intlc++)
        {
            if (InvBoxes[intlc].Intersects(new Rectangle((int)pos.X, (int)pos.Y, 1, 1)))
            {
                if (Items[intlc] != null)
                {
                    ClampedItem = Items[intlc];
                }
                else
                {
                    //Set bln in Game to stop drawing item at cursor
                    ClampedItem = null;
                    GlobalVariables.TheGame.blnClamp = false;
                }
                Items[intlc] = item;
                break;
            }
        }
    }

Logic in my Inventory Class' Update method to Update the mouse state, after setting the old mouse state. Then it check for hovering over an item, and sets all old hovers to false. It then looks for if I am clicking on the item hovered over, and therein lies the problem :

        oms = ms;
        ms = Mouse.GetState();

        //set hover
        for (int intlc = 0; intlc < Items.Count; intlc++)
        {
            if (Items[intlc] != null)
            {
                if ((ms.X - Items[intlc].location.X) < 50 && (ms.X - Items[intlc].location.X) > 0 && (ms.Y - Items[intlc].location.Y) < 30 && (ms.Y - Items[intlc].location.Y) > 0)
                {
                    Items[intlc].invhover = true;
                }
                else
                {
                    Items[intlc].invhover = false;
                }
            }
        }

            for (int intlc = 0; intlc < Items.Count; intlc++)
            {
                if (Items[intlc] != null)
                {
                    if (Items[intlc].invhover)
                    {

                        if (ms.LeftButton == ButtonState.Pressed && oms.LeftButton == ButtonState.Released)
                        {
                            ClampedItem = Items[intlc];
                            Items[intlc] = null;
                            GlobalVariables.TheGame.blnClamp = true;
                        }
                    }
                }
            }

In my game Class at the end of the the Update I have a few calls that pertain to this issue :

        Rectangle rect = new Rectangle(mouseState.X, mouseState.Y, 1, 1);

        if (blnClamp)
        {
            if (rect.Intersects(inventory.Bounds) && mouseState.LeftButton == ButtonState.Pressed && MoldState.LeftButton == ButtonState.Released)
            {
                inventory.ItemDropped(new Vector2(mouseState.X, mouseState.Y), inventory.ClampedItem);
            }
        }

        inventory.Update(InvPos);

If you look at the conditional in my game's inventory's Update method's check for mouse state's current and old button state being pressed and released, when I grab an item from slot 1 and drop it into slot 2, the mouse state conditional validate as intended. But when trying to grab the item at slot 1 and drop it back into slot one, the item drops, and is immediately clamped again because old mouse state is up and new mouse state is down. Both instances will hit the conditional that is inside the hover conditional.

Additional Note : When I put a breakpoint on the ItemDropped Method inside my inventory class, the debugger causes the mouse state to update as intended, and the item that I picked up out of slot 2 is placed into slot 2 without fail. There is a flaw programatically to how I have my updates set up somehow.

\$\endgroup\$
0
\$\begingroup\$

After a good nights rest, I have worked out the solution.

By moving the problem logic :

        for (int intlc = 0; intlc < Items.Count; intlc++)
        {
            if (Items[intlc] != null)
            {
                if (Items[intlc].invhover)
                {

                    if (ms.LeftButton == ButtonState.Pressed && oms.LeftButton == ButtonState.Released)
                    {
                        ClampedItem = Items[intlc];
                        Items[intlc] = null;
                        GlobalVariables.TheGame.blnClamp = true;
                    }
                }
            }
        }

Into its own method I have the following code in my Inventory class :

    public void GrabItem()
    {
        for (int intlc = 0; intlc < Items.Count; intlc++)
        {
            if (Items[intlc] != null)
            {
                if (Items[intlc].invhover)
                {
                        ClampedItem = Items[intlc];
                        Items[intlc] = null;
                        GlobalVariables.TheGame.blnClamp = true;
                }
            }
        }
    }

In my game class, I have conditionals to pick up, and drop the item as follows :

        if (rect.Intersects(inventory.Bounds) && mouseState.LeftButton == ButtonState.Pressed && MoldState.LeftButton == ButtonState.Released)
        {
            if (blnClamp)
            {
                    inventory.ItemDropped(new Vector2(mouseState.X, mouseState.Y), inventory.ClampedItem);
            }
            else
            {
                inventory.GrabItem();
            }
        }

By checking the Mouse State from within the Game class, I was able to get my methods to fire as I intended them to. Perhaps it is best to always check against mouse state and position from the game class, always firing a method in a child class from the parent level.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.