Minecraft – How to allow Riptide to be combined with Channeling and Loyalty

minecraft-commandsminecraft-java-editionminecraft-mods

Title contains the core of it. The way I imagine it to work is:

  • When not in water/rain, instead of blocking you from throwing the trident, Riptide has no effect.
  • Riptide, when actually used, negates the effects of Channeling (and Loyalty since Riptide pretty much does that anyway). So when in water/rain, only the Riptide effect is applied. Otherwise, Channeling and Loyalty are applied.

While at it, several other enchantment patches (such as Smite and Bane of the Anthropods being compatible with and applied instead of lower-level Sharpness, and/or a similar approach for the Protection enchantments) would be appreciated, Riptide/Channeling/Loyalty is the top priority business for me though.

Whether through commands or a mod, I'll settle for any way if I have to. I'm no fan of inventing the wheel though.

Best Answer

I've developed a data pack that allows Riptide, Channeling, and Loyalty to be combined together. Anvils will work to combine Riptide but only when you are not in rain and Riptide is applied first; enchantment tables won't apply them together though.

The data pack is downloadable here.

Concepts used

  • I used commands from Bruno Rodrigues's answer to detect the weather. If you look at the function files, the commands will summon an armour stand at (0, 255, 0) and check the weather using it.
    summon armor_stand ~ ~ ~ {Invulnerable:1b,Invisible:1b,Fire:32766s,CustomName:'"rain"'}
    
    execute as @e[limit=1,name=rain,nbt={Fire:0s}] at @s run scoreboard players set $rain trident_inRain 3
    execute as @e[limit=1,name=rain,nbt={Fire:0s}] at @s run data modify entity @s Fire set value 30000
    execute as @e[name=rain] if score $rain trident_inRain matches 1.. run scoreboard players remove $rain trident_inRain 1
    
  • I used another answer from Bruno Rodrigues to check if the player is exposed to rain. This technique involves checking to see if all blocks above you are air. I set commands to cut a hole at column (0, 0), and then tested for players with that:
    fill 0 2 0 0 255 0 minecraft:air
    
    execute as @a at @s if blocks ~ ~1 ~ ~ 255 ~ 0 2 0 all run ...
    
  • I used a technique that displays fake CanPlaceOn/CanDestroy data on items through the item's lore, and modified it to display fake enchantments instead. When a user is not in the rain, the Riptide enchantment is removed from the enchantments list and a fake Riptide enchantment is added via the lore.
  • I used player inventory modification in order to modify player inventory data. This involves a special loot table, downloadable here.
    loot replace entity @p hotbar.0 1 mine 0 0 0 stick{drop_contents:1b}
    

If you experience any problems with this data pack, please create an issue on GitHub instead of commenting below!