GUI like inventory

Started by proximity, Sat 09/05/2020 11:05:32

Previous topic - Next topic

proximity

I want to create a GUI with buttons just like inventory GUI. When a GUI button is added (visible) or removed (invisible) from the GUI, remaining buttons must stay in order. What is the logic of this? Is there any algorithm for it? If so, how can I implement it with current GUI button script commands?
Proximity Entertainment

Matti

I'm not quite sure what you're trying to do. Do you want to make a GUI with buttons instead of items? And instead of adding and removing items those buttons should turn visible/invisible? Why don't you want to use a regular inventory?

Cassiebsg

If it's just a normal GUI, then buttons will always stay where you have place them. If it's an inventory window GUI with inventory items that fill a certain "button" you can also just create a GUI and check "if player has item X" then turn the button on otherwise turn it off.

So... what exactly is it you want to make? That'll help us figure out a solution for the problem. But right now I can't exactly see what the problem is.  :-\
There are those who believe that life here began out there...

proximity

Sorry, I didn't make myself clear. What I want to say is that I want all visible buttons sorted dynamically so there will be no space between them. When an invisible button becomes visible in the game, it will be positioned next to (or below) the last visible button. There will be hundreds of buttons so I need a logic to keep them positioned correctly.
Proximity Entertainment

Crimson Wizard

#4
Quote from: proximity on Sat 09/05/2020 17:39:27
Sorry, I didn't make myself clear. What I want to say is that I want all visible buttons sorted dynamically so there will be no space between them. When an invisible button becomes visible in the game, it will be positioned next to (or below) the last visible button. There will be hundreds of buttons so I need a logic to keep them positioned correctly.

If buttons are fixed size that should be easy to do. You need a standard grid formula, where cell X = column index * cell width, and cell Y = row index * cell height.



I also noticed you said "hungreds of buttons", if you do not have to show them all on screen at the same time, you may use less and dynamically change which item they represent as player scrolls inventory.

Snarky

If you're going to have hundreds of them, you'll probably want the window to scroll, won't you?

This doesn't sound like something you should be using GUI Buttons for. What is the purpose of this window?
Depending on the details, I would either use an InventoryWindow (just use button images as the item graphics), or possibly program it from scratch, drawing and keeping track of the state.

Crimson Wizard

#6
Quote from: Snarky on Sat 09/05/2020 17:52:35
Depending on the details, I would either use an InventoryWindow (just use button images as the item graphics), or possibly program it from scratch, drawing and keeping track of the state.

Buttons may still be simplier to use as they already have necessary properties and don't require to script drawing yourself.
Their only drawback is that ags does not let you create them in script, so you'll have to use a pool of precreated buttons.

Snarky

Yes, I would not have the patience to set them all up in the editor. Particularly linking all the click events (to a single universal click handler, obviously!).

I suppose it's possible go in and edit the game.agf file manually, copy-pasting to add a whole bunch of them, though.

But again, it really depends on the characteristics of the task. The description is so outside of normal requirements that we really need more details to determine the best way to proceed.

proximity

#8
There are two reasons why I want this;
1- I want to create an RPG game that has hundreds of main and side quests. I must use a button GUI for quests because I reserved 300 inventory items for collectibles. It doesn't have to be a scrolling GUI because maximum 10 quests may be active at the same time. I thought listbox GUI should do it but when removing an item from listbox, remaining items' indexes change and it makes them impossible to track anymore. And also when the player clicks a quest, it should modify another GUI label for quest description. That's why quests must be GUI buttons.
2- Another GUI for collectibles such as weapons, armors, scrolls, books. Inventory items only include food, herbs, ingredients... So I need a custom GUI for special collectibles.
Proximity Entertainment

Snarky

If you can have ten quests, then you only need ten buttons. Lay them out the way they should be displayed.

Each button acts as a slot that you can "fill" with a quest. You probably want to have an array that keeps track of which quest is assigned to each button.

Also keep track of how many quests are active, and when you need to add another one, set that button to that quest, update the array and increase the count.
If you take out a quest from the middle, switch the quests that each of the other buttons are linked to one slot down. That's about it.

And just a word of warning: I have written a couple of RPG-ish engines in AGS. It involves a tremendous amount of wrangling data: setting up arrays and structs with all sorts of definitions. If you struggle with this bit, I would expect it to be an extremely challenging task for you.

proximity

Quote from: Snarky on Sat 09/05/2020 20:52:00
If you can have ten quests, then you only need ten buttons. Lay them out the way they should be displayed.

Each button acts as a slot that you can "fill" with a quest. You probably want to have an array that keeps track of which quest is assigned to each button.

Also keep track of how many quests are active, and when you need to add another one, set that button to that quest, update the array and increase the count.
If you take out a quest from the middle, switch the quests that each of the other buttons are linked to one slot down. That's about it.

And just a word of warning: I have written a couple of RPG-ish engines in AGS. It involves a tremendous amount of wrangling data: setting up arrays and structs with all sorts of definitions. If you struggle with this bit, I would expect it to be an extremely challenging task for you.

How do I switch button texts when removing a quest from the middle? Should I define a string array?
Proximity Entertainment

Crimson Wizard

#11
Quote from: proximity on Sat 09/05/2020 20:24:10
1- I want to create an RPG game that has hundreds of main and side quests. I must use a button GUI for quests because I reserved 300 inventory items for collectibles. It doesn't have to be a scrolling GUI because maximum 10 quests may be active at the same time. I thought listbox GUI should do it but when removing an item from listbox, remaining items' indexes change and it makes them impossible to track anymore. And also when the player clicks a quest, it should modify another GUI label for quest description. That's why quests must be GUI buttons.

This is a universal issue with interfaces, as in game players may want to also sort or filter quests, so the common solution is to not rely on list item index, but somehow bind a list item to data (quest in your example), or provide a conversion between list index and an index of a data.

As a quick example, if you have an array of quest names or structs, then you could have a second array telling how listbox items correspond to these quests. When you change the listbox, you also adjust this helper array.

proximity

Quote from: Crimson Wizard on Sat 09/05/2020 21:26:26
Quote from: proximity on Sat 09/05/2020 20:24:10
1- I want to create an RPG game that has hundreds of main and side quests. I must use a button GUI for quests because I reserved 300 inventory items for collectibles. It doesn't have to be a scrolling GUI because maximum 10 quests may be active at the same time. I thought listbox GUI should do it but when removing an item from listbox, remaining items' indexes change and it makes them impossible to track anymore. And also when the player clicks a quest, it should modify another GUI label for quest description. That's why quests must be GUI buttons.

This is a universal issue with interfaces, as in game players may want to also sort or filter quests, so the common solution is to not rely on list item index, but somehow bind a list item to data (quest in your example), or provide a conversion between list index and an index of a data.

As a quick example, if you have an array of quest names or structs, then you could have a second array telling how listbox items correspond to these quests. When you change the listbox, you also adjust this helper array.

I'm lost here :) Because when adding an item to listbox we define a string, but when removing an item we point index number as int. I can't understand how we can connect anything with them as listbox items are somewhat obscure.

Here is the line from official help : "NOTE: Calling this function causes other items in the list to get re-numbered, so make sure you don't keep around any references from ListBox.SelectedIndex and related functions while using this command."

Proximity Entertainment

Crimson Wizard

#13
Quote from: proximity on Sat 09/05/2020 21:45:13

I'm lost here :) Because when adding an item to listbox we define a string, but when removing an item we point index number as int. I can't understand how we can connect anything with them as listbox items are somewhat obscure.


List box has an array of strings, which have numeric indexes.
In script you have an array of quests (strings, or structs with quest data). These quests have their own indexes.
You make 3rd array of integers, that tell which quest a list's index referring to.

Example:
Quest array contain data:
0: Quest1
1: Quest2
2: Quest3

List Box contain strings:
0: "Quest3"
1: "Quest2"
2: "Quest1"

Helper array does connection from list box's index to quest index:
0: 2 -- refering to Quest3
1: 1 -- refering to Quest2
2: 0 -- refering to Quest1


Case: user clicked on list box item with index 0. How do you find out which quest it is? Under index 0 in helper array is number 2 -- this is a quest's index.

proximity

Code: ags
int Quest[5];

// Adding quests

ListBox.AddItem("Quest3");
Quest[3]=ListBox.ItemCount; // Quest 3 = 1
ListBox.AddItem("Quest1");
Quest[1]=ListBox.ItemCount; // Quest 1 = 2
ListBox.AddItem("Quest5");
Quest[5]=ListBox.ItemCount; // Quest 5 = 3
ListBox.AddItem("Quest4");
Quest[4]=ListBox.ItemCount; // Quest 4 = 4
ListBox.AddItem("Quest2");
Quest[2]=ListBox.ItemCount; // Quest 2 = 5

// Removing Quests
Listbox.RemoveItem(Quest[5]-1); // removing index 2

// After removing, Quest 4 and Quest 2 indexes get re-numbered. How do I tell the engine that Quest[4] and Quest[2] must also get re-numbered?
Proximity Entertainment

Crimson Wizard

#15
Quote// After removing, Quest 4 and Quest 2 indexes get re-numbered. How do I tell the engine that Quest[4] and Quest[2] must also get re-numbered?

Of course you have to adjust your array too.

Note, you did it opposite way, in your array index means quest number and value means listbox number; I suggest index meaning listbox number and value meaning quest number, to keep in sync with listbox easier.


Actually, it is best to write functions for adding/removing items to make it simplier:
Code: ags

// how many quests may be shown in a list at same time
#define MAX_QUESTS_SHOWN 10
// array that connects list items to quest IDs
int Quest[MAX_QUESTS_SHOWN ];
// number of shown quests
int QuestCount;

// Adds quest entry to the list
void AddQuestToList(ListBox* lb, int quest_id, String quest_name)
{
    if (lb.ItemCount >= MAX_QUESTS_SHOWN)
    {
         AbortGame("Script logic error!!"); // or whatever
    }

    Quest[QuestCount] = quest_id;
    QuestCount++;
    lb.AddItem(quest_name);
}

// Removes quest entry from the list, given list item index
void RemoveQuestByListIndex(ListBox* lb, int item)
{
    // Shift quest entries leftwards to fill the gap
    for (int i = item; i < QuestCount - 1; i++)
    {
         Quest[i] = Quest[i + 1];
    }
    QuestCount--;
    lb.RemoveItem(item);
}

// Finds index in list that corresponds to quest ID;
// returns -1 if quest is not in the list.
int FindQuestIDInList(int quest_id)
{
     for (int i = 0; i < QuestCount; i++)
     {
          if (Quest[i]) == quest_id)
              return i;
     }
     return -1;
}

// Removes quest entry from the list, given quest ID
void RemoveQuestByQuestID(ListBox* lb, int quest_id)
{
     int item = FindQuestIDInList(quest_id);
     if (item < 0)
         return; // not found
     RemoveQuestByListIndex(lb, item);
}



Above is quick typed and untested, but I hope to give general idea.

proximity

#16
Thanks Crimson, I've just tested it and it worked  :smiley: Should I follow a similar logic for button GUI with grid formula? Bind buttons to a helper array? Anything different?

https://ibb.co/ZdMJ8jy
Proximity Entertainment

SMF spam blocked by CleanTalk