Added ChunkPopulator

This commit is contained in:
Felix Cravic 2020-05-02 23:45:10 +02:00
parent 1aefbca70a
commit e7c26ab45e
6 changed files with 58 additions and 14 deletions

View File

@ -3,9 +3,11 @@ package fr.themode.demo.generator;
import net.minestom.server.instance.Biome;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.ChunkGenerator;
import net.minestom.server.instance.ChunkPopulator;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.instance.block.Block;
import java.util.List;
import java.util.Random;
public class ChunkGeneratorDemo extends ChunkGenerator {
@ -30,4 +32,9 @@ public class ChunkGeneratorDemo extends ChunkGenerator {
public Biome getBiome(int chunkX, int chunkZ) {
return Biome.PLAINS;
}
@Override
public List<ChunkPopulator> getPopulators() {
return null;
}
}

View File

@ -5,35 +5,41 @@ import de.articdive.jnoise.interpolation.InterpolationType;
import net.minestom.server.instance.Biome;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.ChunkGenerator;
import net.minestom.server.instance.ChunkPopulator;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.instance.block.Block;
import java.util.List;
import java.util.Random;
public class NoiseTestGenerator extends ChunkGenerator {
private Random random = new Random();
private JNoise jNoise = JNoise.newBuilder().perlin().setInterpolationType(InterpolationType.LINEAR).setSeed(141414).setFrequency(0.5).build();
@Override
public void generateChunkData(ChunkBatch batch, int chunkX, int chunkZ) {
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
double height = jNoise.getNoise((x + chunkX * 16) / 16.0, (z + chunkZ * 16) /16.0) * 15 + 40;
System.out.println(height);
double height = jNoise.getNoise((x + chunkX * 16) / 16.0, (z + chunkZ * 16) / 16.0) * 15 + 40;
for (int y = 0; y < height; y++) {
if (random.nextInt(100) > 10) {
batch.setCustomBlock(x, y, z, "custom_block");
} else {
batch.setBlock(x, y, z, Block.DIAMOND_BLOCK);
batch.setBlock(x, y, z, Block.DIAMOND_BLOCK);
}
}
}
}
}
@Override
public Biome getBiome(int chunkX, int chunkZ) {
return Biome.PLAINS;
}
@Override
public List<ChunkPopulator> getPopulators() {
return null;
}
}

View File

@ -2,10 +2,14 @@ package net.minestom.server.instance;
import net.minestom.server.instance.batch.ChunkBatch;
import java.util.List;
public abstract class ChunkGenerator {
public abstract void generateChunkData(ChunkBatch batch, int chunkX, int chunkZ);
public abstract Biome getBiome(int chunkX, int chunkZ);
public abstract List<ChunkPopulator> getPopulators();
}

View File

@ -0,0 +1,9 @@
package net.minestom.server.instance;
import net.minestom.server.instance.batch.ChunkBatch;
public interface ChunkPopulator {
void populateChunk(ChunkBatch batch, int chunkX, int chunkZ);
}

View File

@ -7,7 +7,6 @@ import net.minestom.server.entity.Player;
import net.minestom.server.event.PlayerBlockBreakEvent;
import net.minestom.server.instance.batch.BlockBatch;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.network.PacketWriterUtils;
@ -159,11 +158,11 @@ public class InstanceContainer extends Instance {
// Update neighbors
CustomBlock customBlock = getCustomBlock(neighborX, neighborY, neighborZ);
if(customBlock != null) {
if (customBlock != null) {
boolean directNeighbor = false; // only if directly connected to neighbor (no diagonals)
if(offsetX != 0 ^ offsetZ != 0) {
if (offsetX != 0 ^ offsetZ != 0) {
directNeighbor = offsetY == 0;
} else if(offsetX == 0 && offsetZ == 0) {
} else if (offsetX == 0 && offsetZ == 0) {
directNeighbor = true;
}
customBlock.updateFromNeighbor(this, new BlockPosition(neighborX, neighborY, neighborZ), blockPosition, directNeighbor);
@ -316,6 +315,7 @@ public class InstanceContainer extends Instance {
cacheChunk(chunk);
if (chunkGenerator != null) {
ChunkBatch chunkBatch = createChunkBatch(chunk);
chunkBatch.flushChunkGenerator(chunkGenerator, callback);
}
}
@ -398,16 +398,16 @@ public class InstanceContainer extends Instance {
public void scheduleUpdate(int time, TimeUnit unit, BlockPosition position) {
Instance instance = this;
CustomBlock toUpdate = getCustomBlock(position);
if(toUpdate == null) {
if (toUpdate == null) {
return;
}
MinecraftServer.getSchedulerManager().addDelayedTask(new TaskRunnable() {
@Override
public void run() {
CustomBlock currentBlock = instance.getCustomBlock(position);
if(currentBlock == null)
if (currentBlock == null)
return;
if(currentBlock.getCustomBlockId() != toUpdate.getCustomBlockId()) { // block changed
if (currentBlock.getCustomBlockId() != toUpdate.getCustomBlockId()) { // block changed
return;
}
currentBlock.scheduledUpdate(instance, position, getBlockData(position));

View File

@ -3,11 +3,13 @@ package net.minestom.server.instance.batch;
import net.minestom.server.data.Data;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.ChunkGenerator;
import net.minestom.server.instance.ChunkPopulator;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.block.CustomBlock;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
@ -60,8 +62,20 @@ public class ChunkBatch implements InstanceBatch {
public void flushChunkGenerator(ChunkGenerator chunkGenerator, Consumer<Chunk> callback) {
batchesPool.execute(() -> {
List<ChunkPopulator> populators = chunkGenerator.getPopulators();
boolean hasPopulator = populators != null && populators.isEmpty();
chunkGenerator.generateChunkData(this, chunk.getChunkX(), chunk.getChunkZ());
singleThreadFlush(callback);
singleThreadFlush(hasPopulator ? null : callback);
if (populators != null && !populators.isEmpty()) {
Iterator<ChunkPopulator> populatorIterator = populators.iterator();
while (populatorIterator.hasNext()) {
ChunkPopulator chunkPopulator = populatorIterator.next();
chunkPopulator.populateChunk(this, chunk.getChunkX(), chunk.getChunkZ());
}
singleThreadFlush(callback);
}
});
}
@ -71,6 +85,10 @@ public class ChunkBatch implements InstanceBatch {
});
}
public void clearData() {
dataList.clear();
}
private void singleThreadFlush(Consumer<Chunk> callback) {
synchronized (chunk) {
for (BlockData data : dataList) {