GMS 2.3+ Trying to copy RPG-stats from one array to another... help?

Hello! I'm not always the best at wording things, so I apologize if this gets confusing.

I've been reworking the battle system for my turn-based RPG, so that I can easily change the stats and appearance of different types of enemies. The way I've been trying to implement this is by storing all the enemies' stats and such in different arrays, all of which are stored in a script called "scr_enemystats". The enemy object already has an array with the default enemy stats. (For reference, the array is simply called "enemystats".)
I only had one regular enemy fully implemented in the old system, so I've been trying to implement its stats to the new one. The array containing its stats is called "badapplestats", and it reads as follows:
Code:
    //Name
    badapplestats[0] = "Bad Apple";

    //HP
    badapplestats[1] = 200;

    //Attack
    badapplestats[2] = 5;

    //Speed
    badapplestats[3] = 1;

    //Info page 1
    //(Use [0])

    //Info page 2
    badapplestats[4] = "You've never been a fan of apples...";

    //Info page 3
    badapplestats[5] = "120BPM, 4/4 time signature";

    //Timeline for counter-riff
    badapplestats[6] = tim_appleroll;

    //Sprite
    badapplestats[7] = spr_badapple;

    //Background
    badapplestats[8] = spr_battlebg1;

    //Backing track
    badapplestats[9] = snd_badapplebacking;

    //Lead track
    badapplestats[10] = snd_badapplelead;
And again, for reference, here's the array with the default stats that are loaded unless the enemy's type is specified in the creation code:
Code:
    //Name
    enemystats[0] = "Enemy";

    //HP
    enemystats[1] = 1;

    //Attack
    enemystats[2] = 1;

    //Speed
    enemystats[3] = 1;

    //Info page 1
    //(Use [0])

    //Info page 2
    enemystats[4] = "Flavour text";

    //Info page 3
    enemystats[5] = "xBPM, y/y time signature";

    //Timeline for counter-riff
    enemystats[6] = tim_appleroll;

    //Sprite
    enemystats[7] = sprite_index;

    //Background
    enemystats[8] = spr_battlebg1;
    
    //Backing track
    enemystats[9] = snd_badapplebacking;

    //Lead track
    enemystats[10] = snd_badapplelead;
Now, all I want to do is set the values in "enemystats" to be equal to the values in "badapplestats". I have tried a few different methods to make this work. At first, I tried the most simple thing I could think of, not really expecting it to work-- I simply wrote:
Code:
if enemytype = "badapple"{
     enemystats = badapplestats;
}
And, well, that obviously didn't work. I then read the manual, and found the "array_copy" page. I then more-or-less copied what was on there:
Code:
if enemytype = "badapple"{
    if !array_equals(badapplestats, enemystats)
   {
   var _len = array_length_1d(badapplestats);
   array_copy(enemystats, 0, badapplestats, 0, _len);
   }
}
Aaaaand, that didn't work either, despite the description on the page stating "The above code will check two arrays to see if they hold equivalent values, and if they do not then the code will copy the entire contents of the array 'inventory_array' to the array 'item_array'. "
I tried a few different variations of that code as well, changing a few things around, stored different parts of it in local variables, in hopes that it would help.
... It did not.

When I run the game, the top of the screen, where the name is supposed to be displayed, still just says "Enemy". The HP is set to 1. The info box shows the default messages. Ahhhh.

Also, in case anyone's wondering, yes, the script containing the badapplestats array is called at the top of the create event, and yes, "enemytype" is set to "badapple" in the object's creation code in the test room. I've checked for typos-- I even copy/pasted variable names and such to make sure of that-- but I've come up with nada.

So, what am I doing wrong? Am I completely misunderstanding the limitations of arrays? Are there any obvious errors from the code-snippets? Is my implementation just poor? Does this have to do with the way scripts have been changed in GMS 2.3?

Thank you for your time, I hope I made myself understood, and I apologize once more in case I'm just being stupid. (I don't know all the ins-and-outs of GML, so maybe this just isn't possible. : P)
 

TailBit

Member
Just did a quick check and it seems to work fine:
GML:
r = [0,1,2,3];
t = [];

//r = t; // this just make them refer to the same list .. not copy .. that's why I tried the r[2] = 8
if !array_equals(r,t){
    array_copy(t,0,r,0,4);
    r[2] = 8;
}
show_debug_message(string(r) + " "+string(t))
I suggest using show_debug_message to check if the values are correct when you want them to be, or just to check if part of the code runs at all (but for that you could also press mark the line in the code editor and use debug mode), in debug mode you could also use the variable tab on the row beside the output to set a watch for variables: obj.variable
 
Just did a quick check and it seems to work fine:
GML:
r = [0,1,2,3];
t = [];

//r = t; // this just make them refer to the same list .. not copy .. that's why I tried the r[2] = 8
if !array_equals(r,t){
    array_copy(t,0,r,0,4);
    r[2] = 8;
}
show_debug_message(string(r) + " "+string(t))
I suggest using show_debug_message to check if the values are correct when you want them to be, or just to check if part of the code runs at all (but for that you could also press mark the line in the code editor and use debug mode), in debug mode you could also use the variable tab on the row beside the output to set a watch for variables: obj.variable
Thank you, I will try to do that tomorrow!
 

samspade

Member
The reason (and you might have figured this out) the first version didn't work is that you were copying the array id, so essentially both variables would refer to the exact same array. The second example should have worked. Like @TailBit I would recommend checking with either show debug message or the debugger to see what is actually going on.

If you want to be able to copy arrays with a little more easy, I would also recommend my free array function extension. For example, it has the function array_copy_shallow (and array_copy_deep) that would all you to use a slightly simpler syntax:

GML:
if (!array_equals(a, b)) {
    b = array_copy_shallow(a);
}
Internally, it uses array copy, but I find this a lot easier to write and remember.
 

Yal

šŸ§ *penguin noises*
GMC Elder
Instead of copying data between arrays with different names, I would've recommended having a single 2D array (an array of arrays in GMS2.3) where each enemy's data is on a separate row... then you just need the row number to refer to an enemy, and all the data is in the same place and never needs to be copied. (The big win here is that you can use the same name for the array everywhere, instead of having to make duplicate-code-except-you-change-one-name whenever you add a new enemy.... that's just asking for maintenance issues down the line)
 
Instead of copying data between arrays with different names, I would've recommended having a single 2D array (an array of arrays in GMS2.3) where each enemy's data is on a separate row... then you just need the row number to refer to an enemy, and all the data is in the same place and never needs to be copied. (The big win here is that you can use the same name for the array everywhere, instead of having to make duplicate-code-except-you-change-one-name whenever you add a new enemy.... that's just asking for maintenance issues down the line)
That's an excellent idea that never even crossed my mind. Should be easy to implement as well. Thank you!
 
Top