Since Arrows don't contain the data of what bow shot it from, we must mark the arrow as its being shot.
Setup:
/scoreboard objectives add Shot stat.useItem.minecraft.bow
/scoreboard objectives add Holding dummy
/scoreboard objectives add LightingArrow dummy
/scoreboard objectives add InGround dummy
Clock(20tps)
/scoreboard players set @a Holding 0
/scoreboard players set @a Holding 1 {SelectedItem:{tag:{display:{Name:"Lightning Bow"}}}}
/execute @a[score_Shot_min=1,score_Holding_min=1] ~ ~ ~ scoreboard players set @e[type=Arrow,r=2] LightingArrow 1
/scoreboard players set @e[type=Arrow] InGround 1 {inGround:1b}
/execute @e[type=Arrow,score_LightingArrow_min=1,score_InGround_min=1] ~ ~ ~ summon LightningBolt ~ ~ ~
/kill @e[type=Arrow,score_LightingArrow_min=1,score_InGround_min=1]
/scoreboard players set @a Shot 0
Just like you can't use relative coordinates with ~
in NBT, you also can't use relative coordinates with ^
. What you can do instead is getting both your and the TNT's position and subtracting it to get a momentum.
For the position, you can use the NBT tag "Pos
", because that can be read with data get
. The rest is pretty straightforward, just putting Pos
NBT into scoreboards, applying an operation
to it and putting it back into NBT, this time Motion
.
Preparation:
scoreboard objectives add x dummy
scoreboard objectives add y dummy
scoreboard objectives add z dummy
When you want to activate it:
execute as @p at @s run summon tnt ^ ^ ^1 {Fuse:80,Tags:["toMove"]}
execute as @e[type=tnt,tag=toMove] store result score @s x run data get entity @s Pos[0] 50
execute as @e[type=tnt,tag=toMove] store result score @s y run data get entity @s Pos[1] 50
execute as @e[type=tnt,tag=toMove] store result score @s z run data get entity @s Pos[2] 50
execute as @p store result score @s x run data get entity @s Pos[0] 50
execute as @p store result score @s y run data get entity @s Pos[1] 50
execute as @p store result score @s z run data get entity @s Pos[2] 50
scoreboard players operation @e[type=tnt,tag=toMove] x -= @p x
scoreboard players operation @e[type=tnt,tag=toMove] y -= @p y
scoreboard players operation @e[type=tnt,tag=toMove] z -= @p z
execute as @e[type=tnt,tag=toMove] store result entity @s Motion[0] double 0.02 run scoreboard players get @s x
execute as @e[type=tnt,tag=toMove] store result entity @s Motion[1] double 0.02 run scoreboard players get @s y
execute as @e[type=tnt,tag=toMove] store result entity @s Motion[2] double 0.02 run scoreboard players get @s z
This works for multiple TNTs at once, but not yet for multiple players. If you want to use it in multiplayer, you have to replace @p
with your selector and probably also use tags for them.
For a way that works with multiple entities at once, see here.
Best Answer
you could use a repeating command block that has this command:
/execute @e[type=snowball] ~ ~ ~ detect ~ ~-1 ~ [block ground is made of] [tile data] /summon lightning_bolt ~ ~ ~
then in a attached chain command block put this:
execute @e[type=lightning_bolt] ~ ~ ~ /summon ender_crystal
then add a final chain command block that does this
/execute @e[type=ender_crystal] ~ ~ ~ /summon arrow ~ ~0.5 ~
then you should get a near instant explosion but you would also want another command to kill the snowball after impact, best using a conditional chain command block