If you use a selector that searches for the nearest entity (@p, @e[c=1], etc), it will always find the entity executing the command (if possible), even if there is another equally close entity. Essentially, entities are always closer to themselves than to any other entity, regardless of actual location. This is extremely useful, and is not a bug. However, this behavior only occurs when specifically searching for the one closest entity. If you search for the 2 closest entities, or the farthest entity, this property will not be taken into account.
To reproduce, execute these commands:
/summon minecraft:armor_stand ~ ~ ~ {Tags:["test1"]}
/execute as @e[tag=test1] at @s run summon minecraft:armor_stand ~ ~ ~ {Tags:["test2"]}
/execute as @e[tag=test1] at @s run summon minecraft:armor_stand ~ ~ ~ {Tags:["test3"]}
/execute as @e[tag=test3] at @s run tag @e[limit=2,sort=nearest] list
Or these
/summon armor_stand ~ ~ ~ {CustomName:"test1",NoGravity:1b}
/execute @e[name=test1] ~ ~ ~ /summon armor_stand ~ ~ ~ {CustomName:"test2",NoGravity:1b}
/execute @e[name=test1] ~ ~ ~ /summon armor_stand ~ ~ ~ {CustomName:"test3",NoGravity:1b}
/execute @e[name=test3] ~ ~ ~ /say @e[c=2]
The last command will find "test1" and "test2", while you executed it from "test3"
Code analysis by @unknown can be found in this comment
Attachments
Comments 7
Now it's a dupe of MC-95352
@@unknown That report details issues concerning directional bias, while this report covers the lack of sender bias if an entity has the potential to target itself.
For example, if you summoned 3 armor stands at the exact same location (thus disregarding directional bias) and cause the newest one of them to say the name of the closest two, it will not say its own name and will instead say the name of the two oldest armor stands.
The following commands might make it easier to reproduce since they don't require a scoreboard setup:
/summon armor_stand ~ ~ ~ {CustomName:"test1",NoGravity:1b}
/execute @e[name=test1] ~ ~ ~ /summon armor_stand ~ ~ ~ {CustomName:"test2",NoGravity:1b}
/execute @e[name=test1] ~ ~ ~ /summon armor_stand ~ ~ ~ {CustomName:"test3",NoGravity:1b}
/execute @e[name=test3] ~ ~ ~ /say @e[c=2]
Please link to this comment in the description
The following is based on a decompiled version of Minecraft 1.10 using MCP 9.30.
This could be solved by removing the sender entity from the list of the matching entities if it is contained and inserting it at the index 0. This way even if the distance comparison returns 0 it will be still the first entity in the list.
Possible solution
private static <T extends Entity> List<T> getEntitiesFromPredicates(List<T> matchingEntities, Map<String, String> params, ICommandSender sender, Class <? extends T > targetClass, String type, final Vec3d pos)
{
int i = parseIntWithDefault(params, "c", !type.equals("a") && !type.equals("e") ? 1 : 0);
if (!type.equals("p") && !type.equals("a") && !type.equals("e"))
{
if (type.equals("r"))
{
Collections.shuffle((List<?>)matchingEntities);
}
}
else
{
// Added this
Entity senderEntity = sender.getCommandSenderEntity();
if (senderEntity != null && matchingEntities.remove(senderEntity)) {
matchingEntities.add(0, (T) senderEntity);
}
// Change end
Collections.sort((List<T>)matchingEntities, new Comparator<Entity>()
{
public int compare(Entity p_compare_1_, Entity p_compare_2_)
{
return ComparisonChain.start().compare(p_compare_1_.getDistanceSq(pos.xCoord, pos.yCoord, pos.zCoord), p_compare_2_.getDistanceSq(pos.xCoord, pos.yCoord, pos.zCoord)).result();
}
});
}
// MC-80893
Entity entity = sender.getCommandSenderEntity();
if (entity != null && targetClass.isAssignableFrom(entity.getClass()) && i == 1 && ((List)matchingEntities).contains(entity) && !"r".equals(type))
{
matchingEntities = Lists.newArrayList((T)entity);
}
if (i != 0)
{
if (i < 0)
{
Collections.reverse((List<?>)matchingEntities);
}
matchingEntities = ((List)matchingEntities).subList(0, Math.min(Math.abs(i), ((List)matchingEntities).size()));
}
return (List)matchingEntities;
}
Confirmed for
1.8.4 when using
*c=2*
it seems like it still finds always itself, but when you summon another entity at the exact same position as the first one, it can eventually find you when you walk at this position instead of the second other entityRelates to:
MC-79103