diff --git a/src/main/java/org/ultramine/commands/basic/TechCommands.java b/src/main/java/org/ultramine/commands/basic/TechCommands.java index d223279..42dfced 100644 --- a/src/main/java/org/ultramine/commands/basic/TechCommands.java +++ b/src/main/java/org/ultramine/commands/basic/TechCommands.java @@ -7,8 +7,10 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; +import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChatComponentText; import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MathHelper; import static net.minecraft.util.EnumChatFormatting.*; import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; @@ -21,6 +23,7 @@ import org.ultramine.server.MultiWorld; import org.ultramine.server.Restarter; import org.ultramine.server.Teleporter; +import org.ultramine.server.WorldsConfig.WorldConfig.Border; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -381,4 +384,147 @@ System.gc(); ctx.sendMessage("command.javagc.success"); } + + private static WorldGenerator worldgen; + + @Command( + name = "genworld", + group = "technical", + permissions = {"command.genworld"}, + syntax = { + "", + "[stop]", + "", + "[radius] ", + "[radius] " + } + ) + public static void genworld(CommandContext ctx) + { + if(ctx.getAction().equals("stop")) + { + FMLCommonHandler.instance().bus().unregister(worldgen); + worldgen = null; + ctx.sendMessage("command.genworld.stop"); + return; + } + + if(worldgen != null) + ctx.failure("command.genworld.already"); + + int dim = ctx.getSenderAsPlayer().worldObj.provider.dimensionId; + int radius = ctx.contains("radius") ? ctx.get("radius").asInt(1) : -1; + int cpt = ctx.contains("radius") ? ctx.get("radius").asInt(1) : 1; + + int x = MathHelper.floor_double(ctx.getSenderAsPlayer().posX); + int z = MathHelper.floor_double(ctx.getSenderAsPlayer().posZ); + + worldgen = radius == -1 ? new WorldGenerator(dim, cpt) : new WorldGenerator(dim, x, z, radius, cpt); + FMLCommonHandler.instance().bus().register(worldgen); + ctx.sendMessage("command.genworld.start"); + } + + public static class WorldGenerator + { + private final int dim; + private final int chunksPerTick; + private final boolean isBorder; + + private int borderInd = 0; + private int minX = Integer.MIN_VALUE; + private int minZ; + private int maxX; + private int maxZ; + + private int x; + private int z; + + private int totalGenerated; + + public WorldGenerator(int dim, int chunksPerTick) + { + this.isBorder = true; + this.dim = dim; + this.chunksPerTick = chunksPerTick; + } + + public WorldGenerator(int dim, int chunksPerTick, int centX, int centZ, int radius) + { + this.isBorder = false; + this.dim = dim; + this.chunksPerTick = chunksPerTick; + + minX = (centX - radius) >> 4; + minZ = (centZ - radius) >> 4; + maxX = (centX + radius) >> 4; + maxZ = (centZ + radius) >> 4; + + x = minX; + z = minZ; + } + + @SubscribeEvent + public void onTick(TickEvent.ServerTickEvent e) + { + if(e.phase == TickEvent.Phase.START) + { + WorldServer world = MinecraftServer.getServer().getMultiWorld().getOrLoadWorldByID(dim); + if(world == null) + return; + Border[] borders = world.getConfig().borders; + int counter = 0; + l1: + while(borderInd < (isBorder ? borders.length : 1)) + { + if(minX == Integer.MIN_VALUE) + { + Border border = borders[borderInd]; + + minX = (border.x - border.radius) >> 4; + minZ = (border.z - border.radius) >> 4; + maxX = (border.x + border.radius) >> 4; + maxZ = (border.z + border.radius) >> 4; + + x = minX; + z = minZ; + } + + while(x < maxX) + { + while(z < maxZ) + { + if(world.getBorder().isChunkInsideBorder(x, z) && !world.theChunkProviderServer.isChunkGenerated(x, z)) + { + if(++counter > chunksPerTick) break l1; + + world.theChunkProviderServer.provideChunk(x, z); + world.theChunkProviderServer.unloadChunksIfNotNearSpawn(x, z); + } + + z++; + } + + if(++x != maxX) z = minZ; + } + + if(x == maxX && z == maxZ) + { + borderInd++; + minX = Integer.MIN_VALUE; + } + } + + totalGenerated += counter; + if(totalGenerated % 600*chunksPerTick == 0) + MinecraftServer.getServer().getConfigurationManager().sendChatMsg(new ChatComponentTranslation("command.genworld.process", totalGenerated)); + + if(borderInd >= (isBorder ? borders.length : 1)) + { + FMLCommonHandler.instance().bus().unregister(worldgen); + worldgen = null; + MinecraftServer.getServer().getConfigurationManager().sendChatMsg(new ChatComponentTranslation("command.genworld.complete", totalGenerated)); + } + } + } + } } diff --git a/src/main/java/org/ultramine/server/MultiWorld.java b/src/main/java/org/ultramine/server/MultiWorld.java index 3b5b089..41149a8 100644 --- a/src/main/java/org/ultramine/server/MultiWorld.java +++ b/src/main/java/org/ultramine/server/MultiWorld.java @@ -301,6 +301,15 @@ return dimToWorldMap.get(dim); } + public WorldServer getOrLoadWorldByID(int dim) + { + WorldServer world = dimToWorldMap.get(dim); + if(world != null) + return world; + DimensionManager.initDimension(dim); + return dimToWorldMap.get(dim); + } + public WorldServer getWorldByName(String name) { return nameToWorldMap.get(name); diff --git a/src/main/resources/assets/ultramine/lang/en_US.lang b/src/main/resources/assets/ultramine/lang/en_US.lang index ce1cabb..c7087ee 100644 --- a/src/main/resources/assets/ultramine/lang/en_US.lang +++ b/src/main/resources/assets/ultramine/lang/en_US.lang @@ -194,3 +194,11 @@ command.custmsg.usage=/custmsg command.custmsg.description=Sends custom formatted message to player (support colors, use &) + +command.genworld.usage=/genworld [chunks per tick] OR /genworld [chunks per tick] OR /genworld stop +command.genworld.description=Generateas area radially or inside world border +command.genworld.already=World is now generating. Type "/genworld stop" before +command.genworld.start=World generation started +command.genworld.stop=World generation stopped +command.genworld.complete=World generation completed (generated %s chunks) +command.genworld.process=World generation: generated %s chunks diff --git a/src/main/resources/assets/ultramine/lang/ru_RU.lang b/src/main/resources/assets/ultramine/lang/ru_RU.lang index bdc6cfd..0819985 100644 --- a/src/main/resources/assets/ultramine/lang/ru_RU.lang +++ b/src/main/resources/assets/ultramine/lang/ru_RU.lang @@ -194,3 +194,11 @@ command.custmsg.usage=/custmsg <игрок/ALL> <сообщение> command.custmsg.description=Отправляет кастомное сообщение игроку (поддерживает цвета) + +command.genworld.usage=/genworld [чанков за тик] ИЛИ /genworld <радиус> [чанков за тик] ИЛИ /genworld stop +command.genworld.description=Генерирует мир по радиусу или в пределах мирового барьера +command.genworld.already=Генерауия мира уже запущена. Сначала введите "/genworld stop" +command.genworld.start=Генерация мира остановлена запущена +command.genworld.stop=Генерация мира остановлена +command.genworld.complete=Генерация мира завершена (сгенерировано %s чанков) +command.genworld.process=Генерация мира: сгенерировано %s чанков