Best way to implement inventory where items can be freely moved? [Solved]

Started by BrightBulb, Fri 24/08/2012 22:10:06

Previous topic - Next topic

BrightBulb

What would be the best solution for a inventory where items can be freely moved around in emtpy slots?
The main problem with the normal inventory window is that I cannot check for clicks on empty slots.

My ideas so far:

1. Using buttons. But that would be alot of them.

2. Filling up empty slots with dummy items. But only a workaround.

3.??


Khris

You can check for a click on an empty slot like this:

Code: ags
function on_event (EventType event, int data) {
  if (event == eEventGUIMouseDown && data == gInventory.ID) {
    GuiControl*gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
    InvWindow*iw = gc.AsInvWindow;
    if (!iw) return;
    int x = mouse.x - (gInventory.X + iw.X);
    int y = mouse.y - (gInventory.Y + iw.Y);
    int item_slot = (y/iw.ItemHeight)*iw.ItemsPerRow + x/iw.ItemWidth + iw.TopItem;

    // process click on slot item_slot
    ...
  }
}

The problem that remains is that you can't place an item in slot 10 when there's no item in slot 9.

So the two options are: use dummy items or code the inventory window entirely yourself.

I did the latter when I wanted to recreate the inventory of The Dig. I used two GUIs two overcome the 20 controls per GUI limit and out 20 buttons on each. It was raised to 30 since then, so one GUI might be enough?

Also, do you want an inventory like Diablo2 where bigger items take up multiple squares?

Ghost


BrightBulb

I think I'll go for an inventory where every item has the same size, so no Diablo-Inventory.

I'll make my own gui then. 30 buttons will be enough.

Thanks for the advice.

Edit: If I code it myself could I still make use of the Inventory Items in the Editor? It seems to me that without using an inventory window, I would have to organize item data (like name, cursor graphic) in an own struct.

Right now I'm thinking of using an array for the inventory slots that just holds the interger of the individual ItemID. The ItemID is part of an item struct that holds all information about all items.

Then I could check all inventory slots if it holds an item, and if it holds an item access all item information via the item struct.

Is this a good way to do it?

Khris

You can read all the information you need off of the inventory items, so yes, that should be possible. For each item button, store what the actual item is.

The question though is whether you want to create dozens (or hundreds) of RPG items by hand?

BrightBulb

I'm not quite sure I understand you correctly.

I have to input the data for the items either way (using Inventory Items properties or an own struct).

If I'm not correct what would be your suggestion?

Edit:
And how would I access inventory items from the editor? My problem is that you cannot access the items by their id number, but only by their name (like ikey). But ikey is neither integer nor string. How do I store it in an inventory slot (button)?

Khris

You can access the items using the inventory[] array.
So when you set up the inventory for the first time, you'd do something like this:
Code: ags
  int i = 1;
  int button_id;
  while (i <= Game.InventoryItemCount) {
    if (player.InventoryQuantity[i]) {
      gInventory.Controls[button_id].NormalGraphic = inventory[i].Graphic;
      // store in an array that item i is on button button_id
      button_id++;
    }
    i++;
  }

Note that inventory items have indexes from 1 to total, not 0 - total-1, like pretty much any other collection of objects.

Re creating the items, if you're going to have lots of treasure chests, creating each item individually is pretty much out of the question.
You'll need to generate lots of randomized items. Say you create 50 short swords, and give them random attack values from 2 to 9. Then sort them into different item pools, and when the player opens a chest in the game, a random number of items from a certain pool is moved to the chest.

I guess it comes down to how you want the game to work in that regard. I'm just saying it's possible and the best solution for lots of items. You can still add quest items and special, customized weapons.

BrightBulb

Man, it took me probably more than an hour to come up with a similar script you just wrote down.

But finally I got it all working now. My question is (and your last post doesn't seem to adress this) if a could make use of the inventory item editor.

Then for example I could make use of the automatical cross hair (general settings) that is drawn onto the cursor image that is stored for the item in the editor.
Right now, I just change the cursor graphic manually, so I will not get that cross hair that is linked to the cursor image in the editor.

Khris

I understood your post as asking whether you could use the data of the editor's inventory items.
If you want to use the UseInv mouse mode, you actually have to use the editor's items because only an item in possession of the current player character can be set as player.ActiveInventory.
(Although you could still code the item "storage" yourself and use a dummy inv item.)

But I guess what you want to do comes down to only changing the way items are displayed, not how they are handled internally. Basically, all you have to do is display your set of buttons instead of an InvWindow, and map all clicks on the buttons to the corresponding InvWindow clicks. The only slightly more complex thing is removing an item from the grid while it is moved.

Btw, in case you didn't know, you can use the same handler function for all buttons. Create the first button's on click function as usual, then paste its name into the other buttons' on click event fields. Then check for the .ID of the GUIControl that's provided as the function's parameter.

BrightBulb

Well, I scripted item handling myself now, and so far it seems to work.

And yes I use the same function for all 30 buttons. The control.ID command makes the script way shorter.

Thank you very much for your assistance.

SMF spam blocked by CleanTalk