You will need each object to have a local variable like "faction" so that you can distinguish forces of another player. When the object is created you should assign the appropriate faction value to that object so it can easily be identified during all future object checks. Something like the following:
Code:
o_soldier = instance_create(x,y,o_soldier_parent)
o_soldier.faction = "Red Player"
and then later on when checking for any objects that do not belong the the red players own objects:
Code:
if(object.faction <> "Red Player")
I'm not saying this is wrong, and I realize that you were just giving an example, but giving them a boolean (?) value (true / false) is maybe better than a string. If I'm correct - using strings takes a bit more effort for GMS to do, and is a bit slower. With a lot of units that might make a noticeable difference.
Code:
o_soldier = instance_create(x,y,o_soldier_parent)
o_soldier.is_enemy = true;
o_soldier = instance_create(x,y,o_soldier_parent)
o_soldier.is_enemy = false;
@Craig Davidson
Unfortunately the functions provided by GMS don't allow for differences in objects, such as being the same object type but (in your case) having different "allegiances". Something like instance_nearest won't cycle through instances if they are found to be "friendly" - it just literally returns the closest instance regardless of anything else.
So you will want to build an equivalent function. A relatively straightforward way to do this is by using a priority queue, or by looping through the instances.
create_event
Code:
is_enemy = true (or false)
step event
Code:
var max_dist = 5000; // sets a value to compare instance distance to - the amount doesn't really matter, as it is just setting a baseline for comparison
var closest_obj = noone;
var obj, dist;
for (var a = 0; a < instance_number(whatever); a++) // loop to go through all the instance number of object
{
obj = instance_find(whatever, a); // finds each instance of that object
if obj != id // is not self
{
if obj.is_enemy // is enemy
{dist = point_distance(x, y, obj.x, obj.y);
if dist < max_dist // is less than max dist
{
closest_obj = obj;
max_dist = dist; // shrinks max_dist down to current dist. If next objects distance is larger it will not trigger this part. If it's still smaller, then it will
}
}
}
}
// when loop is finished 'closest_obj' should be the nearest enemy instance, and is an id you can then use for the next step. Or it will not have found an "enemy" in range, and will be "noone"
// in which case it should be ignored.
However, doing that for every instance is probably unnecessary. You could instead have a controller object with a ds list. Put the controller object at the top of the instance creation order. Every enemy created afterwards puts its id onto the list. If it's destroyed it takes its id off the list.
Instead of having to go through every instance and see if it is an enemy or not, you would just loop through this one list that is solely enemy id. This reduces the number of checks: no need to check that it's not "self" - it won't be. No need to check if its friendly or not - if it's on the list it's an enemy. You then only need to get the distance.
Code:
var max_dist = 5000;
var closest_obj = noone;
var control_list = controller.enemy_list;
var list_size = ds_list_size(control_list)
var obj, dist;
for (var a = 0; a < list_size; a++) // loop through list
{
obj = control_list [| a]; // gets id from list
dist = point_distance(x, y, obj.x, obj.y);
if dist < max_dist // is less than max dist
{
closest_obj = obj;
max_dist = dist;
}
}