In Minecraft, how do I make water buckets only placeable on certain blocks?
MC-131346 was fixed, so the new answer to this question is: It just works. /give @s water_bucket{CanPlaceOn:["stone"]}
gives you the proper water bucket that can only be placed on stone.
Here is the old answer for reference, in case you're playing in an older version:
As OnePointZero said, usually CanPlaceOn
should just work for buckets, but due to MC-131346 it doesn't. But there's an easier way to work around it:
Give the player a retextured item that he doesn't usually have anywhere else in your map and that also doesn't appear as a block in it. One idea would be a structure void or, if the item remodeling is too difficult, a sapling, bed, rail or other placeable item with a different texture than the block, as long as it's not anywhere else in the map.
That item has to have the CanPlaceOn
tag, here demonstrated with a stone:
/give @s stone{CanPlaceOn:["sandstone"]}
Then you track the usage of this item, like this:
/scoreboard objectives add placedStone minecraft.used:minecraft.stone
And whenever someone places it, you replace the block in the world with water:
/execute at @a[scores={placedStone=1..}] run fill ~-7 ~-7 ~-7 ~7 ~7 ~7 water replace stone
Luckily /fill
already updates all blocks consistently, so it will begin to flow automatically and you don't have to bother with the inconsistent updates of /setblock
.
Now you just reset the scoreboard for later use:
/scoreboard players set @a[scores={placedStone=1..}] placedStone 0
The last two commands go into repeating command chain or a function. The second command block can be conditional.
This is a bug that was reported on https://bugs.mojang.com/browse/MC-131346 that gave players in adventure mode the ability to pick up and place water, lava, or buckets of fish on any block, even if there was no CanPlaceOn or CanDestroy tag. It is (hopefully) being fixed.
However, my workaround in the meantime was this:
I retextured a tool with the texture of a water bucket but it is only viewable at a certain durability. I set it to Unbreaking to remove the durability bar. Whenever the player wanders from the area I allowed them to place the water, I clear them of the real water bucket and give them the fake, retextured one. Whenever they return to those specific areas, I clear the fake one and give them a real one that says what block it can be placed on, then fill the entire area with moving pistons except for the block surface I said the water could be placed on. It wasn't easy, but it's possible.