diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 863130c5e..4cd72538a 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -55,7 +55,7 @@ public class LodBufferBuilder /** how many chunks to generate outside of the player's * view distance at one time. (or more specifically how * many requests to make at one time) */ - public int maxChunkGenRequests = 8; + public int maxChunkGenRequests = Runtime.getRuntime().availableProcessors(); public LodBufferBuilder(LodBuilder newLodBuilder) diff --git a/src/main/java/com/seibel/lod/builders/LodChunkGenWorker.java b/src/main/java/com/seibel/lod/builders/LodChunkGenWorker.java index eec38da21..bfc48b77b 100644 --- a/src/main/java/com/seibel/lod/builders/LodChunkGenWorker.java +++ b/src/main/java/com/seibel/lod/builders/LodChunkGenWorker.java @@ -19,8 +19,12 @@ import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.chunk.ChunkStatus; import net.minecraft.world.chunk.IChunk; import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.feature.BaseTreeFeatureConfig; +import net.minecraft.world.gen.feature.ConfiguredFeature; +import net.minecraft.world.gen.feature.Features; import net.minecraft.world.gen.feature.IceAndSnowFeature; import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraft.world.gen.feature.TreeFeature; import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorldLightManager; import net.minecraftforge.common.WorldWorkerManager.IWorker; @@ -29,11 +33,11 @@ import net.minecraftforge.common.WorldWorkerManager.IWorker; * This is used to generate a LodChunk at a given ChunkPos. * * @author James Seibel - * @version 6-22-2021 + * @version 6-23-2021 */ public class LodChunkGenWorker implements IWorker { - public static final ExecutorService genThreads = Executors.newFixedThreadPool(16); + public static final ExecutorService genThreads = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); private boolean threadStarted = false; private LodChunkGenThread thread; @@ -132,43 +136,63 @@ public class LodChunkGenWorker implements IWorker List chunkList = new LinkedList<>(); ChunkPrimer chunk = new ChunkPrimer(pos, UpgradeData.EMPTY); chunkList.add(chunk); -// int width = 0; -// for(int i = pos.x - width; i < pos.x + width; i++) -// { -// for(int j = pos.x - width; j < pos.x + width; j++) -// { -// if(i == pos.x && j == pos.z) -// { -// chunkList.add(chunk); -// } -// else -// { -// chunkList.add(new ChunkPrimer(new ChunkPos(i,j), UpgradeData.EMPTY)); -// } -// } -// } ChunkGenerator chunkGen = serverWorld.getWorld().getChunkProvider().getChunkGenerator(); ChunkStatus.EMPTY.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); - //ChunkStatus.STRUCTURE_STARTS.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); - //ChunkStatus.STRUCTURE_REFERENCES.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); for(IChunk c : chunkList) ((ChunkPrimer)c).setStatus(ChunkStatus.STRUCTURE_REFERENCES); ChunkStatus.BIOMES.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); ChunkStatus.NOISE.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); ChunkStatus.SURFACE.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); - //ChunkStatus.CARVERS.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); - //ChunkStatus.LIQUID_CARVERS.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); -// for(IChunk c : chunkList) -// ((ChunkPrimer)c).setStatus(ChunkStatus.LIQUID_CARVERS); - //ChunkStatus.FEATURES.doGenerationWork(serverWorld, chunkGen, serverWorld.getStructureTemplateManager(), (ServerWorldLightManager) serverWorld.getLightManager(), null, chunkList); - LodServerWorld lodWorld = new LodServerWorld(chunk); + LodServerWorld lodWorld = new LodServerWorld(chunk, serverWorld); + IceAndSnowFeature snowFeature = new IceAndSnowFeature(NoFeatureConfig.field_236558_a_); snowFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos(), null); + TreeFeature treeFeature = new TreeFeature(BaseTreeFeatureConfig.CODEC); + treeFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos(), Features.SPRUCE.getConfig()); + treeFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos(), Features.OAK.getConfig()); + treeFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos(), Features.PINE.getConfig()); + + + + try + { + // TODO fix concurrent exception + + ConfiguredFeature configFeature = new ConfiguredFeature(Features.PATCH_TALL_GRASS.feature, Features.PATCH_TALL_GRASS.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_TALL_GRASS_2.feature, Features.PATCH_TALL_GRASS_2.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_TAIGA_GRASS.feature, Features.PATCH_TAIGA_GRASS.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + + configFeature = new ConfiguredFeature(Features.PATCH_GRASS_PLAIN.feature, Features.PATCH_GRASS_PLAIN.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_GRASS_FOREST.feature, Features.PATCH_GRASS_FOREST.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_GRASS_BADLANDS.feature, Features.PATCH_GRASS_BADLANDS.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_GRASS_SAVANNA.feature, Features.PATCH_GRASS_SAVANNA.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_GRASS_NORMAL.feature, Features.PATCH_GRASS_NORMAL.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_GRASS_TAIGA_2.feature, Features.PATCH_GRASS_TAIGA_2.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + configFeature = new ConfiguredFeature(Features.PATCH_GRASS_TAIGA.feature, Features.PATCH_GRASS_TAIGA.config); + configFeature.generate(lodWorld, chunkGen, serverWorld.rand, chunk.getPos().asBlockPos()); + } + catch(Exception e) + { + //e.printStackTrace(); +// System.out.println(); + } + + + LodChunk lod = lodBuilder.generateLodFromChunk(chunk, false); lodDim.addLod(lod); diff --git a/src/main/java/com/seibel/lod/builders/LodServerWorld.java b/src/main/java/com/seibel/lod/builders/LodServerWorld.java index 456e0d5fa..8e9e42878 100644 --- a/src/main/java/com/seibel/lod/builders/LodServerWorld.java +++ b/src/main/java/com/seibel/lod/builders/LodServerWorld.java @@ -25,6 +25,7 @@ import net.minecraft.util.math.SectionPos; import net.minecraft.util.registry.DynamicRegistries; import net.minecraft.world.DifficultyInstance; import net.minecraft.world.DimensionType; +import net.minecraft.world.EmptyTickList; import net.minecraft.world.ISeedReader; import net.minecraft.world.ITickList; import net.minecraft.world.LightType; @@ -42,15 +43,29 @@ import net.minecraft.world.lighting.WorldLightManager; import net.minecraft.world.server.ServerWorld; import net.minecraft.world.storage.IWorldInfo; + +/** + * This is used when generating features. + * This allows us to keep each LodChunk generation independent + * of the actual ServerWorld, allowing us + * to multithread generation. + * + * @author James Seibel + * @version 6-23-2021 + */ public class LodServerWorld implements ISeedReader { public HashMap heightmaps = new HashMap<>(); public IChunk chunk; + private Random rand; + private ServerWorld serverWorld; - public LodServerWorld(IChunk newChunk) + public LodServerWorld(IChunk newChunk, ServerWorld newServerWorld) { chunk = newChunk; + rand = newServerWorld.rand; + serverWorld = newServerWorld; } @@ -58,6 +73,7 @@ public class LodServerWorld implements ISeedReader { @Override public int getHeight(Type heightmapType, int x, int z) { + // make sure the block position is set relative to the chunk x = x % LodChunk.WIDTH; x = (x < 0) ? x + 16 : x; @@ -68,216 +84,202 @@ public class LodServerWorld implements ISeedReader { } @Override - public Biome getBiome(BlockPos pos) { + public Biome getBiome(BlockPos pos) + { return chunk.getBiomes().getNoiseBiome(pos.getX(), pos.getY(), pos.getZ()); } @Override - public boolean setBlockState(BlockPos pos, BlockState state, int flags, int recursionLeft) { + public boolean setBlockState(BlockPos pos, BlockState state, int flags, int recursionLeft) + { return chunk.setBlockState(pos, state, false) == state; } @Override - public BlockState getBlockState(BlockPos pos) { + public BlockState getBlockState(BlockPos pos) + { return chunk.getBlockState(pos); } @Override - public FluidState getFluidState(BlockPos pos) { + public FluidState getFluidState(BlockPos pos) + { return chunk.getFluidState(pos); } @Override public int getLightFor(LightType type, BlockPos pos) { + // this needs to be low for snow generation to work return 0; } + @Override + public boolean hasBlockState(BlockPos pos, Predicate state) + { + return state.test(chunk.getBlockState(pos)); + } + + @Override + public ITickList getPendingBlockTicks() + { + return EmptyTickList.get(); + } + + + + + /** + * + * All methods below shouldn't be needed + * and thus have been left unimplemented. + * + */ @Override public ServerWorld getWorld() { - // TODO Auto-generated method stub - return null; - } - - @Override - public ITickList getPendingBlockTicks() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public ITickList getPendingFluidTicks() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public IWorldInfo getWorldInfo() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public DifficultyInstance getDifficultyForLocation(BlockPos pos) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public AbstractChunkProvider getChunkProvider() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public Random getRandom() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public void playSound(PlayerEntity player, BlockPos pos, SoundEvent soundIn, SoundCategory category, float volume, float pitch) { - // TODO Auto-generated method stub - + throw new UnsupportedOperationException("Not Implemented"); } @Override public void addParticle(IParticleData particleData, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { - // TODO Auto-generated method stub - + throw new UnsupportedOperationException("Not Implemented"); } @Override public void playEvent(PlayerEntity player, int type, BlockPos pos, int data) { - // TODO Auto-generated method stub - + throw new UnsupportedOperationException("Not Implemented"); } @Override public DynamicRegistries func_241828_r() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public List getEntitiesInAABBexcluding(Entity entityIn, AxisAlignedBB boundingBox, Predicate predicate) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public List getEntitiesWithinAABB(Class clazz, AxisAlignedBB aabb, Predicate filter) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public List getPlayers() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public IChunk getChunk(int x, int z, ChunkStatus requiredStatus, boolean nonnull) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public int getSkylightSubtracted() { - // TODO Auto-generated method stub - return 0; + throw new UnsupportedOperationException("Not Implemented"); } @Override public BiomeManager getBiomeManager() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public Biome getNoiseBiomeRaw(int x, int y, int z) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public boolean isRemote() { - // TODO Auto-generated method stub - return false; + throw new UnsupportedOperationException("Not Implemented"); } @Override public int getSeaLevel() { - // TODO Auto-generated method stub - return 0; + throw new UnsupportedOperationException("Not Implemented"); } @Override public DimensionType getDimensionType() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public float func_230487_a_(Direction p_230487_1_, boolean p_230487_2_) { - // TODO Auto-generated method stub - return 0; + throw new UnsupportedOperationException("Not Implemented"); } @Override public WorldLightManager getLightManager() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public TileEntity getTileEntity(BlockPos pos) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } @Override public WorldBorder getWorldBorder() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean hasBlockState(BlockPos pos, Predicate state) { - // TODO Auto-generated method stub - return false; + throw new UnsupportedOperationException("Not Implemented"); } @Override public boolean removeBlock(BlockPos pos, boolean isMoving) { - // TODO Auto-generated method stub - return false; + throw new UnsupportedOperationException("Not Implemented"); } @Override public boolean destroyBlock(BlockPos pos, boolean dropBlock, Entity entity, int recursionLeft) { - // TODO Auto-generated method stub - return false; + throw new UnsupportedOperationException("Not Implemented"); } @Override public long getSeed() { - // TODO Auto-generated method stub - return 0; + throw new UnsupportedOperationException("Not Implemented"); } @Override public Stream> func_241827_a(SectionPos p_241827_1_, Structure p_241827_2_) { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException("Not Implemented"); } }