After playing around a bit, I have found a workaround for the non-functioning stat
objective. It works by using Flint and Steel with a durability of 0 (i.e. Damage of 64), which are automatically given to every player that does not currently have flint and steel somewhere in his inventory.
First, set up the objective as a dummy, also set up an objective tracking whether or not a TNT was already ignited.
/scoreboard objectives add hasFlintAndSteel dummy
/scoreboard objectives add Fuse dummy
Now create a fill clock and run the following 4 commands (in this order):
/scoreboard players set @a hasFlintAndSteel 0
/scoreboard players set @a hasFlintAndSteel 1 {Inventory:[{id:minecraft:flint_and_steel}]}
/scoreboard players add @e[type=PrimedTnt] Fuse 1
/execute @e[type=PrimedTnt,score_Fuse=1] ~ ~ ~ execute @p[score_flintandsteel=0,r=5] ~ ~ ~ tellraw @a ["",{selector:@p,bold:true}," has set us up the bomb!"]
/give @a[score_flintandsteel=0] minecraft:flint_and_steel 1 64
- The first two commands determine whether a player currently has flint and steel in this clock cycle/tick.
- The third command tracks the fuse time of all primed TNT entities. It is used to execute only on newly ignited TNT.
- The forth command checks for a player who just used his flint and steel in a 5 block radius around every freshly primed TNT. If a player is found, the tellraw command is executed at that player.
- The fith command gives an almost broken flint and steel to every player without one.
Since this method requires the Flint and Steel to break, this will only work in Survival or Adventure mode. Also, there is an annoying clunk sound and particles on screen every time you use your Flint and Steel.
If not everyone in your game has access to Flint and Steel, you can use another objective to only give it to the players that do in the 5th command.
What you are looking for is the amazing execute
command:
Executes a command on behalf of one or more other entities, with originating permissions, optionally on condition that a single-block /testforblock-style check passes.
The syntax is:
execute <entity> <x> <y> <z> <command …>
<entity>
is a target selector, such as @a
, <x> <y> <z>
are coordinates from which to execute the following <command …>
from. In most cases, setting this to ~ ~ ~
(i.e. the exact location of the entity) is fine. To set the block under every player to air, you can use
execute @a ~ ~ ~ setblock ~ ~-1 ~ air
Best Answer
Just in case anyone tried to look up how this problem could be accomplished, because this is the first result from google search. And I happened to work it out.
You can do this in 1.13+ now, with the
/execute store
commandThe steps are as follows: store player coordinates > calculate the differences > square the differences > sum up > calculate the sqrt values. I'm using euclidean distance as the metric.
1. Store Player Coordinates:
You'd need to define objectives to store the values, I defined them as
"X", "Y", and "Z"
2. Calculate the Differences:
I defined another set of objectives to store the results
"X_difference", "Y_difference", "Z_difference"
, but you don't have to.I defined another objective
"distance"
to store the sum of the squared values from 3.We can use a simple algorithm to calculate the square root values. You can find more info on how it works here. We need to create three new objectives:
sqrtI
,sqrtX
andrealDistance
. I highly recommend using a datapack to implement this, as we need to recursively get closer to the real square.Once you have your distance value, run the following to reset the sqrt algorithm:
mydatapack:sqrt.mcfunction contains the following commands:
The
realDistance
objective then contains the real distance that every single player is away from you in blocks.