The bug
When you use a command in the chat like:
/say @e[x=0,y=0,z=0,c=1]
Your name will always be stated even if there was a different entity closer to those coordinates. In this case, sender bias (which assumes "the entity closest to itself is always itself") does not take into account if the origin has been changed.
How to reproduce
/tp 20 60 0
/summon armor_stand 0 60 0 {CustomName:"closestEntity",NoGravity:1b,NoAI:1b}
/summon armor_stand 10 60 0 {CustomName:"commandExecuter",NoGravity:1b,NoAI:1b}
/execute @e[type=armor_stand,name=commandExecuter] ~ ~ ~ /say @e[x=0,y=60,z=0,c=1,r=20]
→ It will print "commandExecuter" instead of "closestEntity"
To make sure that "closestEntity" is indeed the closest one, you can run the following command:
/say @e[type=armor_stand,x=0,y=60,z=0,c=1,r=20]
The reason
The following is based on a decompiled version of Minecraft 1.10 using MCP 9.30.
The reason for this is that the method net.minecraft.command.EntitySelector.getEntitiesFromPredicates(List<T>, Map<String, String>, ICommandSender, Class<? extends T>, String, Vec3d)
explicitely uses the sender of the command if c=1
.
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
{
Collections.sort((List<T>)matchingEntities, new Comparator<Entity>()
{
public int compare(Entity p_compare_1_, Entity p_compare_2_)
{
System.out.println(ComparisonChain.start().compare(p_compare_1_.getDistanceSq(pos.xCoord, pos.yCoord, pos.zCoord), p_compare_2_.getDistanceSq(pos.xCoord, pos.yCoord, pos.zCoord)).result());
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();
}
});
}
// This prefers the sender of the command if c=1
//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;
}
Note: This is not a duplicate of MC-80400, because there it only happens with scoreboard commands and affects command blocks. This bug described here is not caused by command blocks and also doesn't only prefer players but instead the entity which ran the command.
Linked issues
is duplicated by 1
Comments 9
At the beginning I thought as well that this was the intended feature (and apparently many others as well). But this was a bug, see MC-49235.
c
is supposed to target the closest if positive and the furthest when negative
This is a duplicate of MC-80400
X/Y/Z are not ignored, but the player in the X/Y/Z/R area is preferred.
You are right, but isn't it then rather related?
If not could you please update the description and summary of MC-80400?
The description and summary of MC-80400 is perfect, if you have additional informaion, leave a comment there.
Duplicate of MC-80400, please close
It's no longer a dupe, info about Sender bias was removed from MC-80400
Doesn't
c
list the entities in order Oldest -> Newest ? Naturally the player is the first entity in the given range, the pig is always younger.