Get an items description and change a label's name to it? [SOLVED]

Started by Stranga, Tue 17/10/2017 04:20:49

Previous topic - Next topic

Stranga

Hey everyone, this sounds simple but is driving me mad. What I am basically trying to do is to change a label text to = an inventory the mouse cursor is over an inventory item.
Except the game has no mouse control, It's a game made for keyboard

Gilbert

If there is no mouse control, what did you mean by "an inventory the mouse cursor is over"?

Or, do you mean, there is still mouse cursor, but other than hovering around the screen the cursor does nothing?

Please elaborate.

Stranga

My apologies, there is no mouse control or cursor, was typing without thinking. I am using a a small HUD like inventory similar to the legend of Zelda how it works is it checks what is in the first slot of the inventory window. Since the inventory only has one slot showing, it uses that information to play an action in the game. For example if you open your inventory selection, press either left or right and it scrolls through the inventory. When you land on an item of choice, close the inventory, your selected item will now show in the HUD. I've set up a global variable for a selected item which uses the item's ID to determine which item is selected (It works quite nicely actually). So when the layer is standing on a hotspot and has that item ID selected and presses the Enter key it does something.



This is an example of what it looks like. Now where it says market key is a label. It wont change when another item is selected. I though of GetTextProperty but that didn't work.

Also here's the secret inventory code I made for the game ;) haha:

Code: ags

function repeatedly_execute_always() 
{
//This checks what is in the equip slot on the HUD then sets the ItemSelect No.
  InventoryItem *i = InventoryItem.GetAtScreenXY(InventoryWindow2.X, InventoryWindow2.Y);
if (i != null)
    { 
      ItemSelect = i.ID; 
      lblItemDescription.Text = i.Name;
    }


InventoryWindow 2 is the HUD inventory window, I made 2 to make 2 separate windows

Khris

There's no need to run these commands in repeatedly_execute_always; the label and active item only change when an arrow key is pressed, so that's where you should run the code.

Code: ags
  if (keycode == eKeyLeftArrow || keycode == eKeyRightArrow) {
    if (keycode == eKeyLeftArrow) InventoryWindow2.ScrollUp();
    else InventoryWindow2.ScrollDown();
    player.ActiveInventory = inventory[InventoryWindow2.TopItem];
    lblItemDescription.Text = player.ActiveInventory.Name;
  }


Edit:
Fixed Code:
Code: ags
  if (keycode == eKeyLeftArrow || keycode == eKeyRightArrow) {
    if (keycode == eKeyLeftArrow) InventoryWindow2.ScrollUp();
    else InventoryWindow2.ScrollDown();
    player.ActiveInventory = InventoryWindow2.ItemAtIndex[InventoryWindow2.TopItem];
    lblItemDescription.Text = player.ActiveInventory.Name;
  }

Gilbert

(Khris ninjaed me, and his solution should be a better one, but anyway, if your still want to check what inventory item is at a certain point on the screen my post should still be relevant.)
Hmmm. Just a quick check, maybe add a few pixels to the coordinates for checking what item it's pointing at and try again.
Something like:
Code: ags
InventoryItem *i = InventoryItem.GetAtScreenXY(InventoryWindow2.X + 4, InventoryWindow2.Y + 4);

Haven't really thought of the reason, but I suspect that one possibility is that you're not getting any inventory item by checking the upper-left corner pixel of InventoryWindow2, so you may need to check from a point somewhere inside that GUI (i.e. somewhere that you're sure you'll reach the item's icons), otherwise it always return null, which is the reason the label never changes (as you didn't have any codes to cater for the situation when the detected item is null).

Stranga

Khris: This may be a work around solution, I'll have to test it. I was trying t avoid using active inventory because when I tried that theory in game when the player stood on a hotspot and had th  active inventory code the mouse with the inventory item selected would appear. (I suppose I could remove the cursor images and it may work, not sure).

Gilbert: I think I may have tried your code before and I though so to adding an extra 4- 16 pixels to center the GetAtScreen script. But I didn't try InventoryWindow1 with that line so I will give that a try also.

Khris

Quote from: Gilbert on Tue 17/10/2017 09:08:29Haven't really thought of the reason, but I suspect that one possibility is that you're not getting any inventory item by checking the upper-left corner pixel of InventoryWindow2
I believe it's even worse; the coordinates stated are those of the InvWindow relative to the GUI's coordinates, so unless the GUI is positioned at 0,0 on the screen, the line might be checking for an item outside the inv window.

Stranga: my suggestion is not even remotely a "workaround". If using player.ActiveInventory causes issues because you forgot to hide the mouse in a keyboard only game, that's what you need to fix.

Stranga

I fixed the issue with what Gilbert mentioned. I added 12 pixels in on both X and Y.

Khris: It was my original idea to use player active inventory.
For example:

Code: ags

function hDoor_WalkOn()
{
if (player.ActiveInventory==iKey)){
  if (IsKeyPressed(eKeyReturn) && !Inventory)  //If Enter pressed and Inventory is not open
    {
      {
      player.FaceDirection(eDirectionUp);
      player.Say("It Unlocked!");
      player.Say("The door is open!");
      }
    }
}
}


Would this work at all, without mouse support?

Edit: I changed to your code Khris, Much better than I had plus...I'm so dumb for that error before.

Khris

Here's how to interact with Objects / Hotspots using a keypress: http://www.adventuregamestudio.co.uk/forums/index.php?topic=44602.msg595691#msg595691
Code is a few posts down. It assumes that regions are used for objects of the same ID, and hotspots are also drawn on the floor.
Adding eModeUseinv is pretty basic:

Code: ags
// in on_key_press
  if (keycode == eKeyReturn) {
    int x = player.x - GetViewportX(), y = player.y - GetViewportY();
    Hotspot*h = Hotspot.GetAtScreenXY(x, y);
    if (h.ID > 0) {
      if (player.ActiveInventory != null) h.RunInteraction(eModeUseinv);
      else h.RunInteraction(eModeInteract);
    }
    else {
      Region rr = Region.GetAtRoomXY(player.x, player.y);
      if (rr.ID > 0) {
        if (player.ActiveInventory != null) object[rr.ID].RunInteraction(eModeUseinv);
        else object[rr.ID].RunInteraction(eModeInteract);
      }
    }
  }


That way you can use interactions as usual:
Code: ags
function hDoor_Useinv() {
  if (player.ActiveInventory == iKey) {
    player.FaceDirection(eDirectionUp);
    player.Say("It Unlocked!");
    player.Say("The door is open!");
  }
  else unhandled_event(1, 3); // import function unhandled_event(int what, int type); in Globalscript.ash
}


(One should always separate game controls and events like that; imagine you want to change the keycode for interacting with the game world; you'd have to change the keycode in every single room).

Stranga

Ah, that's excellent! That would save a ton of time coding if I can use both normal interactions and item interactions! Thanks very much Khris! :smiley:

There's only one other thing. If there's no inventory to select as active inventory it errors out. Should I just add something like:

Code: ags

if (player.ActiveInventory!=null)
    {
            
          player.ActiveInventory = inventory[InventoryWindow2.TopItem];
          lblItemDescription.Text = player.ActiveInventory.Name;
    }

Khris

I believe the issue is with .TopItem being -1, so the fix would be

Code: ags
  if (keycode == eKeyLeftArrow || keycode == eKeyRightArrow) {
    if (gInventory.Visible && InventoryWindow2.ItemCount > 0) { // inventory is on screen and has content
      if (keycode == eKeyLeftArrow) InventoryWindow2.ScrollUp();
      else InventoryWindow2.ScrollDown();
      player.ActiveInventory = inventory[InventoryWindow2.TopItem];
      lblItemDescription.Text = player.ActiveInventory.Name;
    }
  }

Stranga

That seems to only work when I scroll through 1 direction. If I scroll to the right it stops on the last item. if I scroll past the first item to the left it errors. Maybe I am missing something from the code?

Khris

Quote from: Stranga on Tue 17/10/2017 12:17:49it errors

Could you maybe tell us the actual error message? Only if it isn't too much trouble, of course.

Stranga

Sorry about that. Wouldn't let me copy the text so I took a screenshot.



Now your code works fine if i scroll through the inventory to the right or down, when I reverse it and go past the first item in the inventory,
^ this occurs. Also another thing I noticed is that the images and names don't match up properly. Say for instance, I have a picture of a key, the
name says blue cup. If I have a picture of a cup it says key. I was thinking it may have something to do with the top of the inventory method (could be something completely different but this is just my guess)

Khris

Found the issue: .TopItem stores the InvWindow index, not the inventory index.
So you need
Code: ags
  player.ActiveInventory = InventoryWindow2.ItemAtIndex[InventoryWindow2.TopItem];

Stranga


SMF spam blocked by CleanTalk