Save Inventory State

Started by Racoon, Thu 06/02/2020 21:53:56

Previous topic - Next topic

Racoon

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 :)

Crimson Wizard

#1
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

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
}

ManicMatt

#2
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.

eri0o

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.

Mandle

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!

ManicMatt

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.

Cassiebsg

Maniac Matt... using player.Say solves that every time.  (laugh)
There are those who believe that life here began out there...

ManicMatt

#7
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.

Cassiebsg

Code: ags

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


(laugh) 
There are those who believe that life here began out there...

ManicMatt

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!

Crimson Wizard

#10
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.

eri0o

#11
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.

Crimson Wizard

#12
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...

ManicMatt

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.

Racoon

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
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.

SMF spam blocked by CleanTalk