SOLVED: How do I handle inventory items in a single cursor game?

Started by alkis21, Sun 04/11/2018 09:46:00

Previous topic - Next topic

alkis21

Hello everyone, I haven't posted here in years, it's good to be back. I have a potentially embarrassing question:

I have recently started working on a new game, which, unlike the two previous ones I made, has a single cursor interface. I figured out how to get one cursor to do everything in the main game area by using the following script in on_mouse_click:

Code: ags
else if (button == eMouseLeft) {
    String location = Game.GetLocationName(mouse.x, mouse.y);
    if (location == "") ProcessClick(mouse.x, mouse.y, eModeWalkto);
    else ProcessClick(mouse.x, mouse.y, eModeInteract);
  }


but I can't get my inventory to work. The inventory is a bar on the top of the screen, always visible. I want the cursor to 'pick up' the inventory item it clicks on, and I want to be able to use one inventory item on another. Instead, clicking on an inventory item does nothing.

Any help will be appreciated.

Snarky

Over an inventory item, button has a different value: eMouseLeftInv. (I would argue that this is a mistake in the design of AGS, but it is what it is.)

Welcome back, BTW! It has been a long time.

ManicMatt

Just saying hi! Although I never played it (I've probably played like 1% of AGS games in existence) bit I certainly remember your game Diamonds in the Rough!

alkis21

Thank you both for the answer and the welcome!

Quote from: Snarky on Sun 04/11/2018 10:15:32
Over an inventory item, button has a different value: eMouseLeftInv.

That sounds useful but I'm not sure what to do with this information, I tried adding another if-then but no matter what I do, I can't pick up those inventory items.

Lewis

Quote from: alkis21 on Sun 04/11/2018 20:29:41
That sounds useful but I'm not sure what to do with this information, I tried adding another if-then but no matter what I do, I can't pick up those inventory items.

What's your new code?
Returning to AGS after a hiatus. Co-director of Richard & Alice and The Charnel House Trilogy.

Khris

You also need to activate manual inventory click handling in General Settings / inventory.

alkis21

No, actually all I had to do was to change the player's active inventory using each item's OtherClick() function... for some reason I thought that would happen automatically.

And my on_mouse_click now looks like this:

Code: ags
  else if (button == eMouseLeft) {
    String location = Game.GetLocationName(mouse.x, mouse.y);
    if (location == "") ProcessClick(mouse.x, mouse.y, eModeWalkto);
    else {
      if (Mouse.Mode==eModeWalkto) ProcessClick(mouse.x, mouse.y, eModeInteract);
      else ProcessClick(mouse.x, mouse.y, eModeUseinv);
    }
  }
  else if (button == eMouseRight) mouse.Mode=eModeWalkto;


The above seems to do the trick. If I click my cursor on an empty spot, the player walk there, if I click it on a hotspot it described it and if I carry an item it tries to use it on it. Right clicking 'releases' the item.

Does this seem more or less correct?

Crimson Wizard

Quote from: alkis21 on Mon 05/11/2018 21:33:20
No, actually all I had to do was to change the player's active inventory using each item's OtherClick() function... for some reason I thought that would happen automatically.

No, no, this is way too complicated. Following code is usually enough:
Code: ags

else if (button == eMouseLeftInv) {
    // sets an item under mouse cursor as selected for the player character
    player.ActiveInventory = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
}


Or even simplier:
Code: ags

else if (button == eMouseLeftInv) {
    // this uses game.inv_activated which is an index of the last item player clicked on
    player.ActiveInventory = inventory[game.inv_activated];
}

alkis21

That is more or less what I initially tried to do and couldn't get it to work, because I had not activated the 'Override built-in inventory window click handling' option in the General Settings.

Now picking up inventory items works, but using one item on another doesn't.

I tried this but it processes the hotspot behind the inventory bar instead:

Code: ags
  else if (button == eMouseLeftInv) {
    if (mouse.Mode==eModeWalkto) player.ActiveInventory = inventory[game.inv_activated];
    else ProcessClick(mouse.x, mouse.y, eModeUseinv);
  }

Crimson Wizard

Quote from: alkis21 on Mon 05/11/2018 22:14:53
I tried this but it processes the hotspot behind the inventory bar instead:

ProcessClick works only on the Room and room contents (regions, objects, characters), it clicks "through" GUI. Here you need RunInteraction.

It should be something like:
Code: ags

else if (button == eMouseLeftInv) {
    // if no item selected, then select one
    if (player.ActiveInventory == null)
        player.ActiveInventory = inventory[game.inv_activated];
    // otherwise use item on item
    else
        inventory[game.inv_activated].RunInteraction(eModeUseinv);
} else if (button == eMouseRightInv) {
    // if some item is selected, then deselect it
    if (player.ActiveInventory != null)
        player.ActiveInventory = null;
    else
     // do something else? like --
     inventory[game.inv_activated].RunInteraction(eModeLookat);
     // (just an example)
}

alkis21


SMF spam blocked by CleanTalk