I'm super surprised at how many people don't know the in-built way to check for party pokemon given how useful it is. I've seen 3 people ask about it in the last month.
special2 0x8001 0x147 will scan a party slot (0-5) held in variable 0x8004 and return that species ID to variable 0x8001. You can use whatever variable you want in place of 0x8001 in the command. This is useful for when you know the party slot the expected pokemon should be in, say in the first slot. After that, just use a compare command with 0x8001 and the species ID you were checking for.
You can make it even better using special 0x9F, which opens up the party menu so the player can pick whatever slot they want. This special will store the selected slot in 0x8004, making it instantly ready to follow up with special2 0x8001 0x147.
Combining these two makes a super easy checkpokemon function:
Code:
special 0x9F '"Party screen"
waitstate
special2 0x8001 0x147 '"Convert selected slot to species ID in 0x8001"
compare 0x8001 0x2 '"Compare 0x8001 to the species ID you want"
if 0x1 goto @success
...(fail)
That code brings up the party screen, lets the player select whatever pokemon they want, and then checks whether that species is 0x2 (ivysaur). If yes, go to @success. Otherwise, say it failed.
I'm sure you can figure out how to run that code 3 times for your purposes
Whether binary or decomp, there's no need to get any simpler than that