newSpawn is an Optional, you need to check if it contains any reference, and if it does, get this reference before using it:
Optional<Location<World>> newSpawn = Sponge.getGame().getTeleportHelper().getSafeLocation(location, 10, 30);
if(!newSpawn.isPresent) {
//no safe locations exists, you need to do something in that case
}
Location<World> safeNewSpawn = newSpawn.get();
To get the coordinates of a Location you can simply call Location.getPosition().
Ok…but here’s the thing…i’m trying to grab random positions withing that 30block radius if they’re safe to spawn entities. Not my location…I’m only using my location as a focus point.
for example how would i set everything at a 5 block distance to be a new spawn point?
Edit: Perhaps my title was to broad of a question. I’ve updated the title to hopefully solve any confusion.
AFAIK there is no constructor or convenience method to create a random vector in Sponge. Here is how I prefer to do it. Start with a base unit vector. Rotate it by some random amounts. The expand it by the maximum length.
Also remember that you can get a vector from a Location.
Here is roughly how I would do it with my own vectors. Don’t go looking for these methods on the Sponge vectors. You most likely won’t find them. Here is a link to my own Vector3. It’s written in Scala, but then again it’s mostly just math so it shouldn’t matter too much. https://github.com/Katrix-/DanmakuCore/blob/master/src/main/scala/net/katsstuff/danmakucore/data/vec3.scala (Please excuse the mess in there. It’s been some time since I cleanup up that class.)
K…well here’s what i came up with that is still only getting my player’s location… I’m probably using the wrong method within Vector3d…so how would i set the max?
public class SpawnTesting {
public void getSpace(final Player player){
if (!(player == null)){
Vector3d playersVector = player.getLocation().getPosition();
playersVector.max(10, 10, 10);
Sponge.getGame().getServer().getBroadcastChannel().send(Text.of(TextColors.AQUA, playersVector));
I’m trying to get a random coordinate within a specific radius of my player…not my players radius lol :’( this is the first time i’ve dealt with vectors to be honest. That’s why I’m a bit confused…I’ve set the ‘max’ method…but it’s still just giving me the players vector.
Edit: this is mainly because there doesn’t seem to be an offset option for vectors…
max for vector is roughly the same as the max you find in Math. Looked through the Vector3d class though and there does seem to be a method to get a random vector, so that shouldn’t be a problem. Once you have your random vector you can’t just add it to the player’s vector as it is. That only offsets the players vector by 1 block (most random vector methods gives you back a unit vector, that is a vector representing a direction with a length of 1). What you want is a vector with a length up to 30. An easy way to change the length of a unit vector to a given value is to scale that unit vector by the desired length (multiplication).
For a better understanding of vectors and what you can do with them I’d recommend you to read a bit over this page. Euclidean vector - Wikipedia
You don’t have to read it all, Vector algebra is the most important to just get the general gist of it. Basic properties can also be nice to read.
Get a a random unit vector back from the method in Vector3d. Multiply it with the desired length (in this case a value up to 30). The add this value to the player’s position vector. You now have a vector for some random point within 30 blocks of the player.
You are amazing! YoI’ve given me references and examples! And have been patient throughout this! Thank you. I will be trying the above once I’m at home tonight
Though I’m not sure where to set the 30 quite… here
Edit: and it definetly doesn’t like that :’( Can you help out with this? You seem to understand it a lot and I just need an example that’ll work in order for me to understand it
Nearly there. You need to scala the vector to your desired length. Here that is just a number up to 30. Just to something like angle.multiply(random.nextDouble() * 30D) (Can’t remember the exact method name to multiply with these vectors). Go and look for it yourself. Once you have that you can add it to the player vec like you are currently doing.
Eh, a step backwards I’d say. The Sponge vectors are immutable, so if you do something to it you also have to assign it to a variable. If not it’s just dead code that won’t do anything. What you want to do is to use trial as the angle vector. As such you need to multiply trial by the desired length. Here’s the correct code to explain it better. Try to read the comments and understand what’s happening.
Vector3d playersVector = player.getLocation().getPosition(); //We get the players current position
Vector3d angle = Vector3d.createRandomDirection(random); //We create a new random unit vector. This is done by creating a vector from a random pitch and yaw value.
double scale = random.nextDouble() * 30D; //We got some random double, and then multiply it by 30. This will make sure that it goes from 0 to 30 instead of 0 to 1. It's easier to explain if we multiply with 10. Let's say that we have our random double rand. If rand == 0, and we multiply it with 10, it will stay at 0. If rand == 0.1, and we multiply it with 10 it will be 0.1, and so it goes to all values.
Vector3d scaledVector = angle.mul(scale); //Now that we have our scale, we multiply the angle with the scale. We have to assign it to a variable as Vector3d is immutable. While before angle had just a direction (and a length of 1), it now has both a direction, and the amount to go in that direction.
Vector3d newVector = playersVector.add(scaledVector); //We add the scaled vector to our player vector, and thus offset the player vector with the scaledVector.
Sponge.getGame().getServer().getBroadcastChannel().send(Text.of(TextColors.AQUA, playersVector));
If you still have problems understanding it, let’s try to think of how it would look if everything was one dimensional instead of three dimensional.
double playersPos = player.getLocation().getPosition(); //If everything was one dimensional, the vectors would be just doubles
double direction = random.nextBoolean() ? 1D : -1D; //In one dimension there are just two ways to go, so a random boolean is enough.
double scale = random.nextDouble() * 30D; //We create our scala again.
double scaledDirection = direction * scale; //We then apply our scale to our direction
double newPos = playerPos + scaledDirection; //We offset the player's current position by our value.
Sponge.getGame().getServer().getBroadcastChannel().send(Text.of(TextColors.AQUA, newPos));
If you’re using the code above and it doesn’t send, no idea. Some exception maybe? You’d have to show the rest of your code to be able to help you there. This doesn’t have anything to do with a random position anymore.