2

I am fully aware of the /spawnpoint command, however this does not quite work for my purposes. I am making a plugin that allows people to do the "heart tree" challenge easily, and I want to set their spawnpoint to the tree they choose. I already have a system in place for when they choose a tree, meaning I would only have to insert a function or commands for the spawnpoint thing there.

TL;DR I want them to be able to set their spawns somewhere else, and if their other spawn gets destroyed their spawn, and ONLY their spawn, is reset to the original tree position. (Because different players can have different trees, world spawn will not serve.)

I am going to make the small area at their first tree ungriefable, so the spawn there will be impossible to invalidate, but it's really setting their spawn back there that I find to be an issue. I know how to check whether their spawn disappears, but I cannot think of any methods to set their spawn there without messily force loading chunks in order to /execute as an invisible armor stand in place, or something along those lines.

1
  • can't you just have a scoreboard trigger that has them execute /spawnpoint and save their coords in a scoreboard, spawn a marker or armor stand in the block below assuming thats where the tree heart block thing is, and then just test if the block is destroyed each tick with /data, and it can't be destroyed when unloaded anyway Commented May 31, 2023 at 8:19

1 Answer 1

2

It's not actually as complex as you make it out to be.

Here is a post that goes into great detail about how to move an entity / player to a position stored in a score.
Armed with this knowledge, and seeing how you say you've already figured out how to know whether they respawned without an active spawn, you should be able to hook up the linked system to something that checks players respawning without a valid spawnpoint, teleporting to their starting position stored in scoreboards and lastly setting their spawnpoint using the /spawnpoint command without arguments to set the spawn to the current execution point / their position.


For the sake of preserving knowledge in case the above link goes dead, here are the contents of the link:

Teleport an entity to the position set in a score

Assuming your desired position is stored in the entity's posX, posY and posZ value, you can just run execute store to save the score into the Position like this:

execute store result entity @s Pos[0] double 1 run scoreboard players get @s posX
execute store result entity @s Pos[1] double 1 run scoreboard players get @s posY
execute store result entity @s Pos[2] double 1 run scoreboard players get @s posZ

Be aware that if the entity enters unloaded chunks at any point during this operation, it might not continue to work, especially if you're not using a function to do this. So if your X moves the entity out of the loaded chunks, the Y and Z won't be applied anymore. If you're running the commands from above in a function you'll be fine, as we don't need to re-find the entity because we're using the @s selector.

Teleport the player to the position set in a score

The problem with the player is that the player NBT data cannot be modified and thus we can't just set their position like we can with entities. There are three decent ways to go about this:

1: Binary Teleportation

you basically copy their score to some temporary score so you don't loose it when you modify it, and then you go through the different powers of 2 (hence the name), check if their score is above that and then teleport them relatively that far.

teleport @p 0 0 0

execute at @p if entity @p[scores={xTmp=128..}] tp @p ~128 ~ ~
scoreboard players remove @p[scores={xTmp=128..}] xTmp 128

execute at @p if entity @p[scores={xTmp=64..}] tp @p ~64 ~ ~
scoreboard players remove @p[scores={xTmp=64..}] xTmp 64

execute at @p if entity @p[scores={xTmp=32..}] tp @p ~32 ~ ~
scoreboard players remove @p[scores={xTmp=32..}] xTmp 32

....
all the way down to 1, repeat for all 3 coordinates

this does use a lot of commands but using a function it's fairly easy to do and you can go as high as you want. Always start with the highest power of 2.

2: End Gateways

You can use end gateways to teleport the players to an exact location, see this for more info..

Basically you can set its block NBT Data to ExactTeleport:1b,ExitPortal:{X:1,Y:2,X:3} using data merge block or execute store and then teleport the player into said portal. Thanks to execute store you can set the Exit Portal NBT dynamically:

setblock 0 5 0 minecraft:end_gateway{ExactTeleport:1b,ExitPortal:{X:0,Y:0,Z:0}}
execute store result block 0 5 0 ExitPortal.X int 1 run scoreboard players get @s MapX
execute store result block 0 5 0 ExitPortal.Y int 1 run scoreboard players get @s MapY
execute store result block 0 5 0 ExitPortal.Z int 1 run scoreboard players get @s MapZ
tp @s 0 5 0

Make sure the position you're using for the endgateway is in the loaded chunks. End Gateways sometimes shoot out beacon beams, especially when they are newly created, so you migh want to add set the portal once and not every time you need it.

3: Use an entity

Summon an entity, use the above method to teleport the entity to the position and then teleport the player to the entity. Here it is also important that the entity is @s from the moment you move it, in case it goes into unloaded chunks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.