How to: Display Inventory Items in a LIST

Started by Spocker, Sun 19/03/2023 23:57:23

Previous topic - Next topic

Spocker

Hi there!

I am trying to set an inventory as a list, where we could see the object and its definition next to one another (RPG like). I'm not at this step though, as I already have some difficulty getting rid of the slot inventory.



In the picture, you can see that items obviously appears in the Inv Window where I hastily drew red crosses. But I would like a system where you have the object's picture (where are blue circles) and the object's description (where are blue lines) as a list.

1.My first idea was to manually set the item coordinates in the Inv Window, as I don't mind to:
-Try to understand how to set a variable for each item that the player takes in his inventory,
-Do something like IF this is the 4th item, then let the picture go to this (x,y) coordinates, IF this is the 5th, go there, etc.

However, I can't seem to find any way to get to the object coordinates when it is drawn in the inventory. I wanted to have slots under slots, and not next to each other. My scripting skills being almost inexistant, reading (several times) the Manuel on GUI/InvWindow/Inventory Items functions and properties was not enough.

2.The second idea I had was to use a ListBox instead of an Inv Window. However, I'm really not familiar with it. I naively tried this (where "1" is the Item ID) :

Code: ags
function oCupofTea_Interact()
{
    oITEM.Visible = false;
    ListBox.AddItem(1);
}

But it simply doesn't work and return this very enigmatic error: "Must have an instance of the struct to access a non-static member".
Unfortunately, I don't understand a word of it. My plan to conquer the world seems to end here! ^^

Thank you for any help or workaround. I didn't find any module that seems to do the trick!

Crimson Wizard

#1
Quote from: Spocker on Sun 19/03/2023 23:57:23However, I can't seem to find any way to get to the object coordinates when it is drawn in the inventory. I wanted to have slots under slots, and not next to each other.

You may probably achieve wanted result if you make a narrow and tall InventoryWindow, making sure only 1 item is fitting in a row.
Also check for ItemWidth and ItemHeight properties of the invwindow, they define the expected item sizes (it ignores actual sprite sizes when calculating item positioning).

Then place a ListBox for textual descriptions to the right. Or buttons, if ListBox does not look right for any reason. You may also use rows (or columns) of buttons for displaying extra images and whatnot.
In fact, you may use buttons for everything there, it just will be more work, as you'll have to update button images as you scroll this inventory.

Quote from: Spocker on Sun 19/03/2023 23:57:23But it simply doesn't work and return this very enigmatic error: "Must have an instance of the struct to access a non-static member".

That's because you are not refering to an actual list box's script name, but to a type ListBox.
Instead your code has to be
Code: ags
myListBox.AddItem(1);
where "myListBox" is how you called your list box in properties.



In the worst case, when you cannot achieve this using built-in gui controls, you may try DynamicSprite / DrawingSurface solution. AGS lets you create a sprite in script, and then draw anything on it. Then you may assign it to GUI background, and update / redraw as necessary. That's additional effort to program though, and I recommend keeping standard buttons, as it will be difficult for a beginner to program their clicking behavior in script.

About drawing surfaces:
https://adventuregamestudio.github.io/ags-manual/DynamicSprite.html
https://adventuregamestudio.github.io/ags-manual/DrawingSurface.html

But in any case, this is the last solution to try.

Spocker

Thanks for the thorough answer. The last option seems quite complicated indeed, I may try it though.

But first, when I try this as you corrected:
Code: ags
ListBoxInventory.AddItem(1);
I get the error: "Type mismatch: cannot convert 'int' to 'const string'". Would you be able to help?

Crimson Wizard

#3
Quote from: Spocker on Mon 20/03/2023 00:34:02But first, when I try this as you corrected:
Code: ags
ListBoxInventory.AddItem(1);
I get the error: "Type mismatch: cannot convert 'int' to 'const string'". Would you be able to help?

Ahh, sorry, I did not notice that. Yes, ListBox's AddItem require strings. If you're adding explicit values you could write
Code: ags
ListBoxInventory.AddItem("1");
but if you have an integer as a variable, which you want to convert to string, it will be:
Code: ags
ListBoxInventory.AddItem(String.Format("%d", value));

String formatting (printing values in string) in AGS is done in C-language-style; it's quite flexible, but may be found complicated at first:
https://adventuregamestudio.github.io/ags-manual/StringFormats.html

Spocker

Well,
Thank you sincerely, the first idea you gave (about playing with the width/height of the Inv Window) made me rethink a bit the display of my inventory. It's not pixel perfect yet, but it's going. Here with a random example.



As for your explanation on strings, I litterally just understood that it really meant... "STRINGS". I thought it was a concept or a name, like variable or integrer. Not the actual "guillemets". ^^'

Now I just need to find in the Dialog Manual how to do line breaks inside the ListBox' strings, and how NOT to display any background in the ListBox (or a transparent one), and the inventory will actually look nicer.
Strangely I didn't find any explicit list of Dialog options, such as changing the color/size/type of fonts inside a speech. Will look again!


Crimson Wizard

#5
Quote from: Spocker on Mon 20/03/2023 01:30:25As for your explanation on strings, I litterally just understood that it really meant... "STRINGS". I thought it was a concept or a name, like variable or integrer. Not the actual "guillemets". ^^'

Well, there's type String, which means a variable that contains text, and then there's concept of "string literal", which means that you put text in quotes (guillemets?) right in script. Functions require the arguments of String type, and if you print literal string in "" there, it will be automatically converted to one.

Quote from: Spocker on Mon 20/03/2023 01:30:25Now I just need to find in the Dialog Manual how to do line breaks inside the ListBox' strings,

ListBoxes only support single-line items. If you need multiple lines per item, then either:
* add multiple items to listbox, but then you'd have to split them manually somehow. Probably you will have to write your own function that splits one string into multiple, by the pixel width it takes (GetTextWidth function may give an idea).

Another approach would be to have multiple Labels instead of a ListBox. Labels can have multiple lines and wrap text automatically. Hmm... maybe even one label, but then you'd have to program it to arrange the text somehow, so maybe that will become less convenient.

Quote from: Spocker on Mon 20/03/2023 01:30:25and how NOT to display any background in the ListBox (or a transparent one), and the inventory will actually look nicer.

ListBox itself does not have a background, so you see a GUI background underneath... or do you mean background under selected item? that's ListBox.SelectedBackColor, but I do not remember if it can be transparent. There *may* be a workaround, where you'd handle the "SelectionChanged" event in ListBox and unset the selection to "none".
Then again, given your previous question, maybe ListBoxes won't work here.

Khris

I don't see any reason why you should deviate from an actual inventory window; sticking to that will make things way easier.

I'd use the 1 column inv window as CW suggested, then use dynamically drawn sprites for the inventory items (and put the image on the left, then a wrapped description next to it).

IIRC there was a relatively recent thread where I did this exact thing, let me try and find it.

Crimson Wizard

Quote from: Khris on Mon 20/03/2023 17:46:21I'd use the 1 column inv window as CW suggested, then use dynamically drawn sprites for the inventory items (and put the image on the left, then a wrapped description next to it).

That's doable, although I think splitting this into multiple controls may make it more flexible. Especially if you like to add interactivity on separate "parts" of each item.

SMF spam blocked by CleanTalk