This question is very difficult. Testing if two blocks are somehow connected is already difficult, two entities being in the same body of water is even harder. I have a solution, but it's not a great one. There are probably solutions that work a lot better.
I'd recommend instead looking back the actual problem that you want this solution for; see if there's another way to solve it without testing if two entities are in the same body of water.
This part is to make sure that a search will actually work and won't break your world.
First, we can easily make sure the entities are actually both in water. If either of them is not, then we can skip everything else as they can't both be in the same body of water if one of them isn't even in any water. Put an AND gate with these two commands:
/execute @e[name=Entity1] ~ ~ ~ /testforblock ~ ~ ~ water
/execute @e[name=Entity2] ~ ~ ~ /testforblock ~ ~ ~ water
Next I'd next check that the entities are at least somewhat near eachother. This is kind of a safeguard; they could still be in the same body of water thousands of blocks away, but it's unlikely and you'd crash the game trying to work it out anyway.
/execute @e[name=Entity1] ~ ~ ~ /testfor @e[name=Entity2,r=R] ~ ~ ~
Change R
out with however far you want the search to go for. This solution is laggy, so you may want to keep it small.
If that succeeds (the entities are both in water, and aren't ridiculously far away from each-other) then it's time to do the actual search that'll work out if they're in the same body of water.
This part is the actual search.
The following commands make both Entity1
and Entity2
summon marker
ArmorStands in every adjacent direction around them in which there is water. The -1 data type means that any type of water (flowing, source, etc.) will work:
/execute @e[name=Entity1] ~ ~ ~ detect ~1 ~ ~ water -1 /summon ArmorStand ~1 ~ ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~-1 ~ ~ water -1 /summon ArmorStand ~-1 ~ ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~1 ~ water -1 /summon ArmorStand ~ ~1 ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~-1 ~ water -1 /summon ArmorStand ~ ~-1 ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~ ~1 water -1 /summon ArmorStand ~ ~ ~1 {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~ ~-1 water -1 /summon ArmorStand ~ ~ ~-1 {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~1 ~ ~ water -1 /summon ArmorStand ~1 ~ ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~-1 ~ ~ water -1 /summon ArmorStand ~-1 ~ ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~1 ~ water -1 /summon ArmorStand ~ ~1 ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~-1 ~ water -1 /summon ArmorStand ~ ~-1 ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~ ~1 water -1 /summon ArmorStand ~ ~ ~1 {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~ ~-1 water -1 /summon ArmorStand ~ ~ ~-1 {CustomName:"Entity2",Marker:1b,NoGravity:1b}
Note that all of the new ArmorStands being summoned have the name of their summoner. This means that in the next iteration of the search, each of these ArmorStands will also summon more ArmorStands around them in directions that there is water, and so on. The entity that they come from will also be remembered by their name.
Follow all of that up with:
/execute @e[name=Entity1] ~ ~ ~ /setblock ~ ~ ~ red_sandstone
/execute @e[name=Entity2] ~ ~ ~ /setblock ~ ~ ~ red_sandstone
Any solid block will do fine. This is to mark the water blocks as already having a marker ArmorStand on them, so that the future water detects will not spawn another one on that tile.
Repeat all of this search on a clock that terminates when the search succeeds, or the search has gone on for a certain number (I'd recommend R) of iterations (or it'll keep on going forever if they aren't in the same body of water). This search should look like this for each entity:
![The search of 1 entity](https://i.stack.imgur.com/c1d6r.gif)
To test if the search has succeeded, all you need to do is:
/execute @e[name=Entity1] ~ ~ ~ /testfor @e[r=1,Entity2]
Which will make each Entity1 ArmorStand look for adjacent Entity2 ArmorStands, at which point the two entities have been connected by an adjacent route.
To cleanup the all the red_sandstone and marker ArmorStands you just created for this search, all you need to do is:
/execute @e[name=Entity1] ~ ~ ~ /setblock ~ ~ ~ water
/execute @e[name=Entity2] ~ ~ ~ /setbock ~ ~ ~ water
/kill @e[name=Entity1, type=ArmorStand]
/kill @e[name=Entity2, type=ArmorStand]
And that's it done. This is very messy, but works well from what I've tried. It can detect if entities are connected even through mazes of water.
Best Answer
Without the use of redstone and block updates, it can become a bit complicated to replicate it. You will need to check the
SuccessCount
value of the command block running the initial/testforblock
command to determine when the block is no longer there. Image setup:The initial
/testforblock
command, checking for the stone button.Conditional. If the
/testforblock
command succeeded, set the impulse command block (#5) to have anauto
tag value of 1, which causes it to run its command. Unlike a repeating command block, it will only run its command a single time.auto
has to be set back to 0 before it can activate again. Change "X Y Z" to the coordinates of the impulse block.A secondary
/testforblock
that checks theSuccessCount
tag value of the repeating command block. If the value was 0, that means the stone button was not at the location, which means the impulse command block must haveauto
set back to 0.Conditional. If the
SuccessCount
value was indeed 0, set the impulse block'sauto
tag value to 0.This would be the command you want to run a single time when the stone button is at the location, but will be able to run a single time again if the stone button were to be removed and placed back down.
The benefit of doing it this way is to reduce the number of block updates occur, as
/blockdata
does not create block updates. The reduction is good for server performance.