When playing on a Vanilla server like the Maizuma Creative Server, people start missing plugins and mods normally used on public servers.
I often ask what our group would like to see implemented on the server and, when the Back function was suggested, everyone loved the idea.
What this function does is to remember your position every time before you teleport, so you can go return there by just using a command. It's a really simple yet really useful tool to have, so I started to work on a command block version of it, which I named the Return Function.
I originally made the system for our multiplayer server, but I also decided to make a tiny single player version so I can release it to anyone who wants to have it in their world. There'll be an One Command install it after the explanation!
Well, let's talk about how everything works!
The Single Player Version [gfy]
The basic idea behind the Return function is to remember the player's position before teleporting. They can then type a trigger command, which works for non OP players, to return there whenever they want.
We can leave an stationary entity at the saved location to keep track of it. Returning there is as easy as teleporting to the marker created when teleporting.
Of course we need to be always able to find the entity if we want to teleport to it, so it's also necessary to keep it loaded. There is a ton of ways to achieve that and I discussed them on this post about Chunk Loaders.
In this case I used the Arrow Method, that relies on summoning an arrow and teleporting it to loaded chunks after it hits a block. I like this method as it's very easy to set up and causes no lag compared to others, needing only a slow clock making sure the arrow doesn't despawn.
However, there is a very specific problem we may run into, when a player instantly leaves and "unloads" an area, turning the chunks they were at into lazy chunks, that don't process entities, and not letting the arrows hit a block, process necessary for the loader to work.
To avoid the problem, we can either load a 5x5 area of chunks around the arrow - which is not a really good idea haha - or create the arrow before the player teleports. This second idea is much better.
Anyhow, I called the fortune teller society and no one answered me - they already knew what I was going to ask - so, as far as I know, there is no way to know when a player will teleport before they do.
What we actually do is to create a temporary loader periodically, deleting the previous every time we create a new one. When a player actually teleports, the current temporary loader will become permanent.
It might not sound like the best idea lag-wise, but it doesn't cause any problems, as it'll just kill 2 entities and summon another 2. I used a 1 second clock and works fine, yet you can also make it even slower if you wish to, just keep in mind it'll take longer and longer to save your location.
Well, with the problem out of the way, we just need to know when a player teleports, which is pretty straighfoward.
To detect when a player moves a certain amount of blocks in an instant, we can compare their previous position to the new one.
One tracker entity is all we need to compare the positions. It will constantly be teleported to the player and, on the next tick, before teleporting again, the entity detects if it is at least a minimum distance away from them. If that's the case, the system deletes the last position saved and saves a new one.
In any case, the tracker will always be teleported back to the player after the check is done.
That's pretty much it. The single player version doesn't require a lot to work to be done.
I also compacted it into a 1 Command Block creation so you can install it on your single player world. The command can be found here (the command blocks look different from the gfy, but it works the same way).
If you find any problems with the system, please let me know so I can fix it.
The Return Function, after being installed with 1 command
Oh, before going into the multiplayer version, I just want to let you know the system doesn't work in the Nether and the End, due to command blocks not being able to handle entities at different dimensions correctly or reliably.
The Multiplayer Version [gfy]
Let's now jump into the multiplayer version, which is very similar as the single player one in essence, just with some more additions to be able to handle multiple people at once.
To mark the position where the players have to go back to, we keep using a marker entity. However, we will now use an ID score system so we can know to whom each one belongs.
The IDs are given to every player who teleports using the Command Book and Tellraw menu, even if they aren't officially part of the MCS group, and it gets cleared from them when they log off. If the ID is cleared, both the loader and the position marker correspondent will be deleted to avoiding multiple chunks unnecessarily loaded.
To return people to their original position, if they use the Return function, we teleport them to the markers created before they teleport, just like the single player version, though we have to know which marker belongs to the player requesting the Return.
To associate the two with equal ID scores, we can use the player's score and remove it from all markers. The one left with a score of 0 will be the correspondent marker to which the player will teleport.
Of course, the score will be then added back to the markers so they have their original ID score back.
Now, to know when markers and their loaders are no longer needed, because the player with the ID correspondent to them logged off, we use a system similar to detecting players joining or leaving the server, like we did to refresh the Command Book to people logging in on a previous post.
We have a normal clock running a /testfor, checking for players with any score on the ID objective. A comparator taking an output from the command block will point at a BUD, which will update if any changes happen to the amount of players with said score.
It is worth mentioning that, even though a comparator can only output a signal strength up to 15, if the SuccessCount of the command block goes higher than that, the comparator will also update the BUD.
A clock testing for players with any score on the ID objective, with a comparator pointing into a BUD
The ID System
Being detected a change in the ID score list, we now will decide how we are going to handle the extra markers, if that is the case. There are two methods used, an instant one, that can only handle 1 extra marker at once, and a slow one, that can handle many extra markers at once. We could always use the slow method, however it can take a long time to process, if there are many IDs, and it keeps us from letting players teleport using the book.
Using the instant method is preferable. It is most times the case as well.
Anyway, to know when we use one or the other we will see if there are 2 or more extra markers in comparison to the amount of players. To count both, as well as to do more calculations later on, we use 2 entities which I'll refer as ReturnCP (Return Calculation - Players) and ReturnCL (Return Calculation - Loaders).
We firstly make every player with an ID score add 1 to ReturnCP and every loader add 1 to ReturnCL. We just do a scoreboard operation to remove the score of ReturnCP from ReturnCL.
The end results can be 0, meaning the amount of players is equal to the amount of loaders, nothing is done in this case; 1, meaning there is only 1 extra loader, so we execute the instant method; and 2 or more, leaving us to execute the slow method.
The Instant Method
This method consists of adding all the ID scores of players to ReturnCP and all the ID scores of loaders to ReturnCL, then subtracting ReturnCL from ReturnCP. The result will be the exact ID score from the missing player, remembering that there is one extra loader because that person left.
We then remove the result from all loaders, so we know the respective one will always be left with score of 0. The one found is killed and we add back the result to the remaining loaders.
We can't use this if there are more than 2 loaders because the end result would be the sum of those, not letting us know exactly which ones are unnecessary.
The Slow Method
This method is rarely used, yet still needed, in case two or more players leave the game at once for any reason.
It consists of taking all the loaders, one by one, and checking if there is a player for each. The ones without respective players will be deleted.
Before the process starts, we first need to stop the teleport commands from being executed, as they use the ID scores of players to remember their original position before moving, used for the Return function.
We start the clock setting an impulse command block to auto:1b, which will execute all the following commands. The command block will set itself back to auto:0b and, only if the clock needs to cicle again, it'll be set back to auto:1b, repeating the process.
The actual commands will first add 1 to a counter, using the ReturnCL in this case, and then remove 1 from every loader and player with an ID score, with the objective of having a single one of each with a score of 0. If there is a loader but no person with a score of 0, it'll be deleted.
The process repeats as long as there are loaders with at least 1 on ID. If all have been checked, they will all have a score of 0 or less, so the impulse command block at the start won't be set to auto:1b and the clock will stop.
We can detect when the command that keeps the clock running fails and execute the final commands to reset everything, which adds the score accumulated by ReturnCL to all remaining loaders, restoring their original ID score, and lets the teleports to be used again.
And that is the Return Functions explained! If you have any questions you want to make or something you want to point out, please comment below.
Feel free to use the 1 Command to install it on your single player word. Again, it can be found here.
Apart from that, I hope you've liked the post. Thank you for reading as always and see you next time!
No comments:
Post a Comment