• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker [Solved] Instanced objects return the same ID?

B

Blaize

Guest
Hi guys, I have a turn-based tactics game in the works, and I am programming in the unit select function.
Units are created at the start of the level with this code:
Code:
for (i=0;i<instance_number(cSpawnPoint);i++)
{
    instance_create_depth(instance_find(cSpawnPoint,i).x,instance_find(cSpawnPoint,i).y,0,bActor);
}
At the moment, it simply finds spawn points in the scene and spawns the base Unit object into the scene. The units themselves store their id into the corresponding movement node's Occupant variable (the nodes are empty objects with no other code except for Occupant). The names are just bActor for now.
Code:
cMap.Map[@ PositionX div CELL,PositionY div CELL].Occupant = id;
Now, in the draw event, I have the sprite drawing it's own id to help me determine who's who for now.
Everything works up to this point. The two bActors are showing their own ids as expected. In this case, I have one as 100805 and 100806.
The current system as it is stores the id of the selected unit into a global variable (global.SelectedActor).
However, when I click either one of them with this code:
Code:
var _x = argument[0];
var _y = argument[1];
var _obj = argument[2];

if (cMap.Map[@ _x,_y].Occupant!=noone)
    return _obj.id;
else
    return noone;
Regardless of which actor I click on, it will always return the id of 100805. I have a feeling that _obj is returning only the first instance, so how can I return just the occupant's id?

Would appreciate any insight you might have.
 

chamaeleon

Member
Hi guys, I have a turn-based tactics game in the works, and I am programming in the unit select function.
Units are created at the start of the level with this code:
Code:
for (i=0;i<instance_number(cSpawnPoint);i++)
{
    instance_create_depth(instance_find(cSpawnPoint,i).x,instance_find(cSpawnPoint,i).y,0,bActor);
}
At the moment, it simply finds spawn points in the scene and spawns the base Unit object into the scene. The units themselves store their id into the corresponding movement node's Occupant variable (the nodes are empty objects with no other code except for Occupant). The names are just bActor for now.
Code:
cMap.Map[@ PositionX div CELL,PositionY div CELL].Occupant = id;
Now, in the draw event, I have the sprite drawing it's own id to help me determine who's who for now.
Everything works up to this point. The two bActors are showing their own ids as expected. In this case, I have one as 100805 and 100806.
The current system as it is stores the id of the selected unit into a global variable (global.SelectedActor).
However, when I click either one of them with this code:
Code:
var _x = argument[0];
var _y = argument[1];
var _obj = argument[2];

if (cMap.Map[@ _x,_y].Occupant!=noone)
    return _obj.id;
else
    return noone;
Regardless of which actor I click on, it will always return the id of 100805. I have a feeling that _obj is returning only the first instance, so how can I return just the occupant's id?

Would appreciate any insight you might have.
Would probably be very useful if you showed the code that calls your script so people know what you pass as the third argument. If it corresponds to an object id instead of an instance id it would explain your problem for instance.
 

FrostyCat

Redemption Seeker
You need to remember the difference between objects and instances. Don't put an object ID on the left side of a referencing dot if multiple instances of it exist.

Human and Dog are objects. Alice, Bob, Fido and Lassie are instances. If both Alice and Bob are in the same room, you can ask for Alice's name or Bob's name (which while valid is redundant because "Alice" and "Bob" are already names), but not Human's name.

In your case, cMap.Map[@ _x,_y].Occupant is already an instance ID. It will have the equivalent of "Alice" or "Bob" in there. Return that.
 
B

Blaize

Guest
You need to remember the difference between objects and instances. Don't put an object ID on the left side of a referencing dot if multiple instances of it exist.

Human and Dog are objects. Alice, Bob, Fido and Lassie are instances. If both Alice and Bob are in the same room, you can ask for Alice's name or Bob's name (which while valid is redundant because "Alice" and "Bob" are already names), but not Human's name.

In your case, cMap.Map[@ _x,_y].Occupant is already an instance ID. It will have the equivalent of "Alice" or "Bob" in there. Return that.
Looking at my code this morning, you're right. I've changed my code to simply check for an Occupant and returning an id:

Code:
var _x = argument[0];
var _y = argument[1];

return cMap.Map[@ _x,_y].Occupant!=noone? cMap.Map[@ _x,_y].Occupant.id : noone;

Btw, @FrostyCat nice write-up on objects and instances, it's a good reference for forgetful people like me.
 

FrostyCat

Redemption Seeker
Your code is pretty much redundant if that's what's left of it. All you have there is basically this:
Code:
return cMap.Map[@ argument0, argument1].Occupant;
"Alice's name" is still "Alice". There's no need to ask her what her name is if you're already calling her by name.
 
B

Blaize

Guest
That's true. There really isn't much else to do, so I guess doing something like
Code:
global.SelectedUnit = cMap.Map[@ mouse_x div CELL,mouse_y div CELL].Occupant;
in the mouse click event would be enough?
 
Top