It compiles on 1.14, but there's a deadlock

This commit is contained in:
Rutger Kok 2019-04-28 08:01:50 +02:00
parent bfe4400c77
commit d40945c53c
12 changed files with 305 additions and 221 deletions

View File

@ -71,7 +71,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<version>1.14-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -3,18 +3,18 @@ package nl.rutgerkok.worldgeneratorapi.internal;
import java.util.Objects;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_13_R2.generator.NormalChunkGenerator;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import net.minecraft.server.v1_13_R2.ChunkGenerator;
import net.minecraft.server.v1_13_R2.ChunkGeneratorAbstract;
import net.minecraft.server.v1_13_R2.ChunkProviderDebug;
import net.minecraft.server.v1_13_R2.ChunkProviderFlat;
import net.minecraft.server.v1_13_R2.ChunkProviderGenerate;
import net.minecraft.server.v1_13_R2.ChunkProviderHell;
import net.minecraft.server.v1_13_R2.ChunkProviderTheEnd;
import net.minecraft.server.v1_13_R2.SeededRandom;
import net.minecraft.server.v1_13_R2.WorldServer;
import net.minecraft.server.v1_14_R1.ChunkGenerator;
import net.minecraft.server.v1_14_R1.ChunkGeneratorAbstract;
import net.minecraft.server.v1_14_R1.ChunkProviderDebug;
import net.minecraft.server.v1_14_R1.ChunkProviderFlat;
import net.minecraft.server.v1_14_R1.ChunkProviderGenerate;
import net.minecraft.server.v1_14_R1.ChunkProviderHell;
import net.minecraft.server.v1_14_R1.ChunkProviderTheEnd;
import net.minecraft.server.v1_14_R1.GeneratorAccess;
import net.minecraft.server.v1_14_R1.SeededRandom;
import net.minecraft.server.v1_14_R1.WorldServer;
import nl.rutgerkok.worldgeneratorapi.BaseChunkGenerator;
import nl.rutgerkok.worldgeneratorapi.internal.bukkitoverrides.ChunkDataImpl;
import nl.rutgerkok.worldgeneratorapi.internal.bukkitoverrides.InjectedChunkGenerator;
@ -38,20 +38,11 @@ final class BaseChunkGeneratorImpl implements BaseChunkGenerator {
static BaseChunkGenerator fromMinecraft(World world) {
WorldServer worldServer = ((CraftWorld) world).getHandle();
ChunkGenerator<?> chunkGenerator = worldServer.getChunkProvider().getChunkGenerator();
if (chunkGenerator instanceof NormalChunkGenerator<?>) {
try {
chunkGenerator = (ChunkGenerator<?>) ReflectionUtil
.getFieldOfType(chunkGenerator, ChunkGenerator.class)
.get(chunkGenerator);
} catch (IllegalAccessException e) {
throw new RuntimeException("Error getting chunkGenerator from NormalChunkGenerator", e);
}
}
if (chunkGenerator instanceof InjectedChunkGenerator) {
return ((InjectedChunkGenerator) chunkGenerator).getBaseChunkGenerator();
}
if (isSupported(chunkGenerator)) {
return new BaseChunkGeneratorImpl(chunkGenerator);
return new BaseChunkGeneratorImpl(worldServer, chunkGenerator);
}
throw new UnsupportedOperationException(
@ -71,11 +62,13 @@ final class BaseChunkGeneratorImpl implements BaseChunkGenerator {
}
private final ChunkGenerator<?> internal;
private final GeneratorAccess world;
private BaseChunkGeneratorImpl(ChunkGenerator<?> chunkGenerator) {
private BaseChunkGeneratorImpl(GeneratorAccess world, ChunkGenerator<?> chunkGenerator) {
if (chunkGenerator instanceof InjectedChunkGenerator) {
throw new IllegalArgumentException("Double-wrapping");
}
this.world = Objects.requireNonNull(world, "world");
this.internal = Objects.requireNonNull(chunkGenerator, "internal");
}
@ -87,13 +80,13 @@ final class BaseChunkGeneratorImpl implements BaseChunkGenerator {
// Make sure this matches isSupported above
if (internal instanceof ChunkProviderGenerate) {
((ChunkProviderGenerate) internal).a(chunk.getChunkX(), chunk.getChunkZ(), blocks.getHandle());
((ChunkProviderGenerate) internal).buildNoise(world, blocks.getHandle());
} else if (internal instanceof ChunkProviderFlat) {
((ChunkProviderFlat) internal).a(chunk.getChunkX(), chunk.getChunkZ(), blocks.getHandle());
((ChunkProviderFlat) internal).buildNoise(world, blocks.getHandle());
} else if (internal instanceof ChunkProviderHell) {
((ChunkProviderHell) internal).a(chunk.getChunkX(), chunk.getChunkZ(), blocks.getHandle());
((ChunkProviderHell) internal).buildNoise(world, blocks.getHandle());
} else if (internal instanceof ChunkProviderTheEnd) {
((ChunkProviderTheEnd) internal).a(chunk.getChunkX(), chunk.getChunkZ(), blocks.getHandle());
((ChunkProviderTheEnd) internal).buildNoise(world, blocks.getHandle());
} else if (internal instanceof ChunkProviderDebug) {
// Generate nothing - there is no base terrain
} else {

View File

@ -3,10 +3,10 @@ package nl.rutgerkok.worldgeneratorapi.internal;
import java.util.Objects;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlock;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
import net.minecraft.server.v1_13_R2.BiomeBase;
import net.minecraft.server.v1_13_R2.WorldChunkManager;
import net.minecraft.server.v1_14_R1.BiomeBase;
import net.minecraft.server.v1_14_R1.WorldChunkManager;
import nl.rutgerkok.worldgeneratorapi.BiomeGenerator;
public final class BiomeGeneratorImpl implements BiomeGenerator {
@ -30,7 +30,8 @@ public final class BiomeGeneratorImpl implements BiomeGenerator {
@Override
public Biome[] getZoomedOutBiomes(int minX, int minZ, int xSize, int zSize) {
BiomeBase[] biomeArray = internal.getBiomes(minX, minZ, xSize, zSize);
// Last parameter doesn't seem to be used anywhere V
BiomeBase[] biomeArray = internal.a(minX, minZ, xSize, zSize, false);
Biome[] biomes = new Biome[xSize * zSize];
for (int i = 0; i < xSize * zSize; i++) {

View File

@ -6,58 +6,72 @@ import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBanner;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBeacon;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlock;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlockEntityState;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBrewingStand;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftChest;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftCommandBlock;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftComparator;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftCreatureSpawner;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftDaylightDetector;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftDispenser;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftDropper;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftEnchantingTable;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftEndGateway;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftEnderChest;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftFurnace;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftHopper;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftJukebox;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftShulkerBox;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftSign;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftSkull;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftStructureBlock;
import org.bukkit.craftbukkit.v1_13_R2.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBanner;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBarrel;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBeacon;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBell;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlastFurnace;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlockEntityState;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlockState;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBrewingStand;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftCampfire;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftChest;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftCommandBlock;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftComparator;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftCreatureSpawner;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftDaylightDetector;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftDispenser;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftDropper;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftEnchantingTable;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftEndGateway;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftEnderChest;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftFurnace;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftHopper;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftJigsaw;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftJukebox;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftLectern;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftShulkerBox;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftSign;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftSkull;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftSmoker;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftStructureBlock;
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
import net.minecraft.server.v1_13_R2.BlockPosition;
import net.minecraft.server.v1_13_R2.IBlockData;
import net.minecraft.server.v1_13_R2.IChunkAccess;
import net.minecraft.server.v1_13_R2.NBTTagCompound;
import net.minecraft.server.v1_13_R2.RegionLimitedWorldAccess;
import net.minecraft.server.v1_13_R2.TileEntity;
import net.minecraft.server.v1_13_R2.TileEntityBanner;
import net.minecraft.server.v1_13_R2.TileEntityBeacon;
import net.minecraft.server.v1_13_R2.TileEntityBrewingStand;
import net.minecraft.server.v1_13_R2.TileEntityChest;
import net.minecraft.server.v1_13_R2.TileEntityCommand;
import net.minecraft.server.v1_13_R2.TileEntityComparator;
import net.minecraft.server.v1_13_R2.TileEntityDispenser;
import net.minecraft.server.v1_13_R2.TileEntityDropper;
import net.minecraft.server.v1_13_R2.TileEntityEnchantTable;
import net.minecraft.server.v1_13_R2.TileEntityEndGateway;
import net.minecraft.server.v1_13_R2.TileEntityEnderChest;
import net.minecraft.server.v1_13_R2.TileEntityFurnace;
import net.minecraft.server.v1_13_R2.TileEntityHopper;
import net.minecraft.server.v1_13_R2.TileEntityJukeBox;
import net.minecraft.server.v1_13_R2.TileEntityLightDetector;
import net.minecraft.server.v1_13_R2.TileEntityMobSpawner;
import net.minecraft.server.v1_13_R2.TileEntityShulkerBox;
import net.minecraft.server.v1_13_R2.TileEntitySign;
import net.minecraft.server.v1_13_R2.TileEntitySkull;
import net.minecraft.server.v1_13_R2.TileEntityStructure;
import net.minecraft.server.v1_13_R2.BlockPosition.MutableBlockPosition;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.BlockPosition.MutableBlockPosition;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.IChunkAccess;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.RegionLimitedWorldAccess;
import net.minecraft.server.v1_14_R1.TileEntity;
import net.minecraft.server.v1_14_R1.TileEntityBanner;
import net.minecraft.server.v1_14_R1.TileEntityBarrel;
import net.minecraft.server.v1_14_R1.TileEntityBeacon;
import net.minecraft.server.v1_14_R1.TileEntityBell;
import net.minecraft.server.v1_14_R1.TileEntityBlastFurnace;
import net.minecraft.server.v1_14_R1.TileEntityBrewingStand;
import net.minecraft.server.v1_14_R1.TileEntityCampfire;
import net.minecraft.server.v1_14_R1.TileEntityChest;
import net.minecraft.server.v1_14_R1.TileEntityCommand;
import net.minecraft.server.v1_14_R1.TileEntityComparator;
import net.minecraft.server.v1_14_R1.TileEntityDispenser;
import net.minecraft.server.v1_14_R1.TileEntityDropper;
import net.minecraft.server.v1_14_R1.TileEntityEnchantTable;
import net.minecraft.server.v1_14_R1.TileEntityEndGateway;
import net.minecraft.server.v1_14_R1.TileEntityEnderChest;
import net.minecraft.server.v1_14_R1.TileEntityFurnace;
import net.minecraft.server.v1_14_R1.TileEntityHopper;
import net.minecraft.server.v1_14_R1.TileEntityJigsaw;
import net.minecraft.server.v1_14_R1.TileEntityJukeBox;
import net.minecraft.server.v1_14_R1.TileEntityLectern;
import net.minecraft.server.v1_14_R1.TileEntityLightDetector;
import net.minecraft.server.v1_14_R1.TileEntityMobSpawner;
import net.minecraft.server.v1_14_R1.TileEntityShulkerBox;
import net.minecraft.server.v1_14_R1.TileEntitySign;
import net.minecraft.server.v1_14_R1.TileEntitySkull;
import net.minecraft.server.v1_14_R1.TileEntitySmoker;
import net.minecraft.server.v1_14_R1.TileEntityStructure;
import nl.rutgerkok.worldgeneratorapi.decoration.DecorationArea;
class DecorationAreaImpl implements DecorationArea {
@ -98,17 +112,27 @@ class DecorationAreaImpl implements DecorationArea {
Material material = CraftBlockData.fromData(internal.getType(position)).getMaterial();
// This code is based on the following: (this code is similar, in that it
// creates tile entities that have not been added to a world)
// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java?at=421c1728c81e2f729dff88da2ac96535d2b8e5e8#227
// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java?at=a2d787f6ebeb72fa7d5750788221fb9a0d838ac4#290
// If new tile entities are added, don't forget to add them here
switch (material) {
case SIGN:
case WALL_SIGN:
case ACACIA_SIGN:
case ACACIA_WALL_SIGN:
case BIRCH_SIGN:
case BIRCH_WALL_SIGN:
case DARK_OAK_SIGN:
case DARK_OAK_WALL_SIGN:
case JUNGLE_SIGN:
case JUNGLE_WALL_SIGN:
case OAK_SIGN:
case OAK_WALL_SIGN:
case SPRUCE_SIGN:
case SPRUCE_WALL_SIGN:
return new CraftSign(material, (TileEntitySign) tileEntity);
case CHEST:
case TRAPPED_CHEST:
return new CraftChest(material, (TileEntityChest) tileEntity);
case FURNACE:
return new CraftFurnace(material, (TileEntityFurnace) tileEntity);
return new CraftFurnace<>(material, (TileEntityFurnace) tileEntity);
case DISPENSER:
return new CraftDispenser(material, (TileEntityDispenser) tileEntity);
case DROPPER:
@ -203,6 +227,21 @@ class DecorationAreaImpl implements DecorationArea {
return new CraftDaylightDetector(material, (TileEntityLightDetector) tileEntity);
case COMPARATOR:
return new CraftComparator(material, (TileEntityComparator) tileEntity);
case BARREL:
return new CraftBarrel(material, (TileEntityBarrel) tileEntity);
case BELL:
return new CraftBell(material, (TileEntityBell) tileEntity);
case BLAST_FURNACE:
return new CraftBlastFurnace(material, (TileEntityBlastFurnace) tileEntity);
case CAMPFIRE:
return new CraftCampfire(material, (TileEntityCampfire) tileEntity);
case JIGSAW:
return new CraftJigsaw(material, (TileEntityJigsaw) tileEntity);
case LECTERN:
return new CraftLectern(material, (TileEntityLectern) tileEntity);
case SMOKER:
return new CraftSmoker(material, (TileEntitySmoker) tileEntity);
default:
return new CraftBlockState(material);
}
@ -240,10 +279,10 @@ class DecorationAreaImpl implements DecorationArea {
// Update TileEntity data
if (blockState instanceof CraftBlockEntityState) {
IChunkAccess chunk = internal.y(position);
IChunkAccess chunk = internal.x(position);
NBTTagCompound tag = ((CraftBlockEntityState<?>) blockState).getSnapshotNBT();
TileEntity tileEntity = TileEntity.create(tag);
chunk.a(position, tileEntity);
chunk.setTileEntity(position, tileEntity);
}
}

View File

@ -12,11 +12,11 @@ import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlock;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
import net.minecraft.server.v1_13_R2.BiomeBase;
import net.minecraft.server.v1_13_R2.Biomes;
import net.minecraft.server.v1_14_R1.BiomeBase;
import net.minecraft.server.v1_14_R1.Biomes;
import nl.rutgerkok.worldgeneratorapi.WorldGeneratorApi;
import nl.rutgerkok.worldgeneratorapi.WorldRef;
import nl.rutgerkok.worldgeneratorapi.property.FloatProperty;
@ -57,11 +57,11 @@ public final class PropertyRegistryImpl implements PropertyRegistry {
public PropertyRegistryImpl() {
addMinecraftBiomeFloatProperty(TEMPERATURE, BiomeBase::getTemperature);
addMinecraftBiomeFloatProperty(WETNESS, BiomeBase::getHumidity);
addMinecraftBiomeFloatProperty(BASE_HEIGHT, BiomeBase::h);
addMinecraftBiomeFloatProperty(HEIGHT_VARIATION, BiomeBase::l);
addMinecraftBiomeFloatProperty(BASE_HEIGHT, BiomeBase::g);
addMinecraftBiomeFloatProperty(HEIGHT_VARIATION, BiomeBase::k);
addMinecraftWorldProperty(WORLD_SEED, world -> (Long) world.getSeed(), -1L);
addMinecraftWorldFloatProperty(SEA_LEVEL, world -> (float) world.getSeaLevel(), (world, level) -> {
((CraftWorld) world).getHandle().b(level.intValue());
((CraftWorld) world).getHandle().c(level.intValue());
if (world.getSeaLevel() != level.intValue()) {
throw new UnsupportedOperationException("Failed to set sea level to " + level.intValue());
}

View File

@ -1,7 +1,6 @@
package nl.rutgerkok.worldgeneratorapi.internal;
import java.util.BitSet;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
@ -12,15 +11,15 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import net.minecraft.server.v1_13_R2.BiomeBase;
import net.minecraft.server.v1_13_R2.BlockFalling;
import net.minecraft.server.v1_13_R2.BlockPosition;
import net.minecraft.server.v1_13_R2.ChunkGenerator;
import net.minecraft.server.v1_13_R2.RegionLimitedWorldAccess;
import net.minecraft.server.v1_13_R2.SeededRandom;
import net.minecraft.server.v1_13_R2.WorldGenCarverWrapper;
import net.minecraft.server.v1_13_R2.WorldGenFeatureConfiguration;
import net.minecraft.server.v1_13_R2.WorldGenStage;
import net.minecraft.server.v1_14_R1.BiomeBase;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_14_R1.ChunkGenerator;
import net.minecraft.server.v1_14_R1.IChunkAccess;
import net.minecraft.server.v1_14_R1.RegionLimitedWorldAccess;
import net.minecraft.server.v1_14_R1.SeededRandom;
import net.minecraft.server.v1_14_R1.WorldGenCarverWrapper;
import net.minecraft.server.v1_14_R1.WorldGenStage;
import nl.rutgerkok.worldgeneratorapi.BaseChunkGenerator;
import nl.rutgerkok.worldgeneratorapi.BaseChunkGenerator.GeneratingChunk;
import nl.rutgerkok.worldgeneratorapi.decoration.BaseDecorationType;
@ -52,19 +51,23 @@ public final class WorldDecoratorImpl implements WorldDecorator {
private final Map<BaseDecorationType, List<BaseChunkGenerator>> customBaseDecorations = new ConcurrentHashMap<>();
private final Set<BaseDecorationType> disabledBaseDecorations = EnumSet.noneOf(BaseDecorationType.class);
private BiomeBase getCarvingBiome(IChunkAccess ichunkaccess) {
return ichunkaccess.getBiome(BlockPosition.ZERO);
}
@Override
public List<BaseChunkGenerator> getCustomBaseDecorations(BaseDecorationType type) {
Objects.requireNonNull(type, "type");
return customBaseDecorations.computeIfAbsent(type, t -> new CopyOnWriteArrayList<>());
}
@Override
public List<Decoration> getCustomDecorations(DecorationType type) {
Objects.requireNonNull(type, "type");
return customDecorations.computeIfAbsent(type, t -> new CopyOnWriteArrayList<>());
}
public boolean isDefaultEnabled(BaseDecorationType type) {
return !this.disabledBaseDecorations.contains(type);
}
@ -89,29 +92,27 @@ public final class WorldDecoratorImpl implements WorldDecorator {
}
}
@SuppressWarnings("deprecation")
public void spawnCarvers(RegionLimitedWorldAccess world, WorldGenStage.Features stage, SeededRandom seededrandom) {
public void spawnCarvers(IChunkAccess ichunkaccess, WorldGenStage.Features stage, int seaLevel, long seed) {
SeededRandom seededrandom = new SeededRandom(seed);
DecorationType decorationType = CARVER_TRANSLATION.get(stage);
if (!this.disabledDecorations.contains(decorationType)) {
// Spawn default carvers (code based on ChunkGeneratorAbstract.addFeatures)
int chunkX = world.a();
int chunkZ = world.b();
BitSet bitset = world.getChunkAt(chunkX, chunkZ).a(stage);
for (int lookingChunkX = chunkX - 8; lookingChunkX <= chunkX + 8; ++lookingChunkX) {
for (int lookingChunkZ = chunkZ - 8; lookingChunkZ <= chunkZ + 8; ++lookingChunkZ) {
BiomeBase biome = world.getChunkProvider().getChunkGenerator()
.getWorldChunkManager()
.getBiome(new BlockPosition(lookingChunkX * 16, 0, lookingChunkZ * 16), null);
List<WorldGenCarverWrapper<?>> list = biome == null ? Collections.emptyList() : biome.a(stage);
// Spawn default carvers (code based on ChunkGenerator.doCarving)
ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
int i = chunkcoordintpair.x;
int j = chunkcoordintpair.z;
BitSet bitset = ichunkaccess.a(stage);
for (int k = i - 8; k <= i + 8; ++k) {
for (int l = j - 8; l <= j + 8; ++l) {
List<WorldGenCarverWrapper<?>> list = this.getCarvingBiome(ichunkaccess).a(stage);
ListIterator<WorldGenCarverWrapper<?>> listiterator = list.listIterator();
while (listiterator.hasNext()) {
int i2 = listiterator.nextIndex();
int i1 = listiterator.nextIndex();
WorldGenCarverWrapper<?> worldgencarverwrapper = listiterator.next();
seededrandom.c(world.getMinecraftWorld().getSeed() + i2, lookingChunkX, lookingChunkZ);
if (worldgencarverwrapper.a(world, seededrandom, lookingChunkX, lookingChunkZ,
WorldGenFeatureConfiguration.e)) {
worldgencarverwrapper.a(world, seededrandom, lookingChunkX, lookingChunkZ, chunkX, chunkZ,
bitset, WorldGenFeatureConfiguration.e);
seededrandom.c(seed + i1, k, l);
if (worldgencarverwrapper.a(seededrandom, k, l)) {
worldgencarverwrapper.a(ichunkaccess, seededrandom, seaLevel, k, l, i, j, bitset);
}
}
}
@ -119,14 +120,7 @@ public final class WorldDecoratorImpl implements WorldDecorator {
}
// Spawn custom carvers
List<Decoration> decorations = this.customDecorations.get(decorationType);
if (decorations == null) {
return;
}
DecorationArea decorationArea = new DecorationAreaImpl(world);
for (Decoration decoration : decorations) {
decoration.decorate(decorationArea, seededrandom);
}
// TODO re-enable now that it operates
}
public void spawnCustomBaseDecorations(BaseDecorationType type, GeneratingChunk chunk) {
@ -142,7 +136,6 @@ public final class WorldDecoratorImpl implements WorldDecorator {
}
public void spawnDecorations(ChunkGenerator<?> chunkGenerator, RegionLimitedWorldAccess populationArea) {
BlockFalling.instaFall = true;
int i = populationArea.a();
int j = populationArea.b();
int k = i * 16;
@ -175,7 +168,6 @@ public final class WorldDecoratorImpl implements WorldDecorator {
decorationIndex++;
}
}
BlockFalling.instaFall = false;
}
}

View File

@ -6,13 +6,12 @@ import java.util.Objects;
import javax.annotation.Nullable;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import net.minecraft.server.v1_13_R2.ChunkGenerator;
import net.minecraft.server.v1_13_R2.ChunkProviderServer;
import net.minecraft.server.v1_13_R2.ChunkTaskScheduler;
import net.minecraft.server.v1_13_R2.WorldChunkManager;
import net.minecraft.server.v1_13_R2.WorldServer;
import net.minecraft.server.v1_14_R1.ChunkGenerator;
import net.minecraft.server.v1_14_R1.ChunkProviderServer;
import net.minecraft.server.v1_14_R1.WorldChunkManager;
import net.minecraft.server.v1_14_R1.WorldServer;
import nl.rutgerkok.worldgeneratorapi.BaseChunkGenerator;
import nl.rutgerkok.worldgeneratorapi.BiomeGenerator;
import nl.rutgerkok.worldgeneratorapi.WorldGenerator;
@ -75,6 +74,13 @@ final class WorldGeneratorImpl implements WorldGenerator {
return worldRef;
}
private Class<?> nmsClass(String simpleName) throws ClassNotFoundException {
// Returns a class in the net.mineraft.server package
Class<?> exampleNmsClass = ChunkGenerator.class;
String name = exampleNmsClass.getName().replace(exampleNmsClass.getSimpleName(), simpleName);
return Class.forName(name);
}
/**
* Injects {@link InjectedChunkGenerator} into the world, so that we can
* customize how blocks are generated.
@ -91,10 +97,15 @@ final class WorldGeneratorImpl implements WorldGenerator {
Field chunkGeneratorField = ReflectionUtil.getFieldOfType(chunkProvider, ChunkGenerator.class);
chunkGeneratorField.set(chunkProvider, injected);
Field chunkTaskSchedulerField = ReflectionUtil.getFieldOfType(chunkProvider, ChunkTaskScheduler.class);
ChunkTaskScheduler scheduler = (ChunkTaskScheduler) chunkTaskSchedulerField.get(chunkProvider);
chunkGeneratorField = ReflectionUtil.getFieldOfType(scheduler, ChunkGenerator.class);
chunkGeneratorField.set(scheduler, injected);
try {
Field chunkTaskSchedulerField = ReflectionUtil.getFieldOfType(chunkProvider,
nmsClass("ChunkTaskScheduler"));
Object scheduler = chunkTaskSchedulerField.get(chunkProvider);
chunkGeneratorField = ReflectionUtil.getFieldOfType(scheduler, ChunkGenerator.class);
chunkGeneratorField.set(scheduler, injected);
} catch (ClassNotFoundException e) {
// Ignore, we're not on Paper but on Spigot
}
this.injected = injected;
} catch (ReflectiveOperationException e) {

View File

@ -1,10 +1,10 @@
package nl.rutgerkok.worldgeneratorapi.internal.bukkitoverrides;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlock;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import net.minecraft.server.v1_13_R2.BiomeBase;
import net.minecraft.server.v1_14_R1.BiomeBase;
public final class BiomeGridImpl implements BiomeGrid {
private final BiomeBase[] biomeArray;

View File

@ -2,22 +2,29 @@ package nl.rutgerkok.worldgeneratorapi.internal.bukkitoverrides;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_13_R2.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
import org.bukkit.generator.ChunkGenerator.ChunkData;
import net.minecraft.server.v1_13_R2.BlockPosition.MutableBlockPosition;
import net.minecraft.server.v1_13_R2.IBlockData;
import net.minecraft.server.v1_13_R2.IChunkAccess;
import net.minecraft.server.v1_14_R1.BlockPosition.MutableBlockPosition;
import net.minecraft.server.v1_14_R1.HeightMap;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.IChunkAccess;
import net.minecraft.server.v1_14_R1.ProtoChunk;
public final class ChunkDataImpl implements ChunkData {
private final IChunkAccess internal;
private final ProtoChunk internal;
private final HeightMap heightmap;
private final HeightMap heightmap1;
private final int xOffset;
private final int zOffset;
private final MutableBlockPosition reusableBlockPos = new MutableBlockPosition();
ChunkDataImpl(IChunkAccess internal) {
ChunkDataImpl(ProtoChunk internal) {
this.internal = internal;
this.heightmap = internal.b(HeightMap.Type.OCEAN_FLOOR_WG);
this.heightmap1 = internal.b(HeightMap.Type.WORLD_SURFACE_WG);
this.xOffset = internal.getPos().x * 16;
this.zOffset = internal.getPos().z * 16;
}
@ -60,6 +67,8 @@ public final class ChunkDataImpl implements ChunkData {
}
private void setBlock(int x, int y, int z, IBlockData blockData) {
heightmap.a(x, y, z, blockData);
heightmap1.a(x, y, z, blockData);
reusableBlockPos.c(xOffset + x, y, zOffset + z);
internal.setType(reusableBlockPos, blockData, false);
}

View File

@ -6,26 +6,27 @@ import java.util.Objects;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.generator.ChunkGenerator.ChunkData;
import net.minecraft.server.v1_13_R2.BiomeBase;
import net.minecraft.server.v1_13_R2.BiomeBase.BiomeMeta;
import net.minecraft.server.v1_13_R2.BlockPosition;
import net.minecraft.server.v1_13_R2.ChunkCoordIntPair;
import net.minecraft.server.v1_13_R2.ChunkGeneratorAbstract;
import net.minecraft.server.v1_13_R2.ChunkStatus;
import net.minecraft.server.v1_13_R2.EnumCreatureType;
import net.minecraft.server.v1_13_R2.GeneratorSettingsDefault;
import net.minecraft.server.v1_13_R2.HeightMap;
import net.minecraft.server.v1_13_R2.IChunkAccess;
import net.minecraft.server.v1_13_R2.MobSpawnerPhantom;
import net.minecraft.server.v1_13_R2.NoiseGenerator3;
import net.minecraft.server.v1_13_R2.RegionLimitedWorldAccess;
import net.minecraft.server.v1_13_R2.SeededRandom;
import net.minecraft.server.v1_13_R2.SpawnerCreature;
import net.minecraft.server.v1_13_R2.World;
import net.minecraft.server.v1_13_R2.WorldGenFeatureSwampHut;
import net.minecraft.server.v1_13_R2.WorldGenStage;
import net.minecraft.server.v1_13_R2.WorldGenerator;
import net.minecraft.server.v1_13_R2.WorldServer;
import net.minecraft.server.v1_14_R1.BiomeBase;
import net.minecraft.server.v1_14_R1.BiomeBase.BiomeMeta;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_14_R1.ChunkGeneratorAbstract;
import net.minecraft.server.v1_14_R1.EnumCreatureType;
import net.minecraft.server.v1_14_R1.GeneratorAccess;
import net.minecraft.server.v1_14_R1.GeneratorSettingsDefault;
import net.minecraft.server.v1_14_R1.HeightMap.Type;
import net.minecraft.server.v1_14_R1.IChunkAccess;
import net.minecraft.server.v1_14_R1.MobSpawnerCat;
import net.minecraft.server.v1_14_R1.MobSpawnerPatrol;
import net.minecraft.server.v1_14_R1.MobSpawnerPhantom;
import net.minecraft.server.v1_14_R1.NoiseGenerator3;
import net.minecraft.server.v1_14_R1.ProtoChunk;
import net.minecraft.server.v1_14_R1.RegionLimitedWorldAccess;
import net.minecraft.server.v1_14_R1.SeededRandom;
import net.minecraft.server.v1_14_R1.SpawnerCreature;
import net.minecraft.server.v1_14_R1.WorldGenStage;
import net.minecraft.server.v1_14_R1.WorldGenerator;
import net.minecraft.server.v1_14_R1.WorldServer;
import nl.rutgerkok.worldgeneratorapi.BaseChunkGenerator;
import nl.rutgerkok.worldgeneratorapi.BaseChunkGenerator.GeneratingChunk;
import nl.rutgerkok.worldgeneratorapi.BiomeGenerator;
@ -43,7 +44,7 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
private final BiomeGenerator biomeGenerator;
private final BiomeGridImpl biomeGrid;
GeneratingChunkImpl(IChunkAccess internal, BiomeGenerator biomeGenerator) {
GeneratingChunkImpl(ProtoChunk internal, BiomeGenerator biomeGenerator) {
this.chunkX = internal.getPos().x;
this.chunkZ = internal.getPos().z;
this.blocks = new ChunkDataImpl(internal);
@ -81,22 +82,24 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
private final org.bukkit.World world;
/**
* Could someone ask Mojang why world generation controls Phantom spawning?
* Could someone ask Mojang why world generation controls these mobs?
*/
private final MobSpawnerPhantom phantomSpawner = new MobSpawnerPhantom();
private final GeneratorSettingsDefault defaultSettings = new GeneratorSettingsDefault();
private final NoiseGenerator3 surfaceNoise;
private final MobSpawnerPatrol patrolSpawner = new MobSpawnerPatrol();
private final MobSpawnerCat catSpawner = new MobSpawnerCat();
private final NoiseGenerator3 surfaceNoise;
public final WorldDecoratorImpl worldDecorator = new WorldDecoratorImpl();
private BaseChunkGenerator baseChunkGenerator;
private final BiomeGenerator biomeGenerator;
public InjectedChunkGenerator(WorldServer world, BaseChunkGenerator baseChunkGenerator) {
super(world, world.getChunkProvider().getChunkGenerator().getWorldChunkManager());
super(world, world.getChunkProvider().getChunkGenerator().getWorldChunkManager(),
4, 8, 256, world.getChunkProvider().getChunkGenerator().getSettings(), true);
this.world = world.getWorld();
SeededRandom seededrandom = new SeededRandom(this.b);
SeededRandom seededrandom = new SeededRandom(this.seed);
surfaceNoise = new NoiseGenerator3(seededrandom, 4);
this.biomeGenerator = new BiomeGeneratorImpl(world.getChunkProvider()
@ -105,15 +108,30 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
}
@Override
public double[] a(int i, int j) {
return this.surfaceNoise.a(i << 4, j << 4, 16, 16, 0.0625, 0.0625, 1.0);
protected double a(double d0, double d1, int i) {
// No idea what this is calculating - we only know that it has got something to
// do with terrain shape
double d3 = (i - (8.5D + d0 * 8.5D / 8.0D * 4.0D)) * 12.0D * 128.0D / 256.0D / d1;
if (d3 < 0.0D) {
d3 *= 4.0D;
}
return d3;
}
@Override
protected void a(double[] adouble, int i, int j) {
// No idea what this is calculating - but it has got something to do with
// terrain shape
this.a(adouble, i, j, 684.4119873046875D, 684.4119873046875D, 8.555149841308594D, 4.277574920654297D, 3, -10);
}
@Override
public int a(World world, boolean flag, boolean flag1) {
final byte b0 = 0;
final int i = b0 + this.phantomSpawner.a(world, flag, flag1);
return i;
protected double[] a(int i, int j) {
// No idea what this is calculating - but it has got something to do with
// terrain shape
throw new UnsupportedOperationException("Not supported, sorry!");
}
@Override
@ -121,11 +139,6 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
this.worldDecorator.spawnDecorations(this, populationArea);
}
@Override
public void addFeatures(RegionLimitedWorldAccess world, WorldGenStage.Features stage) {
this.worldDecorator.spawnCarvers(world, stage, new SeededRandom(this.b));
}
@Override
public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) {
final int i = regionlimitedworldaccess.a();
@ -137,29 +150,30 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
}
@Override
public void createChunk(IChunkAccess ichunkaccess) {
public void buildBase(IChunkAccess ichunkaccess) {
ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
int i = chunkcoordintpair.x;
int j = chunkcoordintpair.z;
int k = chunkcoordintpair.x;
int l = chunkcoordintpair.z;
SeededRandom seededrandom = new SeededRandom();
seededrandom.a(i, j);
// Generate zoomed-in biomes
ichunkaccess.a(this.c.getBiomeBlock(i * 16, j * 16, 16, 16));
// Generate blocks
GeneratingChunkImpl chunk = new GeneratingChunkImpl(ichunkaccess, biomeGenerator);
baseChunkGenerator.setBlocksInChunk(chunk);
seededrandom.a(k, l);
// Generate early decorations
GeneratingChunkImpl chunk = new GeneratingChunkImpl((ProtoChunk) ichunkaccess, biomeGenerator);
this.worldDecorator.spawnCustomBaseDecorations(BaseDecorationType.RAW_GENERATION, chunk);
// Heightmap calculations
ichunkaccess.a(HeightMap.Type.WORLD_SURFACE_WG, HeightMap.Type.OCEAN_FLOOR_WG);
// Generate surface
if (this.worldDecorator.isDefaultEnabled(BaseDecorationType.SURFACE)) {
this.a(ichunkaccess, ichunkaccess.getBiomeIndex(), seededrandom, world.getSeaLevel());
BiomeBase[] abiomebase = ichunkaccess.getBiomeIndex();
for (int i1 = 0; i1 < 16; ++i1) {
for (int j1 = 0; j1 < 16; ++j1) {
int k1 = k + i1;
int l1 = l + j1;
int i2 = ichunkaccess.a(Type.WORLD_SURFACE_WG, i1, j1) + 1;
double d1 = this.surfaceNoise.a(k1 * 0.0625D, l1 * 0.0625D, 0.0625D, i1 * 0.0625D);
abiomebase[j1 * 16 + i1].a(seededrandom, ichunkaccess, k1, l1, i2, d1, this.getSettings().r(),
this.getSettings().s(), this.getSeaLevel(), this.a.getSeed());
}
}
}
this.worldDecorator.spawnCustomBaseDecorations(BaseDecorationType.SURFACE, chunk);
@ -168,9 +182,25 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
this.a(ichunkaccess, seededrandom);
}
this.worldDecorator.spawnCustomBaseDecorations(BaseDecorationType.BEDROCK, chunk);
}
ichunkaccess.a(HeightMap.Type.WORLD_SURFACE_WG, HeightMap.Type.OCEAN_FLOOR_WG);
ichunkaccess.a(ChunkStatus.BASE);
@Override
public void buildNoise(GeneratorAccess generatoraccess, IChunkAccess ichunkaccess) {
// Generate blocks
GeneratingChunkImpl chunk = new GeneratingChunkImpl((ProtoChunk) ichunkaccess, biomeGenerator);
baseChunkGenerator.setBlocksInChunk(chunk);
}
@Override
public void doCarving(IChunkAccess world, WorldGenStage.Features stage) {
this.worldDecorator.spawnCarvers(world, stage, this.getSeaLevel(), this.seed);
}
@Override
public void doMobSpawning(WorldServer worldserver, boolean flag, boolean flag1) {
this.phantomSpawner.a(worldserver, flag, flag1);
this.patrolSpawner.a(worldserver, flag, flag1);
this.catSpawner.a(worldserver, flag, flag1);
}
public BaseChunkGenerator getBaseChunkGenerator() {
@ -183,19 +213,30 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
@Override
public List<BiomeMeta> getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) {
final BiomeBase biomebase = this.a.getBiome(blockposition);
return (enumcreaturetype == EnumCreatureType.MONSTER
&& ((WorldGenFeatureSwampHut) WorldGenerator.l).d(this.a, blockposition))
? WorldGenerator.l.d()
: ((enumcreaturetype == EnumCreatureType.MONSTER && WorldGenerator.n.b(this.a, blockposition))
? WorldGenerator.n.d()
: biomebase.getMobs(enumcreaturetype));
if (WorldGenerator.SWAMP_HUT.c(this.a, blockposition)) {
if (enumcreaturetype == EnumCreatureType.MONSTER) {
return WorldGenerator.SWAMP_HUT.e();
}
if (enumcreaturetype == EnumCreatureType.CREATURE) {
return WorldGenerator.SWAMP_HUT.f();
}
} else if (enumcreaturetype == EnumCreatureType.MONSTER) {
if (WorldGenerator.PILLAGER_OUTPOST.a(this.a, blockposition)) {
return WorldGenerator.PILLAGER_OUTPOST.e();
}
if (WorldGenerator.OCEAN_MONUMENT.a(this.a, blockposition)) {
return WorldGenerator.OCEAN_MONUMENT.e();
}
}
return super.getMobsFor(enumcreaturetype, blockposition);
}
@Override
public GeneratorSettingsDefault getSettings() {
return defaultSettings;
public int getSeaLevel() {
return world.getSeaLevel();
}
@Override
@ -203,8 +244,6 @@ public final class InjectedChunkGenerator extends ChunkGeneratorAbstract<Generat
return world.getSeaLevel() + 1;
}
public void setBaseChunkGenerator(BaseChunkGenerator baseChunkGenerator) {
this.baseChunkGenerator = Objects.requireNonNull(baseChunkGenerator, "baseChunkGenerator");
}

View File

@ -8,7 +8,7 @@ import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.mockito.Mockito;
import net.minecraft.server.v1_13_R2.DispenserRegistry;
import net.minecraft.server.v1_14_R1.DispenserRegistry;
public class TestFactory {
@ -22,7 +22,7 @@ public class TestFactory {
if (Bukkit.getServer() != null) {
return;
}
DispenserRegistry.c();
DispenserRegistry.init();
Server server = Mockito.mock(Server.class);
Mockito.when(server.getLogger()).thenReturn(Logger.getLogger(TestFactory.class.getName()));
Mockito.when(server.getWorld(Mockito.eq("test"))).thenAnswer(args -> world(args.getArgument(0)));

View File

@ -69,7 +69,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13.1-R0.1-SNAPSHOT</version>
<version>1.14-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion> <!-- Let's not put the outdated JUnit 4 on our build path -->