How to test if a passive mob is a baby with command blocks?

I'm trying to find out, in a command block, if a targeted mob (cow, sheep, chicken, etc.) is a baby or an adult. I know that's determined by the Age data tag: if Age<0, it's a baby, otherwise it's an adult. The problem is, as far as I know, there's no way to check if a data tag is <0, you can only test for exact values.
I'm able to detect the moment when a baby grows up, since the Age passes through -1 in that case (not checking 0 to avoid detection of newly spawned adults). But how can I tell whether a passive mob is a baby or an adult before that moment triggers (especially since adults won't have that moment at all)?
Best Answer
MBraedley's answer doesn't work at all in its current state (gfy link demonstration). colorfusion's answer somewhat works, but messes up with breeding as you appear to have noticed.
The following method is a bit of a hybrid between the two that I believe works 100% of the time.
Add these objectives:
/scoreboard objectives add CheckAge dummy
/scoreboard objectives add GrowthLevel dummy
On your clock:
/scoreboard players set @e CheckAge 1 {InLove:0}
/scoreboard players add @e[score_CheckAge_min=1] GrowthLevel 0
/scoreboard players set @e[score_CheckAge_min=1] GrowthLevel 1 {Age:0}
Then use @e[score_GrowthLevel_min=1]
to select adults, or @e[score_GrowthLevel=0]
for babies.
Pictures about "How to test if a passive mob is a baby with command blocks?"



Is there a way to make baby animals stay babies using commands?
You can make a baby mob by applying the appropriate spawn event in the /summon command. For drowned and zombies, it is minecraft:as_baby , and for other mobs, it is minecraft:entity_born . This does not work with villagers due to a bug.How to tame any mob in Minecraft using 3 command block. easy tutorial
More answers regarding how to test if a passive mob is a baby with command blocks?
Answer 2
So my comment above was wrong, this is doable, albeit with a caveat. The important thing to realize is what the Age tag actually represents:
Age: Represents the age of the mob in ticks; when negative, the mob is a baby. When 0 or above, the mob is an adult. When above 0, represents the number of ticks before this mob can breed again.
So, all friendly mobs will have an Age of 0 unless they're either a baby or were recently bred. This means we can easily tag them with a scoreboard value. Now we won't get newly minted parents, but if we use version 1.9 (or, at this point, the snapshots for 1.9), we don't have to worry about that, since we're going to tag all adults ready to breed. Even after you breed them, they'll still keep their tag; adults can't turn back into babies, so there's no reason to remove the tag.
So, it's fairly simple: just tag all entities with an Age of 0 as an adult.
/scoreboard players tag @e add Adult {Age:0}
Run that in a repeating command block, and all friendly mobs that are adults will have the tag unless they recently bred.
Now, to get all the babies is a little more complicated. The naive approach below isn't very desirable:
/scoreboard players tag @e remove Baby
/scoreboard players tag @e[tag=!Adult] add Baby
That will tag every single entity, including players, as a baby if they aren't already tagged as an adult. Not great. What we need to do is be able to distinguish friendly mobs from every other entity. Luckily, there is a way to do this:
/scoreboard players tag @e add FriendlyMob {InLove:0}
So, your commands, in order, should be:
/scoreboard players tag @e add FriendlyMob {InLove:0}
/scoreboard players tag @e add Adult {Age:0}
/scoreboard players tag @e[tag=!Adult] add Baby
/scoreboard players tag @e[tag=!FriendlyMob] remove Baby
/scoreboard players tag @e[tag=Adult] remove Baby
The only friendly mobs this won't work correctly with are mobs that are about to breed, or have just bred, and still, once those two timers reach 0 again, they'll be properly tagged. This won't take long either. The timer for InLove is only 10 seconds, and the timer for Age is 5 minutes. In most cases, you won't have to wait at all.
Hopefully it's self evident, but in order to select the adults, just use @e[tag=Adult]
, and similarly for the babies, use @e[tag=Baby]
.
SirBenet's answer made me realize I could simplify things a little (well, a lot): I don't need to actually tag friendly mobs, I can just do a data tag check instead:
/scoreboard players tag @e add Adult {Age:0}
/scoreboard players tag @e[tag=!Adult] add Baby {InLove:0}
/scoreboard players tag @e[tag=Adult] remove Baby
As before, if the Age or InLove timers are counting down, it won't tag the mob properly, but unless you're willing to go mess with those, there isn't really a way around it.
Sources: Stack Exchange - This article follows the attribution requirements of Stack Exchange and is licensed under CC BY-SA 3.0.
Images: Pew Nguyen, Lazaro Rodriguez Jr, Vidal Balielo Jr., Vidal Balielo Jr.