Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Tamanegi on Sun 28/11/2010 19:28:27

Title: SOLVED: "Neutral" inventory spacing?
Post by: Tamanegi on Sun 28/11/2010 19:28:27
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?
Title: Re: "Neutral" inventory spacing?
Post by: monkey0506 on Sun 28/11/2010 21:33:58
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.
Title: Re: "Neutral" inventory spacing?
Post by: Tamanegi on Sun 28/11/2010 22:45:13
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?
Title: Re: "Neutral" inventory spacing?
Post by: monkey0506 on Sun 28/11/2010 23:57:03
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:

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)):

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?
 }
}
Title: Re: "Neutral" inventory spacing?
Post by: Tamanegi on Mon 29/11/2010 11:30:43
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
Title: Re: "Neutral" inventory spacing?
Post by: Khris on Mon 29/11/2010 11:58:12
It should be possible to do the check within on_mouse_click:

// 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:
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.
Title: Re: "Neutral" inventory spacing?
Post by: Tamanegi on Mon 29/11/2010 19:41:37
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