Max Equips in Inventory and Saving Equip Status to JSON (Solved)

Greeetings,

You all probably know that I’m still working on that inventory from before.

I have 2 issues here. For now, let’s focus on issue 1 first.

Issue 1:
I want to have a maximum amount of equips for the player. Basically, in this example here, the player can only equip 2 trinkets so far. They will not be able to equip any more than 2 (Until upgrade is found).

It’s only half working right now, once 2 trinkets are equipped, clicking on another trinket rolls the counter that keeps track of how many trinkets you have on now down to -1 (In the debugger), allowing an extra to be equipped, which isn’t what I want.

Here’s the code:

And here’s the issue:



Clicking on a third trinket with 2 already equipped (Which in this case is that heart charm with the face), silently equips it, rolling the trinket counter down by 1, thus opening up an extra slot (3 in this case). The other 2 trinkets were unequipped for the demonstration, and the debugger displays the slot with the heart as equipped too

So basically, when I hit the max amount of trinkets I can wear at once, the counters keep moving. How can I get them to freeze once all the equips remaining are filled?


Issue 2:

I have the save system up and running for the trinkets. Since they each have their own dedicated slots, it’s an easy read and write to JSON code. No problem.


But since my game will have equippable trinkets, how can I make it so that the save system remembers that trinkets are equipped? Is the built in inventory system capable of handling this? Or do I have to reinvent the wheel and rewrite the trinket inventory with an array instead?

Thanks

I found this little gem the other day that will probably solve your first issue.

I’m tapping out for your second issue.

Okey

Alright, so the numbers in the debugger and onscreen aren’t displaying the wrong values anymore, but in consequence, it makes tracking the issue harder. If you click a third trinket a few times, it equips anyways.

Is there any way to stop the equipping entirely when the max limit is reached? I thought the code I have already does that, but there’s something missing…

EDIT: I think I may have found a potential culprit. Is this “less than or equal to” sign

The fix isn’t that easy though.
When I change it to “greater than or equal to” and invert the condition, I just get the same results with no changes. If I change it to simply “less than,” then the limit works! Except once I reach the max, I can’t unequip my trinkets…

Is there a different way, or am I doing something wrong here?

You need to check if the equipped count is less than the max to equip but it doesn’t matter what the count is to unequip.

I think on the toggle line or the previous event you need an OR with an AND. I’m not at my PC to test. I’m not going to try to type your variable names but I’m sure you’ll get me concept.

If one of these is true
   Trinket equipped variable is true
    
   [&] If all off these are true
         Trinket equiped variable is false
         Trinket count variable is less than max
1 Like

You probably need to add this to your base event check (the one with the mouse check) or change the 4 events after the toggle line to sub-events so they only happen if the toggle happens. IDK if executing those lines if the boolean doesn’t change would affect anything but it’s always a good idea to ignore unnecessary events.

If mouse and other events
   If can toggle then toggle
       Change the inventory and blend mode

Alright, I made the changes

However, the problem still isn’t fixed yet. The items can still be equipped infinitely, and the equipped amount when unequipping never reverts back to the max amount (2), being stuck at a max of 1, even in the debugger. Overequipping isn’t displaying negative numbers either

Is this a step in the right direction? What else am I missing?

The conditions I suggested were for the line with the toggle. That way the boolean is only toggled when below the max number. And since the other events are subevents they’ll also only trigger when the boolean is toggled. Which is a good thing.

 If one of these is true
 Trinket equipped variable is true

[&] If all off these are true 
  Trinket equiped variable is false 
  Trinket count variable is less than max

I think the sub-events of the line with the toggle were fine like this. You just need to check the values before you toggle.

1 Like

Heyy, thanks, I moved the code, and now it’s working perfectly. Thank you so much.

Although, that segways into the next wall I hit at this same time:

The second issue, where I can save the inventory just fine, but I can’t save the equip status for items.

Basically, I want items to remember that they’re equipped. Is there a way to do that? I can’t find any events that allow me to do so. Do I need to store the equipped status in a structure variable or something?

1 Like

I know very little about the inventory system. When you save the trinkets, can you save the “equipped” state? (if not as a Boolean, then maybe as a 0 and 1.) Again, I know very little about inventory saving and loading.

When you load them, check the state and equip the ones that are true or 1. I have no idea how to achieve that in your project. I’ll help debug it if needed.

Alright, so an idea I have is to make the game track which slots are classified as “equipped” by saving the ID of the slot into an array. Then the game shall save the array, and load it back in, match the array children to the correct slots, then set them to true, automatically equipping them

While debugging, I found a problem with the array. Here’s the code.
You can see that I added actions to append the ID to the array if the boolean is true, and remove it if it’s false:

In the debugger though, when unequipping the trinket, the array value doesn’t go away, or only seems to get removed when it feels like it

Did I do something wrong here?

When you append, you’re adding it to the end of the array but the remove is choosing a specific index that may not even exist. At least, that’s how I’m reading it. Eventually, you might add enough, depending on the ID number but there’s no connection. It could be any ID.

You might be better off just setting and reading specific indexes as a Boolean

(IDKW, the autocomplete doesn’t work inside the brackets. You can type it somewhere else and copy/paste or just type really carefully)

1 Like

Progress has been made! I feel like we’re just about to complete this. There’s just one more problem…

So, I switched the toggle to change the array directly instead like you suggested, and it works just as it did before with no errors, meaning it can now be read by the save system!

I put in the save code to save the entire structure for playerStats (Because it’s good practice to save the structure instead of each variable individually). Here’s the new code:

Code for saving:

Code for loading:

So, here’s where the problem lies. The code IS actually saving and loading the inventory, and remembering if they’re equipped! However, the game forgets to SHOW that the trinket is equipped upon loading (The blend mode effect that indicates the trinket is equipped)

Here, you can see that trinket 2 is equipped:

Upon saving and loading though (Or more specifically, changing or restarting scenes), this is the result:

So technically, the trinket IS equipped upon loading, however, the blend mode isn’t reapplying (Until you click it to unequip it and then click it again, then it starts working normally again)

I think the culprit is the code that applies it in the first place. The way it’s set up, it only applies the blend when it’s clicked, not when it’s loaded

I tried doing this, moving the blend and equip checks outside of the click events:

But it just breaks the whole thing…

Any ideas on how I can remedy this final issue?

There’s a lot to read and I’m on my phone.

When you load the data/inventory, you need to set the state of the cell’s blend mode for each item based on the boolean. probably both true and false. So all of the tiles get reset. Once set, your original code should be fine for everything else. You just need to initialize things.

The safe way is use an array of structures with a matching ID.

Something like: trinket.IsEquiped and trinket.ID and go through it with a variable for the element number using a repeat. I can create an example if needed when I’m on my PC.

It took me awhile to figure this out. I’m not used to the way arrays work in Gdevelop. It’s easier for me to share a project instead of trying to explain it. I omitted your maximum checks and inventory. This was just about using an array of structures. More structures can be added as needed.

doug13579/Gdevelop-inventory-trinket-save-to-array (github.com)

1 Like

I tried to do something similar here, because the equip status is being tracked by a global variable instead of the scene variable “Trinket” in your example, so I tried to make it read the dump that’s created when it’s loaded

Unfortunately, nothing changed. Did I do it right?

You need something to select the trinkCell objects. Otherwise, the blend mode will apply to all the objects whose animation isn’t zero.

If you have a matching ID variable with the Equiped boolean in your array (which it appears you do) then you can use the ID to pick the matching trinkCell by it’s ID object variable.
(This is a rough example, not perfect syntax or variable names)

It looks like your code is just slightly reversed.

Example:

For each child in trinkArray
   trinkCell.Variable(ID) = Variable(child.ID)
        child.equiped is true | blend mode = 1
        child.equiped is false | blend mode = 0

I’m not sure on your blend mode or your boolean, it might be reversed. IDK

Edit: it shouldve been child.equiped. I changed it…

Alright, I made some changes, but unfortunately, nothing changed


Did I put the wrong variable in somewhere?

It looks close. As long as the array has a matching ID value it should be ID to ID

TrinketCell.Variable(ID) = variable (child.ID)

You might want to move this section inside the load code. So, it happens everytime the data is loaded . You might not need the check animation isn’t Empty if the array captures all of the cell data. IDK about how the array is filled. If it’s a sub event of the load code you wouldn’t need the at the beginning of the scene

FYI, the at the beginning of the scene really means during the first frame of the scene. But it still gets executed based on event order. So, placememt still matters and this section should be placed before anything that interacts with the cells but after the events that load the data and creates the array that it reads from.

I originally thought the at the beginning of the scene gave the events priority no matter where they were placed. The name of the event is a bit misleading. It’s sort of like a trigger once.

I moved the code to the load events instead to see if anything would happen


I tested it, but still nothing changed, it’s the same results as last time. Am I close?

Just in case it would make things easier, here are my global variables

trinkEquip: The number of trinkets currently equipped

trinkEquipArray: The array that checks to see which trinkets are currently equipped

trinkEquipMax: The base maximum amount of trinkets you can equip at once

Take a look at my example project from before. Your code looks right but I don’t think your variable is setup to use it. In my example there’s an array of structures with a boolean for equiped and a number for ID. So, when you use the for every child you have the matching values. I can’t tell if you’re setting the values in the array first.

If you want to, upload your current project again and I can look at it tomorrow. I need to see the whole thing in context.