Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Racoon on Thu 06/02/2020 21:53:56

Title: Save Inventory State
Post by: Racoon on Thu 06/02/2020 21:53:56
Hey there,

Is there a way to save the inventory state in a room and call it up again when entering that room?
I want the character to loose all inventory and to get it back when reentering.
If there already is a post about this problem please link it, I couldn´t find anything.

Thank you :)
Title: Re: Save Inventory State
Post by: Crimson Wizard on Thu 06/02/2020 22:11:42
One solution is perhaps to create a dummy character (place it in room -1, which does not exist, so you'll never see it on screen) and move all inventory items to its inventory, and then back when you return.

More resource efficient solution with slightly more scripting, is to create a dynamic array of inventory item IDs in the room and use it as a "item cash".

In the room script
Code (ags) Select

int Cash[]; // array, contains number of item instances (copies) per item ID
// the size of array, when it is filled, is always equal to Game.InventoryItemCount

function Room_BeforeFadein()
{
     // if cash already exists, then move items to player
     if (Cash != null)
     {
          for (int i = 0; i < Game.InventoryItemCount; i++) {
               player.InventoryQuantity[i] = Cash[i];
          }
          UpdateInventory(); // update inventory window(s), if any exist
          Cash = null; // reset the cash
     }
}

function Room_Leave()
{
     // move items to the cash
     Cash = new int[Game.InventoryItemCount];
     for (int i = 0; i < Game.InventoryItemCount; i++) {
          Cash[i] = player.InventoryQuantity[i];
          player.InventoryQuantity[i] = 0;
     }
     UpdateInventory(); // update inventory window(s), if any exist
}
Title: Re: Save Inventory State
Post by: ManicMatt on Fri 07/02/2020 00:25:32
I love how there's often multiple solutions to one problem. I was thinking you could use global variables to determine upon entering the room which items would be added.

so say you name a global variable:

IsPencilInInventory

and set the variable to be false (bool or int, i can't remember off the top of my head).

Then when they pick up the pencil the variable is set to true. when they leave the room, you code in to have the character lose the inventory item. now when they go back in, you have code set to check if the pencil is set to true, and if so you add the inventory item. you would do the same for all inventory items.

if the character needs to lose the item upon using it or whatever, then set it to false when you code in to remove that item so it doesn't reappear if they go back in the inventory room again.

i am about to go to sleep so this advice might have a flaw but i think it sounds solid in theory. I think the inventory items might appear in a different order, is all.
Title: Re: Save Inventory State
Post by: eri0o on Fri 07/02/2020 00:40:46
Depending on what you want to achieve may be easier to switch player character to one that looks just like him/her, and hide the original player character on and then revert.
Title: Re: Save Inventory State
Post by: Mandle on Fri 07/02/2020 16:02:14
Quote from: eri0o on Fri 07/02/2020 00:40:46
Depending on what you want to achieve may be easier to switch player character to one that looks just like him/her, and hide the original player character on and then revert.

Elegant!
Title: Re: Save Inventory State
Post by: ManicMatt on Fri 07/02/2020 16:38:15
That's a clever idea! Although I'm wondering about complications like having to make sure the code for the character is the right one, like if they say something it needs to be the right cEgo or cEgo2 or whatever.

But otherwise it does seem the easiest route to take.
Title: Re: Save Inventory State
Post by: Cassiebsg on Fri 07/02/2020 16:58:50
Maniac Matt... using player.Say solves that every time.  (laugh)
Title: Re: Save Inventory State
Post by: ManicMatt on Fri 07/02/2020 17:23:17
Oh. Oh yeah.

... er.. hmm.

Ah! But what if they decide to have two different characters in the game and they both have unique dialogue, and you'd code in if statements for which character it is currently being controlled, then you couldn't do player say! So ha! Take that desperate clutch at saving myself! Ahem.
Title: Re: Save Inventory State
Post by: Cassiebsg on Fri 07/02/2020 17:32:04
Code (ags) Select

if (player==EGO1 || player==EGO2) player.Say("blah blah blah");
else player.Say("blublubli");


(laugh) 
Title: Re: Save Inventory State
Post by: ManicMatt on Fri 07/02/2020 17:37:31
Ah but what if they decide to have THREE characters?!

Lol I'd better stop before the mods zap me. No need to answer that, I know how that code would look!
Title: Re: Save Inventory State
Post by: Crimson Wizard on Fri 07/02/2020 19:44:44
Quote from: Mandle on Fri 07/02/2020 16:02:14
Quote from: eri0o on Fri 07/02/2020 00:40:46
Depending on what you want to achieve may be easier to switch player character to one that looks just like him/her, and hide the original player character on and then revert.

Elegant!

From my point of view, this is an open hole into the hell. As soon as you begin adding more to the game and player character, this solution, seemingly trivial at first, may turn into source of bugs.

Simple examples: later in game you'd like to change character's property. Then you'd also have to make same change to the character copy. If you change properties in runtime, you also would have to do this for the duplicate character. You end up having to update second character each time you adjust your first one (or at least remember to copy those properties when you make the switch).

And all this trouble instead of moving array of items from one place to another, which is an explicit operation.
Title: Re: Save Inventory State
Post by: eri0o on Fri 07/02/2020 19:58:42
I agree it may be a bad solution but it depends on what are the requirements for the game.

There's missing data on this operation relatively to the order the items were added, so while operating arrays work, the order of them in the inventory would change - going from ManicMatt comment.

Probably to avoid this, one would need to traverse the inventory window to figure out the order, and store this too. And later on, add them using this order.

Edit: thinking again, may be easier to change which character the inventory window belongs to. Again, this depends on the game constraints.

Disclaimer: in my game I had to do this and did exactly what CW said in his first comment of creating a dummy character and moving the inventory to it.
Title: Re: Save Inventory State
Post by: Crimson Wizard on Fri 07/02/2020 20:06:03
Quote from: eri0o on Fri 07/02/2020 19:58:42
There's missing data on this operation relatively to the order the items were added, so while operating arrays work, the order of them in the inventory would change - going from ManicMatt comment.

Probably to avoid this, one would need to traverse the inventory window to figure out the order, and store this too. And later on, add them using this order.

Yes, this is where keeping original character as a backup has an advantage. But this also reminds that there's another hidden property that user does not have an access too directly...


Quote from: eri0o on Fri 07/02/2020 19:58:42
Edit: thinking again, may be easier to change which character the inventory window belongs to.

If not displaying items is a primary goal, then indeed.
Actually, it's like the suggestion to switch player characters, except you keep controlling original character, but using items from another. It's even possible to script storing items in another character, probably, you just need not use "player" but some custom pointer "playerInventory" when dealing with items. (if necessary)

But if not displaying items is all you want, then maybe just draw an empty inventory window...
Title: Re: Save Inventory State
Post by: ManicMatt on Fri 07/02/2020 20:21:09
Or just disable the inventory GUI from appearing all together, unless the save and load etc icons are on it.

Yup, multiple solutions to one problem, but not all solutions are equal, heh.
Title: Re: Save Inventory State
Post by: Racoon on Sat 08/02/2020 23:35:02
Thanks for your ideas!
The solution I did go with is making an invisible character cDummy and move all inventory to it when leaving the room and doing the same but backwards when reentering.
The code I scratched together while looking through the forums is:

Code (ags) Select
function oGoBack_AnyClick()
{
int i = 1;
while (i < Game.InventoryItemCount +1) {
  cDummy.InventoryQuantity[i] += cEgo.InventoryQuantity[i];
  cEgo.InventoryQuantity[i] = 0;
  i++;
  }
UpdateInventory();
player.ChangeRoom(1);
}


function room_Load()
{
int i = 1;
while (i < Game.InventoryItemCount +1) {
  cEgo.InventoryQuantity[i]+= cDummy.InventoryQuantity[i];
  cDummy.InventoryQuantity[i] = 0;
  i++;
  }
UpdateInventory();
}


The only problem left is, that there are 4 items that the player should have at all time after adding them to the inventory. But I have an idea of how to do that with variables.