I’m spawning players randomly but I didn’t know how to set a Y coordinate. So the solution I found was to set the Y value to 255 (maximum I think) and use a loop that would decrement this value while the player isn’t on ground. Here’s my code:
int x, y=255, z;
plugin.getLogger().info("Generate random coordonates");
x = randX + (int) Math.round(Math.sin((i*360)/players.size()) * radius);
z = randZ + (int) Math.round(Math.cos((i*360)/players.size()) * radius);
plugin.getLogger().info("X=" + x + " / Z=" + z);
plugin.getLogger().info("Set new position to the player");
p.setLocation(p.getLocation().setPosition(new Vector3d(x, y, z)));
plugin.getLogger().info("Call the while loop to set the new Y pos");
while(p.isOnGround()) {
plugin.getLogger().info("Player " + p.getName() + "isn't on the ground. Y = " + y);
y--;
}
p.setLocation(p.getLocation().setPosition(new Vector3d(x, y, z)));
This code is always calling the loop whereas it should never call it… But when I change while(p.isOnGround()) to while(!p.isOnGround()) the loop isn’t call.
uhm … why should it change?
if you do y-- you wont change the players y coord, just your local y variable
i would do it like this: (just pseudo example code)
Location l = new Location(world, x, y, z);
while(l.getBlock... (is no solid block)){
l = l.add(0, -1, 0);
if (l.getY() <= 0) break;
}
p.setLocation(l.add(0, 1, 0)); // push it up again 1 block so player isn't stuck in ground
Also, to explain why p.IsOnGroud() is true even after teleported high up in the air…
This variable is updated each tick (or so) … and if you teleport a player and immediately after that check isOnGround() the value isn’t updated yet and you still get the value from before the teleport
Random rand = new Random();
int randX = rand.nextInt(101)-50;
int randZ = rand.nextInt(101)-50;
int i = 0;
for(Player p: players) {
//Random coordinates
int x, y=255, z;
x = randX + (int) Math.round(Math.sin((i*360)/players.size()) * radius);
z = randZ + (int) Math.round(Math.cos((i*360)/players.size()) * radius);
//Initialize the location (X;Z)
Location<World> loc = new Location<World>(p.getWorld(), x, y, z);
plugin.getLogger().debug("New Location<World> :" + loc.toString());
plugin.getLogger().debug("Call the while loop to set the new Y pos");
while(loc.getBlock().getType().equals(BlockTypes.AIR)) {
plugin.getLogger().debug("The new Y=" + y);
loc.add(0, -1, 0);
y--;
//for non infinite loop
if (loc.getY() <= 0) break;
}
p.setLocation(new Location<World>(p.getWorld(), x, y+1, z));
displaySpawnLocation(p, x, y, z);
i++;
}
And there’s the crash log:
[01:16:20] [Server thread/DEBUG] [HG/]: New Location<World> :Location{(-28.0, 255.0, 28.0) in net.minecraft.world.WorldServer@4b513a02}
[01:16:20] [Server thread/DEBUG] [HG/]: Call the while loop to set the new Y pos
[01:16:20] [Server thread/DEBUG] [HG/]: The new Y=255
[01:16:20] [Server thread/DEBUG] [HG/]: The new Y=254
[01:16:20] [Server thread/DEBUG] [HG/]: The new Y=253
[01:16:20] [Server thread/DEBUG] [HG/]: The new Y=252
[01:16:20] [Server thread/DEBUG] [HG/]: The new Y=251
[01:16:20] [Server thread/DEBUG] [HG/]: The new Y=250
The loop is endless
EDIT: Sorry but the debug message doesn’t appear in the console so I thought it came from Location<World> loc = new Location<World>(p.getWorld(), x, y, z); whereas it is actually coming from the while loop.