How to make collected keys and unlocked doors not reappear when the room is re-entered?

T

Taycamgame

Guest
I'm working on an RPG and it will have keys and locked doors / blocks. Keys will be limited to the dungeon they are found in (so you can't use a key from dungeon 1 in dungeon 2 etc.).
I have the following in the create event for the object obj_game:
Code:
//Keys
global.keysNormal = array_create(LEVEL_COUNT, 0)
LEVEL_COUNT is a macro which is just the number of levels.
Each key has a variable dungeon assigned to it, this is what number dungeon the key can be used in.

When the player collides with a key:
Code:
collectKey(other.dungeon)
instance_destroy(other)
And the collectKey function:
Code:
function collectKey(_dungeon){
    for (var i = 0; i < array_length(global.keysNormal); i ++){
        if (i == _dungeon){
            global.keysNormal[i] += 1
        }
    }
    show_debug_message(global.keysNormal)
}
This code just adds 1 key to the number they have in the correct dungeon.

Next, the player's collision check with the locked blocks:
Code:
unlockBlock(other.dungeon, other)
And the unlockBlock function:
Code:
function unlockBlock(_dungeon, _other){
    for (var i = 0; i < array_length(global.keysNormal); i++){
        if (i == _dungeon){
            if (global.keysNormal[i] > 0){
                global.keysNormal[i] -= 1
                instance_destroy(_other)
            }
        }
    }
    show_debug_message(global.keysNormal)
}
This goes through the global.keysNormal array, looks for the dungeon and compares the number of keys they have. If they have atleast one key, the door unlocks (destroys) and the number of keys is reduced.

And basically what this does is setup an array, e.g. when LEVEL_COUNT is 2 then the global.keysNormal array will start off as [0, 0]. If a key in dungeon 1 is collected this array goes to [1, 0]. If a door is unlocked then it will remove one key from the correct dungeon.

The problem i have is that, if the player collects a key or unlocks a door, and leaves the room and returns, then the key / door will reappear. This does not change the value in the array so the player could get basically infinite keys. How do i make it so that collected keys and unlocked doors don't reappear when they shouldn't?
 
P

ParodyKnaveBob

Guest
Howdy, Taycangame, and welcome to the GMC. $:^ J

A couple different concepts come to mind off the top of my head. One is to keep the rooms persistent; if you intend to have a lot of rooms to track this way (and not, say, a "mini-RPG,") then this might tax the system, although it'd be pretty convenient and automatic for you (depending on what you'd want for enemies and such staying the same, too). Another totally different idea is to tell your appropriate objects to compare their instance info to your array info, and only appear/destroy upon room entry accordingly. Obviously, you'll have to rewrite some stuff either of these ways, and any other ways that might come up.

I hope this helps,
 
T

Taycamgame

Guest
I changed the structure so now the keys and locks have a unique ID. So before the key array was of the form [0, 0] - now it's of the form [ [0, 0, 0], [0, 0] ] (variable size).
This feels like an impractical solution though (if i want a dungeon with 20 keys then i need to put 20 0's in the array). I'm wondering if there's a more ideal way to go about this.
With that said, it does work now! Thanks for the help :)
 
P

ParodyKnaveBob

Guest
Glad you got it going!

If you need to create a new array branching off merely filled with the same value, like 0s, array_create() has you covered. If you reeeaaally want perhaps a single variable instead of an array, you can study up on bit-flipping. One variable, a real number, just primed to store lots of 1s and 0s... and each 1 or 0 being a "flag" set (true or false) for each key/lock. It's what the old systems used, like, pre-2000s, lol, and it works; it takes a bit more effort in some ways, and a bit less effort in other ways. Just another option.

Regards!
 
Hello !

It's a bit difficult for me to understand how you intend to to use those keys and how you've set your systen so I won't try to fix your job but instead give you an other approach of it that may as well solve some future issues you may have.

I think you should use an external file as a base :
-INI file or CSV file
-You can read and write them easily with GML functions.

An ini file is made of "sections" and "pairs" for example :

[dungeon 1]
key1=found
key2=not_found
key3=not_found
door1=open
door2=closed
tree1=cut

[dungeon 2]
key1=not_found
key2=found
etc ...

INI files are quiet fast to read from if you need to check some status at instance creation or in a punctual action.
If you need to access this data more often you may load it into a ds_map :
dungeon1_data = ds_map_create();
then add each pairs with ds_map_add()

That way you could create all of your data with a text file (INI file) easy to modify and read (much more that a array indexed in numbers). That would be persistent between rooms without the need of a persistent room or persistent instance(s), and finaly a save if you close the game.



Same story with CSV but here you you would use a table maker to make it ("Libre office calc" for exemple because it's fine and free of use) and you would load the data as a ds_grid this time.

You could have 2 lines per dungeon, 1 for the item (key, door etc ...) and 1 for the status (found, not_found, open, closed, 0, 1 etc...).

line 0 (dungeon 0 item) : key1,key2,door1,door2
line 1 (dungeon 0 status) : 0,1,0,0



Hope it helps o/
Good luck in you enterprise !
 
Top