package net.minecraft.command; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import javax.annotation.Nullable; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.scoreboard.Team; import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; public class CommandSpreadPlayers extends CommandBase { /** * Gets the name of the command */ public String getName() { return "spreadplayers"; } /** * Return the required permission level for this command. */ public int getRequiredPermissionLevel() { return 2; } /** * Gets the usage string for the command. */ public String getUsage(ICommandSender sender) { return "commands.spreadplayers.usage"; } /** * Callback for when the command is executed */ public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { if (args.length < 6) { throw new WrongUsageException("commands.spreadplayers.usage", new Object[0]); } else { int i = 0; BlockPos blockpos = sender.getPosition(); double d0 = parseDouble((double)blockpos.getX(), args[i++], true); double d1 = parseDouble((double)blockpos.getZ(), args[i++], true); double d2 = parseDouble(args[i++], 0.0D); double d3 = parseDouble(args[i++], d2 + 1.0D); boolean flag = parseBoolean(args[i++]); List list = Lists.newArrayList(); while (i < args.length) { String s = args[i++]; if (EntitySelector.isSelector(s)) { List list1 = EntitySelector.matchEntities(sender, s, Entity.class); if (list1.isEmpty()) { throw new EntityNotFoundException("commands.generic.selector.notFound", new Object[] {s}); } list.addAll(list1); } else { EntityPlayer entityplayer = server.getPlayerList().getPlayerByUsername(s); if (entityplayer == null) { throw new PlayerNotFoundException("commands.generic.player.notFound", new Object[] {s}); } list.add(entityplayer); } } sender.setCommandStat(CommandResultStats.Type.AFFECTED_ENTITIES, list.size()); if (list.isEmpty()) { throw new EntityNotFoundException("commands.spreadplayers.noop"); } else { sender.sendMessage(new TextComponentTranslation("commands.spreadplayers.spreading." + (flag ? "teams" : "players"), new Object[] {list.size(), d3, d0, d1, d2})); this.spread(sender, list, new CommandSpreadPlayers.Position(d0, d1), d2, d3, (list.get(0)).world, flag); } } } private void spread(ICommandSender sender, List p_110669_2_, CommandSpreadPlayers.Position pos, double spreadDistance, double maxRange, World worldIn, boolean respectTeams) throws CommandException { Random random = new Random(); double d0 = pos.x - maxRange; double d1 = pos.z - maxRange; double d2 = pos.x + maxRange; double d3 = pos.z + maxRange; CommandSpreadPlayers.Position[] acommandspreadplayers$position = this.createInitialPositions(random, respectTeams ? this.getNumberOfTeams(p_110669_2_) : p_110669_2_.size(), d0, d1, d2, d3); int i = this.spreadPositions(pos, spreadDistance, worldIn, random, d0, d1, d2, d3, acommandspreadplayers$position, respectTeams); double d4 = this.setPlayerPositions(p_110669_2_, worldIn, acommandspreadplayers$position, respectTeams); notifyCommandListener(sender, this, "commands.spreadplayers.success." + (respectTeams ? "teams" : "players"), new Object[] {acommandspreadplayers$position.length, pos.x, pos.z}); if (acommandspreadplayers$position.length > 1) { sender.sendMessage(new TextComponentTranslation("commands.spreadplayers.info." + (respectTeams ? "teams" : "players"), new Object[] {String.format("%.2f", d4), i})); } } private int getNumberOfTeams(List p_110667_1_) { Set set = Sets.newHashSet(); for (Entity entity : p_110667_1_) { if (entity instanceof EntityPlayer) { set.add(entity.getTeam()); } else { set.add(null); } } return set.size(); } private int spreadPositions(CommandSpreadPlayers.Position p_110668_1_, double p_110668_2_, World worldIn, Random random, double minX, double minZ, double maxX, double maxZ, CommandSpreadPlayers.Position[] p_110668_14_, boolean respectTeams) throws CommandException { boolean flag = true; double d0 = 3.4028234663852886E38D; int i; for (i = 0; i < 10000 && flag; ++i) { flag = false; d0 = 3.4028234663852886E38D; for (int j = 0; j < p_110668_14_.length; ++j) { CommandSpreadPlayers.Position commandspreadplayers$position = p_110668_14_[j]; int k = 0; CommandSpreadPlayers.Position commandspreadplayers$position1 = new CommandSpreadPlayers.Position(); for (int l = 0; l < p_110668_14_.length; ++l) { if (j != l) { CommandSpreadPlayers.Position commandspreadplayers$position2 = p_110668_14_[l]; double d1 = commandspreadplayers$position.dist(commandspreadplayers$position2); d0 = Math.min(d1, d0); if (d1 < p_110668_2_) { ++k; commandspreadplayers$position1.x += commandspreadplayers$position2.x - commandspreadplayers$position.x; commandspreadplayers$position1.z += commandspreadplayers$position2.z - commandspreadplayers$position.z; } } } if (k > 0) { commandspreadplayers$position1.x /= (double)k; commandspreadplayers$position1.z /= (double)k; double d2 = (double)commandspreadplayers$position1.getLength(); if (d2 > 0.0D) { commandspreadplayers$position1.normalize(); commandspreadplayers$position.moveAway(commandspreadplayers$position1); } else { commandspreadplayers$position.randomize(random, minX, minZ, maxX, maxZ); } flag = true; } if (commandspreadplayers$position.clamp(minX, minZ, maxX, maxZ)) { flag = true; } } if (!flag) { for (CommandSpreadPlayers.Position commandspreadplayers$position3 : p_110668_14_) { if (!commandspreadplayers$position3.isSafe(worldIn)) { commandspreadplayers$position3.randomize(random, minX, minZ, maxX, maxZ); flag = true; } } } } if (i >= 10000) { throw new CommandException("commands.spreadplayers.failure." + (respectTeams ? "teams" : "players"), new Object[] {p_110668_14_.length, p_110668_1_.x, p_110668_1_.z, String.format("%.2f", d0)}); } else { return i; } } private double setPlayerPositions(List p_110671_1_, World worldIn, CommandSpreadPlayers.Position[] p_110671_3_, boolean p_110671_4_) { double d0 = 0.0D; int i = 0; Map map = Maps.newHashMap(); for (int j = 0; j < p_110671_1_.size(); ++j) { Entity entity = p_110671_1_.get(j); CommandSpreadPlayers.Position commandspreadplayers$position; if (p_110671_4_) { Team team = entity instanceof EntityPlayer ? entity.getTeam() : null; if (!map.containsKey(team)) { map.put(team, p_110671_3_[i++]); } commandspreadplayers$position = map.get(team); } else { commandspreadplayers$position = p_110671_3_[i++]; } entity.setPositionAndUpdate((double)((float)MathHelper.floor(commandspreadplayers$position.x) + 0.5F), (double)commandspreadplayers$position.getSpawnY(worldIn), (double)MathHelper.floor(commandspreadplayers$position.z) + 0.5D); double d2 = Double.MAX_VALUE; for (CommandSpreadPlayers.Position commandspreadplayers$position1 : p_110671_3_) { if (commandspreadplayers$position != commandspreadplayers$position1) { double d1 = commandspreadplayers$position.dist(commandspreadplayers$position1); d2 = Math.min(d1, d2); } } d0 += d2; } d0 = d0 / (double)p_110671_1_.size(); return d0; } private CommandSpreadPlayers.Position[] createInitialPositions(Random p_110670_1_, int p_110670_2_, double p_110670_3_, double p_110670_5_, double p_110670_7_, double p_110670_9_) { CommandSpreadPlayers.Position[] acommandspreadplayers$position = new CommandSpreadPlayers.Position[p_110670_2_]; for (int i = 0; i < acommandspreadplayers$position.length; ++i) { CommandSpreadPlayers.Position commandspreadplayers$position = new CommandSpreadPlayers.Position(); commandspreadplayers$position.randomize(p_110670_1_, p_110670_3_, p_110670_5_, p_110670_7_, p_110670_9_); acommandspreadplayers$position[i] = commandspreadplayers$position; } return acommandspreadplayers$position; } /** * Get a list of options for when the user presses the TAB key */ public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { return args.length >= 1 && args.length <= 2 ? getTabCompletionCoordinateXZ(args, 0, targetPos) : Collections.emptyList(); } static class Position { double x; double z; Position() { } Position(double xIn, double zIn) { this.x = xIn; this.z = zIn; } double dist(CommandSpreadPlayers.Position pos) { double d0 = this.x - pos.x; double d1 = this.z - pos.z; return Math.sqrt(d0 * d0 + d1 * d1); } void normalize() { double d0 = (double)this.getLength(); this.x /= d0; this.z /= d0; } float getLength() { return MathHelper.sqrt(this.x * this.x + this.z * this.z); } public void moveAway(CommandSpreadPlayers.Position pos) { this.x -= pos.x; this.z -= pos.z; } public boolean clamp(double p_111093_1_, double p_111093_3_, double p_111093_5_, double p_111093_7_) { boolean flag = false; if (this.x < p_111093_1_) { this.x = p_111093_1_; flag = true; } else if (this.x > p_111093_5_) { this.x = p_111093_5_; flag = true; } if (this.z < p_111093_3_) { this.z = p_111093_3_; flag = true; } else if (this.z > p_111093_7_) { this.z = p_111093_7_; flag = true; } return flag; } public int getSpawnY(World worldIn) { BlockPos blockpos = new BlockPos(this.x, 256.0D, this.z); while (blockpos.getY() > 0) { blockpos = blockpos.down(); if (worldIn.getBlockState(blockpos).getMaterial() != Material.AIR) { return blockpos.getY() + 1; } } return 257; } public boolean isSafe(World worldIn) { BlockPos blockpos = new BlockPos(this.x, 256.0D, this.z); while (blockpos.getY() > 0) { blockpos = blockpos.down(); Material material = worldIn.getBlockState(blockpos).getMaterial(); if (material != Material.AIR) { return !material.isLiquid() && material != Material.FIRE; } } return false; } public void randomize(Random rand, double p_111097_2_, double p_111097_4_, double p_111097_6_, double p_111097_8_) { this.x = MathHelper.nextDouble(rand, p_111097_2_, p_111097_6_); this.z = MathHelper.nextDouble(rand, p_111097_4_, p_111097_8_); } } }