SOLVED: "Neutral" inventory spacing?

Started by Tamanegi, Sun 28/11/2010 19:28:27

Previous topic - Next topic

Tamanegi

What I'd like to do is an inventory GUI that displays each item in a separate "window" in the GUI. I thought I could best archieve that by just having one big window with frames as a background image and spacing between the items.

What happens when I set ItemHeight and ItemWidth to a few pixels more so the images are a little bit apart is that even the extra spacing counts as the item, which is not what I want. Having it checked pixel-perfect isn't a viable option because of the nature of some item images.

Is there a way to have "neutral" spacing between the items that isn't clickable?
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

monkey0506

The only way I know of is that if you have a fixed-space grid, create a sprite of the grid outline, and import that as the background of a non-clickable Button with a higher Z-order than the InvWindow.

Tamanegi

For that to work I'd have to make many many "buttons" that divide the slots. I can't just make one big stencil because transparent pixels still block clicking what's underneath.

While that would work, maybe there is a more elegant solution?
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

monkey0506

With pixel-perfect click detection transparent pixels shouldn't absorb clicks.. ???

Or at least I'd think you could just make it clickable and just not do anything in the interaction event handler..?

What else you could possibly do is if you have a fixed-size grid you could manually calculate the item the user actually clicked on via the script:

Code: ags
InventoryItem* GetInventoryItemAt(int x, int y)
{
  InventoryItem *theItem = InventoryItem.GetAtScreenXY(x, y);
  if (theItem == null) return null;
  x -= (invInvWindow.X + invInvWindow.OwningGUI.X);
  y -= (invInvWindow.Y + invInvWindow.OwningGUI.Y);
  if ((x < 0) || (y < 0)) return null; // this shouldn't happen at this point anyway??
  x = (x / invInvWindow.ItemWidth);
  y = (y / invInvWindow.ItemHeight);
  if ((x > Game.SpriteWidth[theItem.Graphic]) || (y > Game.SpriteHeight[theItem.Graphic])) return null;
  return theItem;
}


Then you'd have to handle all inventory item clicking manually (meaning you can't even rely on on_mouse_click(eMouseLeftInv)):

Code: ags
function on_event(EventType event, int data)
{
  if (event == eEventGUIMouseUp)
  {
    InventoryItem *iat = GetInventoryItemAt(mouse.x, mouse.y);
    if (iat == null) return;
    // inventory item processing here..such as:
    if (iat.IsInteractionAvailable(mouse.Mode)) iat.RunInteraction(mouse.Mode);
    else if (mouse.Mode == eModeInteract) player.ActiveInventory = iat;
    // else..unhandled_event?
  }
}

Tamanegi

Quote from: monkey_05_06 on Sun 28/11/2010 23:57:03
With pixel-perfect click detection transparent pixels shouldn't absorb clicks.. ???
Ah right, I didn't think about that... but pixel-perfect click detection is not built in, right? At least, I didn't find it in the editor.

Quote
Or at least I'd think you could just make it clickable and just not do anything in the interaction event handler..?
Then it would still block clicking anything underneath  :(

Quote
What else you could possibly do is if you have a fixed-size grid you could manually calculate the item the user actually clicked on via the script:
That was one option I was actually considering at first, but I didn't quite catch how exactly to use pointers... I used pointers in school with Turbo Pascal so I know the general concept, but I can't figure out how they are used in AGS, maybe because I don't really know neither Java nor C++.
Maybe your script will help me understand it, thank you for that!  :D
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

Khris

It should be possible to do the check within on_mouse_click:

Code: ags
// above on_mouse_click

bool OutsideItem(InvWindow*iw, int b) {
  int x = mouse.x - (iw.X + iw.OwningGUI.X);
  int y = mouse.y - (iw.Y + iw.OwningGUI.Y);
  return (x >= b && x < iw.ItemWidth - b && y >= b && y < iw.ItemHeight - b);
} 

// in on_mouse_click, before clicks are handled:

  if ((button == eMouseLeftInv || button == eMouseRightInv) && OutsideItem(invCustomInv, 10)) return;

  // standard handling of clicks


This will ignore clicks on inventory items less than 10 pixels away from the edges.

If you're using an additional script for general purpose functions or something, this will also work:
Code: ags
void on_mouse_click(MouseButton button) {
  if ((button == eMouseLeftInv || button == eMouseRightInv) && OutsideItem(invCustomInv, 10)) ClaimEvent();
}


That way you can separate the border click handling from clicks that do something. Tidier, is all.

Tamanegi

Thank you, I went with the tiled border now because I figured out how to make the inventory work how I imagined without overriding the click functions  :D
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

SMF spam blocked by CleanTalk