SPIGOT-7283, SPIGOT-7318: Add AsyncStructureGenerateEvent and BlockState cloning

By: Lauriichan <laura.endress@playuniverse.org>
This commit is contained in:
CraftBukkit/Spigot 2023-09-29 06:54:35 +10:00
parent bbc6a0e459
commit c651c0a51b
61 changed files with 1920 additions and 4 deletions

View File

@ -0,0 +1,10 @@
--- a/net/minecraft/server/commands/PlaceCommand.java
+++ b/net/minecraft/server/commands/PlaceCommand.java
@@ -130,6 +130,7 @@
if (!structurestart.isValid()) {
throw PlaceCommand.ERROR_STRUCTURE_FAILED.create();
} else {
+ structurestart.generationEventCause = org.bukkit.event.world.AsyncStructureGenerateEvent.Cause.COMMAND; // CraftBukkit - set AsyncStructureGenerateEvent.Cause.COMMAND as generation cause
StructureBoundingBox structureboundingbox = structurestart.getBoundingBox();
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(SectionPosition.blockToSectionCoord(structureboundingbox.minX()), SectionPosition.blockToSectionCoord(structureboundingbox.minZ()));
ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(SectionPosition.blockToSectionCoord(structureboundingbox.maxX()), SectionPosition.blockToSectionCoord(structureboundingbox.maxZ()));

View File

@ -0,0 +1,151 @@
--- a/net/minecraft/world/level/levelgen/structure/StructurePiece.java
+++ b/net/minecraft/world/level/levelgen/structure/StructurePiece.java
@@ -50,7 +50,7 @@
private EnumBlockRotation rotation;
protected int genDepth;
private final WorldGenFeatureStructurePieceType type;
- private static final Set<Block> SHAPE_CHECK_BLOCKS = ImmutableSet.builder().add(Blocks.NETHER_BRICK_FENCE).add(Blocks.TORCH).add(Blocks.WALL_TORCH).add(Blocks.OAK_FENCE).add(Blocks.SPRUCE_FENCE).add(Blocks.DARK_OAK_FENCE).add(Blocks.ACACIA_FENCE).add(Blocks.BIRCH_FENCE).add(Blocks.JUNGLE_FENCE).add(Blocks.LADDER).add(Blocks.IRON_BARS).build();
+ public static final Set<Block> SHAPE_CHECK_BLOCKS = ImmutableSet.<Block>builder().add(Blocks.NETHER_BRICK_FENCE).add(Blocks.TORCH).add(Blocks.WALL_TORCH).add(Blocks.OAK_FENCE).add(Blocks.SPRUCE_FENCE).add(Blocks.DARK_OAK_FENCE).add(Blocks.ACACIA_FENCE).add(Blocks.BIRCH_FENCE).add(Blocks.JUNGLE_FENCE).add(Blocks.LADDER).add(Blocks.IRON_BARS).build(); // CraftBukkit - decompile error / PAIL private -> public
protected StructurePiece(WorldGenFeatureStructurePieceType worldgenfeaturestructurepiecetype, int i, StructureBoundingBox structureboundingbox) {
this.type = worldgenfeaturestructurepiecetype;
@@ -59,14 +59,11 @@
}
public StructurePiece(WorldGenFeatureStructurePieceType worldgenfeaturestructurepiecetype, NBTTagCompound nbttagcompound) {
- int i = nbttagcompound.getInt("GD");
- DataResult dataresult = StructureBoundingBox.CODEC.parse(DynamicOpsNBT.INSTANCE, nbttagcompound.get("BB"));
- Logger logger = StructurePiece.LOGGER;
-
- Objects.requireNonNull(logger);
- this(worldgenfeaturestructurepiecetype, i, (StructureBoundingBox) dataresult.resultOrPartial(logger::error).orElseThrow(() -> {
+ // CraftBukkit start - decompile error
+ this(worldgenfeaturestructurepiecetype, nbttagcompound.getInt("GD"), (StructureBoundingBox) StructureBoundingBox.CODEC.parse(DynamicOpsNBT.INSTANCE, nbttagcompound.get("BB")).resultOrPartial(Objects.requireNonNull(StructurePiece.LOGGER)::error).orElseThrow(() -> {
return new IllegalArgumentException("Invalid boundingbox");
}));
+ // CraftBukkit end
int j = nbttagcompound.getInt("O");
this.setOrientation(j == -1 ? null : EnumDirection.from2DDataValue(j));
@@ -84,13 +81,11 @@
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.putString("id", BuiltInRegistries.STRUCTURE_PIECE.getKey(this.getType()).toString());
- DataResult dataresult = StructureBoundingBox.CODEC.encodeStart(DynamicOpsNBT.INSTANCE, this.boundingBox);
- Logger logger = StructurePiece.LOGGER;
-
- Objects.requireNonNull(logger);
- dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> {
- nbttagcompound.put("BB", nbtbase);
+ // CraftBukkit start - decompile error
+ StructureBoundingBox.CODEC.encodeStart(DynamicOpsNBT.INSTANCE, this.boundingBox).resultOrPartial(Objects.requireNonNull(StructurePiece.LOGGER)::error).ifPresent((nbtbase) -> {
+ nbttagcompound.put("BB", nbtbase);
});
+ // CraftBukkit end
EnumDirection enumdirection = this.getOrientation();
nbttagcompound.putInt("O", enumdirection == null ? -1 : enumdirection.get2DDataValue());
@@ -190,6 +185,11 @@
}
generatoraccessseed.setBlock(blockposition_mutableblockposition, iblockdata, 2);
+ // CraftBukkit start - fluid handling is already done if we have a transformer generator access
+ if (generatoraccessseed instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess) {
+ return;
+ }
+ // CraftBukkit end
Fluid fluid = generatoraccessseed.getFluidState(blockposition_mutableblockposition);
if (!fluid.isEmpty()) {
@@ -204,6 +204,38 @@
}
}
+ // CraftBukkit start
+ protected boolean placeCraftBlockEntity(WorldAccess worldAccess, BlockPosition position, org.bukkit.craftbukkit.block.CraftBlockEntityState<?> craftBlockEntityState, int i) {
+ if (worldAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) {
+ return transformerAccess.setCraftBlock(position, craftBlockEntityState, i);
+ }
+ boolean result = worldAccess.setBlock(position, craftBlockEntityState.getHandle(), i);
+ TileEntity tileEntity = worldAccess.getBlockEntity(position);
+ if (tileEntity != null) {
+ tileEntity.load(craftBlockEntityState.getSnapshotNBT());
+ }
+ return result;
+ }
+
+ protected void placeCraftSpawner(WorldAccess worldAccess, BlockPosition position, org.bukkit.entity.EntityType entityType, int i) {
+ // This method is used in structures that are generated by code and place spawners as they set the entity after the block was placed making it impossible for plugins to access that information
+ org.bukkit.craftbukkit.block.CraftCreatureSpawner spawner = (org.bukkit.craftbukkit.block.CraftCreatureSpawner) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(position, Blocks.SPAWNER.defaultBlockState(), null);
+ spawner.setSpawnedType(entityType);
+ placeCraftBlockEntity(worldAccess, position, spawner, i);
+ }
+
+ protected void setCraftLootTable(WorldAccess worldAccess, BlockPosition position, RandomSource randomSource, net.minecraft.resources.MinecraftKey loottableKey) {
+ // This method is used in structures that use data markers to a loot table to loot containers as otherwise plugins won't have access to that information.
+ net.minecraft.world.level.block.entity.TileEntity tileEntity = worldAccess.getBlockEntity(position);
+ if (tileEntity instanceof net.minecraft.world.level.block.entity.TileEntityLootable tileEntityLootable) {
+ tileEntityLootable.setLootTable(loottableKey, randomSource.nextLong());
+ if (worldAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) {
+ transformerAccess.setCraftBlock(position, (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(position, tileEntity.getBlockState(), tileEntityLootable.saveWithFullMetadata()), 3);
+ }
+ }
+ }
+ // CraftBukkit end
+
protected boolean canBeReplaced(IWorldReader iworldreader, int i, int j, int k, StructureBoundingBox structureboundingbox) {
return true;
}
@@ -397,12 +429,20 @@
iblockdata = reorient(worldaccess, blockposition, Blocks.CHEST.defaultBlockState());
}
+ // CraftBukkit start
+ /*
worldaccess.setBlock(blockposition, iblockdata, 2);
TileEntity tileentity = worldaccess.getBlockEntity(blockposition);
if (tileentity instanceof TileEntityChest) {
((TileEntityChest) tileentity).setLootTable(minecraftkey, randomsource.nextLong());
}
+ */
+ org.bukkit.craftbukkit.block.CraftChest chestState = (org.bukkit.craftbukkit.block.CraftChest) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockposition, iblockdata, null);
+ chestState.setLootTable(org.bukkit.Bukkit.getLootTable(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(minecraftkey)));
+ chestState.setSeed(randomsource.nextLong());
+ placeCraftBlockEntity(worldaccess, blockposition, chestState, 2);
+ // CraftBukkit end
return true;
} else {
@@ -414,12 +454,31 @@
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = this.getWorldPos(i, j, k);
if (structureboundingbox.isInside(blockposition_mutableblockposition) && !generatoraccessseed.getBlockState(blockposition_mutableblockposition).is(Blocks.DISPENSER)) {
+ // CraftBukkit start
+ /*
this.placeBlock(generatoraccessseed, (IBlockData) Blocks.DISPENSER.defaultBlockState().setValue(BlockDispenser.FACING, enumdirection), i, j, k, structureboundingbox);
TileEntity tileentity = generatoraccessseed.getBlockEntity(blockposition_mutableblockposition);
if (tileentity instanceof TileEntityDispenser) {
((TileEntityDispenser) tileentity).setLootTable(minecraftkey, randomsource.nextLong());
}
+ */
+ if (!this.canBeReplaced(generatoraccessseed, i, j, k, structureboundingbox)) {
+ return true;
+ }
+ IBlockData iblockdata = Blocks.DISPENSER.defaultBlockState().setValue(BlockDispenser.FACING, enumdirection);
+ if (this.mirror != EnumBlockMirror.NONE) {
+ iblockdata = iblockdata.mirror(this.mirror);
+ }
+ if (this.rotation != EnumBlockRotation.NONE) {
+ iblockdata = iblockdata.rotate(this.rotation);
+ }
+
+ org.bukkit.craftbukkit.block.CraftDispenser dispenserState = (org.bukkit.craftbukkit.block.CraftDispenser) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockposition_mutableblockposition, iblockdata, null);
+ dispenserState.setLootTable(org.bukkit.Bukkit.getLootTable(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(minecraftkey)));
+ dispenserState.setSeed(randomsource.nextLong());
+ placeCraftBlockEntity(generatoraccessseed, blockposition_mutableblockposition, dispenserState, 2);
+ // CraftBukkit end
return true;
} else {

View File

@ -0,0 +1,38 @@
--- a/net/minecraft/world/level/levelgen/structure/StructureStart.java
+++ b/net/minecraft/world/level/levelgen/structure/StructureStart.java
@@ -31,6 +31,7 @@
private int references;
@Nullable
private volatile StructureBoundingBox cachedBoundingBox;
+ public org.bukkit.event.world.AsyncStructureGenerateEvent.Cause generationEventCause = org.bukkit.event.world.AsyncStructureGenerateEvent.Cause.WORLD_GENERATION; // CraftBukkit
public StructureStart(Structure structure, ChunkCoordIntPair chunkcoordintpair, int i, PiecesContainer piecescontainer) {
this.structure = structure;
@@ -91,6 +92,8 @@
StructureBoundingBox structureboundingbox1 = ((StructurePiece) list.get(0)).boundingBox;
BlockPosition blockposition = structureboundingbox1.getCenter();
BlockPosition blockposition1 = new BlockPosition(blockposition.getX(), structureboundingbox1.minY(), blockposition.getZ());
+ // CraftBukkit start
+ /*
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
@@ -100,6 +103,18 @@
structurepiece.postProcess(generatoraccessseed, structuremanager, chunkgenerator, randomsource, structureboundingbox, chunkcoordintpair, blockposition1);
}
}
+ */
+ List<StructurePiece> pieces = list.stream().filter(piece -> piece.getBoundingBox().intersects(structureboundingbox)).toList();
+ if (!pieces.isEmpty()) {
+ org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess = new org.bukkit.craftbukkit.util.TransformerGeneratorAccess();
+ transformerAccess.setHandle(generatoraccessseed);
+ transformerAccess.setStructureTransformer(new org.bukkit.craftbukkit.util.CraftStructureTransformer(generationEventCause, generatoraccessseed, structuremanager, structure, structureboundingbox, chunkcoordintpair));
+ for (StructurePiece piece : pieces) {
+ piece.postProcess(transformerAccess, structuremanager, chunkgenerator, randomsource, structureboundingbox, chunkcoordintpair, blockposition1);
+ }
+ transformerAccess.getStructureTransformer().discard();
+ }
+ // CraftBukkit end
this.structure.afterPlace(generatoraccessseed, structuremanager, chunkgenerator, randomsource, structureboundingbox, chunkcoordintpair, this.pieceContainer);
}

View File

@ -0,0 +1,18 @@
--- a/net/minecraft/world/level/levelgen/structure/structures/DesertPyramidStructure.java
+++ b/net/minecraft/world/level/levelgen/structure/structures/DesertPyramidStructure.java
@@ -70,6 +70,15 @@
private static void placeSuspiciousSand(StructureBoundingBox structureboundingbox, GeneratorAccessSeed generatoraccessseed, BlockPosition blockposition) {
if (structureboundingbox.isInside(blockposition)) {
+ // CraftBukkit start
+ if (generatoraccessseed instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) {
+ org.bukkit.craftbukkit.block.CraftBrushableBlock brushableState = (org.bukkit.craftbukkit.block.CraftBrushableBlock) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockposition, Blocks.SUSPICIOUS_SAND.defaultBlockState(), null);
+ brushableState.setLootTable(org.bukkit.Bukkit.getLootTable(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(LootTables.DESERT_PYRAMID_ARCHAEOLOGY)));
+ brushableState.setSeed(blockposition.asLong());
+ transformerAccess.setCraftBlock(blockposition, brushableState, 2);
+ return;
+ }
+ // CraftBukkit end
generatoraccessseed.setBlock(blockposition, Blocks.SUSPICIOUS_SAND.defaultBlockState(), 2);
generatoraccessseed.getBlockEntity(blockposition, TileEntityTypes.BRUSHABLE_BLOCK).ifPresent((brushableblockentity) -> {
brushableblockentity.setLootTable(LootTables.DESERT_PYRAMID_ARCHAEOLOGY, blockposition.asLong());

View File

@ -0,0 +1,15 @@
--- a/net/minecraft/world/level/levelgen/structure/structures/EndCityPieces.java
+++ b/net/minecraft/world/level/levelgen/structure/structures/EndCityPieces.java
@@ -284,7 +284,12 @@
BlockPosition blockposition1 = blockposition.below();
if (structureboundingbox.isInside(blockposition1)) {
+ // CraftBukkit start - ensure block transformation
+ /*
TileEntityLootable.setLootTable(worldaccess, randomsource, blockposition1, LootTables.END_CITY_TREASURE);
+ */
+ setCraftLootTable(worldaccess, blockposition1, randomsource, LootTables.END_CITY_TREASURE);
+ // CraftBukkit end
}
} else if (structureboundingbox.isInside(blockposition) && World.isInSpawnableBounds(blockposition)) {
if (s.startsWith("Sentry")) {

View File

@ -0,0 +1,19 @@
--- a/net/minecraft/world/level/levelgen/structure/structures/IglooPieces.java
+++ b/net/minecraft/world/level/levelgen/structure/structures/IglooPieces.java
@@ -85,11 +85,16 @@
protected void handleDataMarker(String s, BlockPosition blockposition, WorldAccess worldaccess, RandomSource randomsource, StructureBoundingBox structureboundingbox) {
if ("chest".equals(s)) {
worldaccess.setBlock(blockposition, Blocks.AIR.defaultBlockState(), 3);
+ // CraftBukkit start - ensure block transformation
+ /*
TileEntity tileentity = worldaccess.getBlockEntity(blockposition.below());
if (tileentity instanceof TileEntityChest) {
((TileEntityChest) tileentity).setLootTable(LootTables.IGLOO_CHEST, randomsource.nextLong());
}
+ */
+ setCraftLootTable(worldaccess, blockposition.below(), randomsource, LootTables.IGLOO_CHEST);
+ // CraftBukkit end
}
}

View File

@ -0,0 +1,55 @@
--- a/net/minecraft/world/level/levelgen/structure/structures/MineshaftPieces.java
+++ b/net/minecraft/world/level/levelgen/structure/structures/MineshaftPieces.java
@@ -42,6 +42,10 @@
import net.minecraft.world.level.storage.loot.LootTables;
import org.slf4j.Logger;
+// CraftBukkit start - imports
+import net.minecraft.nbt.NBTBase;
+// CraftBukkit end
+
public class MineshaftPieces {
static final Logger LOGGER = LogUtils.getLogger();
@@ -514,6 +518,8 @@
if (structureboundingbox.isInside(blockposition_mutableblockposition) && this.isInterior(generatoraccessseed, 1, 0, l, structureboundingbox)) {
this.hasPlacedSpider = true;
+ // CraftBukkit start
+ /*
generatoraccessseed.setBlock(blockposition_mutableblockposition, Blocks.SPAWNER.defaultBlockState(), 2);
TileEntity tileentity = generatoraccessseed.getBlockEntity(blockposition_mutableblockposition);
@@ -522,6 +528,9 @@
tileentitymobspawner.setEntityId(EntityTypes.CAVE_SPIDER, randomsource);
}
+ */
+ placeCraftSpawner(generatoraccessseed, blockposition_mutableblockposition, org.bukkit.entity.EntityType.CAVE_SPIDER, 2);
+ // CraftBukkit end
}
}
}
@@ -813,11 +822,11 @@
public d(NBTTagCompound nbttagcompound) {
super(WorldGenFeatureStructurePieceType.MINE_SHAFT_ROOM, nbttagcompound);
- DataResult dataresult = StructureBoundingBox.CODEC.listOf().parse(DynamicOpsNBT.INSTANCE, nbttagcompound.getList("Entrances", 11));
+ DataResult<List<StructureBoundingBox>> dataresult = StructureBoundingBox.CODEC.listOf().parse(DynamicOpsNBT.INSTANCE, nbttagcompound.getList("Entrances", 11)); // CraftBukkit - decompile error
Logger logger = MineshaftPieces.LOGGER;
Objects.requireNonNull(logger);
- Optional optional = dataresult.resultOrPartial(logger::error);
+ Optional<List<StructureBoundingBox>> optional = dataresult.resultOrPartial(logger::error); // CraftBukkit - decompile error
List list = this.childEntranceBoxes;
Objects.requireNonNull(this.childEntranceBoxes);
@@ -923,7 +932,7 @@
@Override
protected void addAdditionalSaveData(StructurePieceSerializationContext structurepieceserializationcontext, NBTTagCompound nbttagcompound) {
super.addAdditionalSaveData(structurepieceserializationcontext, nbttagcompound);
- DataResult dataresult = StructureBoundingBox.CODEC.listOf().encodeStart(DynamicOpsNBT.INSTANCE, this.childEntranceBoxes);
+ DataResult<NBTBase> dataresult = StructureBoundingBox.CODEC.listOf().encodeStart(DynamicOpsNBT.INSTANCE, this.childEntranceBoxes); // CraftBukkit - decompile error
Logger logger = MineshaftPieces.LOGGER;
Objects.requireNonNull(logger);

View File

@ -0,0 +1,21 @@
--- a/net/minecraft/world/level/levelgen/structure/structures/NetherFortressPieces.java
+++ b/net/minecraft/world/level/levelgen/structure/structures/NetherFortressPieces.java
@@ -428,6 +428,8 @@
if (structureboundingbox.isInside(blockposition_mutableblockposition)) {
this.hasPlacedSpawner = true;
+ // CraftBukkit start
+ /*
generatoraccessseed.setBlock(blockposition_mutableblockposition, Blocks.SPAWNER.defaultBlockState(), 2);
TileEntity tileentity = generatoraccessseed.getBlockEntity(blockposition_mutableblockposition);
@@ -436,6 +438,9 @@
tileentitymobspawner.setEntityId(EntityTypes.BLAZE, randomsource);
}
+ */
+ placeCraftSpawner(generatoraccessseed, blockposition_mutableblockposition, org.bukkit.entity.EntityType.BLAZE, 2);
+ // CraftBukkit end
}
}

View File

@ -0,0 +1,23 @@
--- a/net/minecraft/world/level/levelgen/structure/structures/OceanRuinPieces.java
+++ b/net/minecraft/world/level/levelgen/structure/structures/OceanRuinPieces.java
@@ -198,12 +198,20 @@
@Override
protected void handleDataMarker(String s, BlockPosition blockposition, WorldAccess worldaccess, RandomSource randomsource, StructureBoundingBox structureboundingbox) {
if ("chest".equals(s)) {
+ // CraftBukkit start - transform block to ensure loot table is accessible
+ /*
worldaccess.setBlock(blockposition, (IBlockData) Blocks.CHEST.defaultBlockState().setValue(BlockChest.WATERLOGGED, worldaccess.getFluidState(blockposition).is(TagsFluid.WATER)), 2);
TileEntity tileentity = worldaccess.getBlockEntity(blockposition);
if (tileentity instanceof TileEntityChest) {
((TileEntityChest) tileentity).setLootTable(this.isLarge ? LootTables.UNDERWATER_RUIN_BIG : LootTables.UNDERWATER_RUIN_SMALL, randomsource.nextLong());
}
+ */
+ org.bukkit.craftbukkit.block.CraftChest craftChest = (org.bukkit.craftbukkit.block.CraftChest) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockposition, Blocks.CHEST.defaultBlockState().setValue(BlockChest.WATERLOGGED, worldaccess.getFluidState(blockposition).is(TagsFluid.WATER)), null);
+ craftChest.setSeed(randomsource.nextLong());
+ craftChest.setLootTable(org.bukkit.Bukkit.getLootTable(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(this.isLarge ? LootTables.UNDERWATER_RUIN_BIG : LootTables.UNDERWATER_RUIN_SMALL)));
+ placeCraftBlockEntity(worldaccess, blockposition, craftChest, 2);
+ // CraftBukkit end
} else if ("drowned".equals(s)) {
EntityDrowned entitydrowned = (EntityDrowned) EntityTypes.DROWNED.create(worldaccess.getLevel());

View File

@ -0,0 +1,30 @@
--- a/net/minecraft/world/level/levelgen/structure/structures/StrongholdPieces.java
+++ b/net/minecraft/world/level/levelgen/structure/structures/StrongholdPieces.java
@@ -53,7 +53,7 @@
public boolean doPlace(int i) {
return super.doPlace(i) && i > 5;
}
- }};
+ } }; // CraftBukkit - fix decompile styling
private static List<StrongholdPieces.f> currentPieces;
static Class<? extends StrongholdPieces.p> imposedPiece;
private static int totalWeight;
@@ -1136,6 +1136,8 @@
if (structureboundingbox.isInside(blockposition_mutableblockposition)) {
this.hasPlacedSpawner = true;
+ // CraftBukkit start
+ /*
generatoraccessseed.setBlock(blockposition_mutableblockposition, Blocks.SPAWNER.defaultBlockState(), 2);
TileEntity tileentity = generatoraccessseed.getBlockEntity(blockposition_mutableblockposition);
@@ -1144,6 +1146,9 @@
tileentitymobspawner.setEntityId(EntityTypes.SILVERFISH, randomsource);
}
+ */
+ placeCraftSpawner(generatoraccessseed, blockposition_mutableblockposition, org.bukkit.entity.EntityType.SILVERFISH, 2);
+ // CraftBukkit end
}
}

View File

@ -34,7 +34,66 @@
return definedstructure_blockinfo.pos.getY();
}).thenComparingInt((definedstructure_blockinfo) -> {
return definedstructure_blockinfo.pos.getX();
@@ -472,11 +483,13 @@
@@ -229,6 +240,19 @@
if (this.palettes.isEmpty()) {
return false;
} else {
+ // CraftBukkit start
+ // We only want the TransformerGeneratorAccess at certain locations because in here are many "block update" calls that shouldn't be transformed
+ WorldAccess wrappedAccess = worldaccess;
+ org.bukkit.craftbukkit.util.CraftStructureTransformer structureTransformer = null;
+ if (wrappedAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) {
+ worldaccess = transformerAccess.getHandle();
+ structureTransformer = transformerAccess.getStructureTransformer();
+ // The structureTransformer is not needed if we can not transform blocks therefore we can save a little bit of performance doing this
+ if (structureTransformer != null && !structureTransformer.canTransformBlocks()) {
+ structureTransformer = null;
+ }
+ }
+ // CraftBukkit end
List<DefinedStructure.BlockInfo> list = definedstructureinfo.getRandomPalette(this.palettes, blockposition).blocks();
if ((!list.isEmpty() || !definedstructureinfo.isIgnoreEntities() && !this.entityInfoList.isEmpty()) && this.size.getX() >= 1 && this.size.getY() >= 1 && this.size.getZ() >= 1) {
@@ -260,6 +284,20 @@
Clearable.tryClear(tileentity);
worldaccess.setBlock(blockposition2, Blocks.BARRIER.defaultBlockState(), 20);
}
+ // CraftBukkit start
+ if (structureTransformer != null) {
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockposition2, iblockdata, null);
+ if (definedstructure_blockinfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> entityState) {
+ entityState.loadData(definedstructure_blockinfo.nbt);
+ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable<?> craftLootable) {
+ craftLootable.setSeed(randomsource.nextLong());
+ }
+ }
+ craftBlockState = structureTransformer.transformCraftState(craftBlockState);
+ iblockdata = craftBlockState.getHandle();
+ definedstructure_blockinfo = new DefinedStructure.BlockInfo(blockposition2, iblockdata, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null));
+ }
+ // CraftBukkit end
if (worldaccess.setBlock(blockposition2, iblockdata, i)) {
j = Math.min(j, blockposition2.getX());
@@ -272,7 +310,7 @@
if (definedstructure_blockinfo.nbt != null) {
tileentity = worldaccess.getBlockEntity(blockposition2);
if (tileentity != null) {
- if (tileentity instanceof TileEntityLootable) {
+ if (wrappedAccess == worldaccess && tileentity instanceof TileEntityLootable) { // CraftBukkit - only process if don't have a transformer access (originalAccess == worldaccess)
definedstructure_blockinfo.nbt.putLong("LootTableSeed", randomsource.nextLong());
}
@@ -377,7 +415,7 @@
}
if (!definedstructureinfo.isIgnoreEntities()) {
- this.placeEntities(worldaccess, blockposition, definedstructureinfo.getMirror(), definedstructureinfo.getRotation(), definedstructureinfo.getRotationPivot(), structureboundingbox, definedstructureinfo.shouldFinalizeEntities());
+ this.placeEntities(wrappedAccess, blockposition, definedstructureinfo.getMirror(), definedstructureinfo.getRotation(), definedstructureinfo.getRotationPivot(), structureboundingbox, definedstructureinfo.shouldFinalizeEntities()); // CraftBukkit
}
return true;
@@ -472,11 +510,13 @@
}
private static Optional<Entity> createEntityIgnoreException(WorldAccess worldaccess, NBTTagCompound nbttagcompound) {
@ -52,7 +111,7 @@
}
public BaseBlockPosition getSize(EnumBlockRotation enumblockrotation) {
@@ -690,6 +703,11 @@
@@ -690,6 +730,11 @@
nbttagcompound.put("entities", nbttaglist3);
nbttagcompound.put("size", this.newIntegerList(this.size.getX(), this.size.getY(), this.size.getZ()));
@ -64,7 +123,7 @@
return GameProfileSerializer.addCurrentDataVersion(nbttagcompound);
}
@@ -729,6 +747,12 @@
@@ -729,6 +774,12 @@
}
}
@ -77,7 +136,7 @@
}
private void loadPalette(HolderGetter<Block> holdergetter, NBTTagList nbttaglist, NBTTagList nbttaglist1) {
@@ -858,7 +882,7 @@
@@ -858,7 +909,7 @@
public IBlockData stateFor(int i) {
IBlockData iblockdata = (IBlockData) this.ids.byId(i);

View File

@ -21,6 +21,12 @@ public final class CapturedBlockState extends CraftBlockState {
this.treeBlock = treeBlock;
}
protected CapturedBlockState(CapturedBlockState state) {
super(state);
this.treeBlock = state.treeBlock;
}
@Override
public boolean update(boolean force, boolean applyPhysics) {
boolean result = super.update(force, applyPhysics);
@ -50,6 +56,11 @@ public final class CapturedBlockState extends CraftBlockState {
return result;
}
@Override
public CapturedBlockState copy() {
return new CapturedBlockState(this);
}
public static CapturedBlockState getBlockState(World world, BlockPosition pos, int flag) {
return new CapturedBlockState(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()), flag, false);
}

View File

@ -23,6 +23,10 @@ public class CraftBanner extends CraftBlockEntityState<TileEntityBanner> impleme
super(world, tileEntity);
}
protected CraftBanner(CraftBanner state) {
super(state);
}
@Override
public void load(TileEntityBanner banner) {
super.load(banner);
@ -100,4 +104,9 @@ public class CraftBanner extends CraftBlockEntityState<TileEntityBanner> impleme
}
banner.itemPatterns = newPatterns;
}
@Override
public CraftBanner copy() {
return new CraftBanner(this);
}
}

View File

@ -15,6 +15,10 @@ public class CraftBarrel extends CraftLootable<TileEntityBarrel> implements Barr
super(world, tileEntity);
}
protected CraftBarrel(CraftBarrel state) {
super(state);
}
@Override
public Inventory getSnapshotInventory() {
return new CraftInventory(this.getSnapshot());
@ -58,4 +62,9 @@ public class CraftBarrel extends CraftLootable<TileEntityBarrel> implements Barr
}
getTileEntity().openersCounter.opened = false;
}
@Override
public CraftBarrel copy() {
return new CraftBarrel(this);
}
}

View File

@ -20,6 +20,10 @@ public class CraftBeacon extends CraftBlockEntityState<TileEntityBeacon> impleme
super(world, tileEntity);
}
protected CraftBeacon(CraftBeacon state) {
super(state);
}
@Override
public Collection<LivingEntity> getEntitiesInRange() {
ensureNoWorldGeneration();
@ -92,4 +96,9 @@ public class CraftBeacon extends CraftBlockEntityState<TileEntityBeacon> impleme
public void setLock(String key) {
this.getSnapshot().lockKey = (key == null) ? ChestLock.NO_LOCK : new ChestLock(key);
}
@Override
public CraftBeacon copy() {
return new CraftBeacon(this);
}
}

View File

@ -11,6 +11,10 @@ public class CraftBed extends CraftBlockEntityState<TileEntityBed> implements Be
super(world, tileEntity);
}
protected CraftBed(CraftBed state) {
super(state);
}
@Override
public DyeColor getColor() {
switch (getType()) {
@ -55,4 +59,9 @@ public class CraftBed extends CraftBlockEntityState<TileEntityBed> implements Be
public void setColor(DyeColor color) {
throw new UnsupportedOperationException("Must set block type to appropriate bed colour");
}
@Override
public CraftBed copy() {
return new CraftBed(this);
}
}

View File

@ -20,6 +20,10 @@ public class CraftBeehive extends CraftBlockEntityState<TileEntityBeehive> imple
super(world, tileEntity);
}
protected CraftBeehive(CraftBeehive state) {
super(state);
}
@Override
public Location getFlower() {
BlockPosition flower = getSnapshot().savedFlowerPos;
@ -81,4 +85,9 @@ public class CraftBeehive extends CraftBlockEntityState<TileEntityBeehive> imple
getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false);
}
@Override
public CraftBeehive copy() {
return new CraftBeehive(this);
}
}

View File

@ -18,6 +18,10 @@ public class CraftBell extends CraftBlockEntityState<TileEntityBell> implements
super(world, tileEntity);
}
protected CraftBell(CraftBell state) {
super(state);
}
@Override
public boolean ring(Entity entity, BlockFace direction) {
Preconditions.checkArgument(direction == null || direction.isCartesian(), "direction must be cartesian, given %s", direction);
@ -67,4 +71,9 @@ public class CraftBell extends CraftBlockEntityState<TileEntityBell> implements
public int getResonatingTicks() {
return isResonating() ? getSnapshot().ticks : 0;
}
@Override
public CraftBell copy() {
return new CraftBell(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftBlastFurnace extends CraftFurnace<TileEntityBlastFurnace> impl
public CraftBlastFurnace(World world, TileEntityBlastFurnace tileEntity) {
super(world, tileEntity);
}
protected CraftBlastFurnace(CraftBlastFurnace state) {
super(state);
}
@Override
public CraftBlastFurnace copy() {
return new CraftBlastFurnace(this);
}
}

View File

@ -28,6 +28,13 @@ public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState
this.load(snapshot);
}
protected CraftBlockEntityState(CraftBlockEntityState<T> state) {
super(state);
this.tileEntity = createSnapshot(state.snapshot);
this.snapshot = tileEntity;
load(snapshot);
}
public void refreshSnapshot() {
this.load(tileEntity);
}
@ -43,6 +50,12 @@ public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState
return snapshot;
}
// Loads the specified data into the snapshot TileEntity.
public void loadData(NBTTagCompound nbtTagCompound) {
snapshot.load(nbtTagCompound);
load(snapshot);
}
// copies the TileEntity-specific data, retains the position
private void copyData(T from, T to) {
NBTTagCompound nbtTagCompound = from.saveWithFullMetadata();
@ -118,4 +131,9 @@ public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState
T vanillaTileEntitiy = (T) TileEntity.loadStatic(CraftLocation.toBlockPosition(location), getHandle(), getSnapshotNBT());
return PacketPlayOutTileEntityData.create(vanillaTileEntitiy);
}
@Override
public CraftBlockEntityState<T> copy() {
return new CraftBlockEntityState<>(this);
}
}

View File

@ -50,6 +50,15 @@ public class CraftBlockState implements BlockState {
data = blockData;
}
// Creates a unplaced copy (world == null copy)
protected CraftBlockState(CraftBlockState state) {
this.world = null;
this.position = state.getPosition().immutable();
this.data = state.data;
this.flag = state.flag;
setWorldHandle(state.getWorldHandle());
}
public void setWorldHandle(GeneratorAccess generatorAccess) {
if (generatorAccess instanceof net.minecraft.world.level.World) {
this.weakWorld = null;
@ -318,4 +327,9 @@ public class CraftBlockState implements BlockState {
protected void requirePlaced() {
Preconditions.checkState(isPlaced(), "The blockState must be placed to call this method");
}
@Override
public CraftBlockState copy() {
return new CraftBlockState(this);
}
}

View File

@ -12,6 +12,10 @@ public class CraftBrewingStand extends CraftContainer<TileEntityBrewingStand> im
super(world, tileEntity);
}
protected CraftBrewingStand(CraftBrewingStand state) {
super(state);
}
@Override
public BrewerInventory getSnapshotInventory() {
return new CraftInventoryBrewer(this.getSnapshot());
@ -45,4 +49,9 @@ public class CraftBrewingStand extends CraftContainer<TileEntityBrewingStand> im
public void setFuelLevel(int level) {
this.getSnapshot().fuel = level;
}
@Override
public CraftBrewingStand copy() {
return new CraftBrewingStand(this);
}
}

View File

@ -16,6 +16,10 @@ public class CraftBrushableBlock extends CraftBlockEntityState<BrushableBlockEnt
super(world, tileEntity);
}
protected CraftBrushableBlock(CraftBrushableBlock state) {
super(state);
}
@Override
public ItemStack getItem() {
return CraftItemStack.asBukkitCopy(getSnapshot().getItem());
@ -64,4 +68,9 @@ public class CraftBrushableBlock extends CraftBlockEntityState<BrushableBlockEnt
MinecraftKey key = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
getSnapshot().setLootTable(key, seed);
}
@Override
public CraftBrushableBlock copy() {
return new CraftBrushableBlock(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftCalibratedSculkSensor extends CraftSculkSensor<CalibratedSculk
public CraftCalibratedSculkSensor(World world, CalibratedSculkSensorBlockEntity tileEntity) {
super(world, tileEntity);
}
protected CraftCalibratedSculkSensor(CraftCalibratedSculkSensor state) {
super(state);
}
@Override
public CraftCalibratedSculkSensor copy() {
return new CraftCalibratedSculkSensor(this);
}
}

View File

@ -12,6 +12,10 @@ public class CraftCampfire extends CraftBlockEntityState<TileEntityCampfire> imp
super(world, tileEntity);
}
protected CraftCampfire(CraftCampfire state) {
super(state);
}
@Override
public int getSize() {
return getSnapshot().getItems().size();
@ -47,4 +51,9 @@ public class CraftCampfire extends CraftBlockEntityState<TileEntityCampfire> imp
public void setCookTimeTotal(int index, int cookTimeTotal) {
getSnapshot().cookingTime[index] = cookTimeTotal;
}
@Override
public CraftCampfire copy() {
return new CraftCampfire(this);
}
}

View File

@ -19,6 +19,10 @@ public class CraftChest extends CraftLootable<TileEntityChest> implements Chest
super(world, tileEntity);
}
protected CraftChest(CraftChest state) {
super(state);
}
@Override
public Inventory getSnapshotInventory() {
return new CraftInventory(this.getSnapshot());
@ -77,4 +81,9 @@ public class CraftChest extends CraftLootable<TileEntityChest> implements Chest
}
getTileEntity().openersCounter.opened = false;
}
@Override
public CraftChest copy() {
return new CraftChest(this);
}
}

View File

@ -17,6 +17,10 @@ public class CraftChiseledBookshelf extends CraftBlockEntityState<ChiseledBookSh
super(world, tileEntity);
}
protected CraftChiseledBookshelf(CraftChiseledBookshelf state) {
super(state);
}
@Override
public int getLastInteractedSlot() {
return getSnapshot().getLastInteractedSlot();
@ -67,4 +71,9 @@ public class CraftChiseledBookshelf extends CraftBlockEntityState<ChiseledBookSh
return ChiseledBookShelfBlock.getHitSlot(faceVector);
}
@Override
public CraftChiseledBookshelf copy() {
return new CraftChiseledBookshelf(this);
}
}

View File

@ -11,6 +11,10 @@ public class CraftCommandBlock extends CraftBlockEntityState<TileEntityCommand>
super(world, tileEntity);
}
protected CraftCommandBlock(CraftCommandBlock state) {
super(state);
}
@Override
public String getCommand() {
return getSnapshot().getCommandBlock().getCommand();
@ -30,4 +34,9 @@ public class CraftCommandBlock extends CraftBlockEntityState<TileEntityCommand>
public void setName(String name) {
getSnapshot().getCommandBlock().setName(CraftChatMessage.fromStringOrNull(name != null ? name : "@"));
}
@Override
public CraftCommandBlock copy() {
return new CraftCommandBlock(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftComparator extends CraftBlockEntityState<TileEntityComparator>
public CraftComparator(World world, TileEntityComparator tileEntity) {
super(world, tileEntity);
}
protected CraftComparator(CraftComparator state) {
super(state);
}
@Override
public CraftComparator copy() {
return new CraftComparator(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftConduit extends CraftBlockEntityState<TileEntityConduit> imple
public CraftConduit(World world, TileEntityConduit tileEntity) {
super(world, tileEntity);
}
protected CraftConduit(CraftConduit state) {
super(state);
}
@Override
public CraftConduit copy() {
return new CraftConduit(this);
}
}

View File

@ -12,6 +12,10 @@ public abstract class CraftContainer<T extends TileEntityContainer> extends Craf
super(world, tileEntity);
}
protected CraftContainer(CraftContainer<T> state) {
super(state);
}
@Override
public boolean isLocked() {
return !this.getSnapshot().lockKey.key.isEmpty();
@ -46,4 +50,7 @@ public abstract class CraftContainer<T extends TileEntityContainer> extends Craf
container.setCustomName(null);
}
}
@Override
public abstract CraftContainer<T> copy();
}

View File

@ -18,6 +18,10 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<TileEntityMobSpa
super(world, tileEntity);
}
protected CraftCreatureSpawner(CraftCreatureSpawner state) {
super(state);
}
@Override
public EntityType getSpawnedType() {
MobSpawnerData spawnData = this.getSnapshot().getSpawner().nextSpawnData;
@ -136,4 +140,9 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<TileEntityMobSpa
public void setSpawnRange(int spawnRange) {
this.getSnapshot().getSpawner().spawnRange = spawnRange;
}
@Override
public CraftCreatureSpawner copy() {
return new CraftCreatureSpawner(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftDaylightDetector extends CraftBlockEntityState<TileEntityLight
public CraftDaylightDetector(World world, TileEntityLightDetector tileEntity) {
super(world, tileEntity);
}
protected CraftDaylightDetector(CraftDaylightDetector state) {
super(state);
}
@Override
public CraftDaylightDetector copy() {
return new CraftDaylightDetector(this);
}
}

View File

@ -20,6 +20,10 @@ public class CraftDecoratedPot extends CraftBlockEntityState<DecoratedPotBlockEn
super(world, tileEntity);
}
protected CraftDecoratedPot(CraftDecoratedPot state) {
super(state);
}
@Override
public void setSherd(Side face, Material sherd) {
Preconditions.checkArgument(face != null, "face must not be null");
@ -69,4 +73,9 @@ public class CraftDecoratedPot extends CraftBlockEntityState<DecoratedPotBlockEn
public List<Material> getShards() {
return getSnapshot().getDecorations().sorted().map(CraftMagicNumbers::getMaterial).collect(Collectors.toUnmodifiableList());
}
@Override
public CraftDecoratedPot copy() {
return new CraftDecoratedPot(this);
}
}

View File

@ -19,6 +19,10 @@ public class CraftDispenser extends CraftLootable<TileEntityDispenser> implement
super(world, tileEntity);
}
protected CraftDispenser(CraftDispenser state) {
super(state);
}
@Override
public Inventory getSnapshotInventory() {
return new CraftInventory(this.getSnapshot());
@ -58,4 +62,9 @@ public class CraftDispenser extends CraftLootable<TileEntityDispenser> implement
return false;
}
}
@Override
public CraftDispenser copy() {
return new CraftDispenser(this);
}
}

View File

@ -17,6 +17,10 @@ public class CraftDropper extends CraftLootable<TileEntityDropper> implements Dr
super(world, tileEntity);
}
protected CraftDropper(CraftDropper state) {
super(state);
}
@Override
public Inventory getSnapshotInventory() {
return new CraftInventory(this.getSnapshot());
@ -42,4 +46,9 @@ public class CraftDropper extends CraftLootable<TileEntityDropper> implements Dr
drop.dispenseFrom(world.getHandle(), this.getHandle(), this.getPosition());
}
}
@Override
public CraftDropper copy() {
return new CraftDropper(this);
}
}

View File

@ -11,6 +11,10 @@ public class CraftEnchantingTable extends CraftBlockEntityState<TileEntityEnchan
super(world, tileEntity);
}
protected CraftEnchantingTable(CraftEnchantingTable state) {
super(state);
}
@Override
public String getCustomName() {
TileEntityEnchantTable enchant = this.getSnapshot();
@ -30,4 +34,9 @@ public class CraftEnchantingTable extends CraftBlockEntityState<TileEntityEnchan
enchantingTable.setCustomName(null);
}
}
@Override
public CraftEnchantingTable copy() {
return new CraftEnchantingTable(this);
}
}

View File

@ -14,6 +14,10 @@ public class CraftEndGateway extends CraftBlockEntityState<TileEntityEndGateway>
super(world, tileEntity);
}
protected CraftEndGateway(CraftEndGateway state) {
super(state);
}
@Override
public Location getExitLocation() {
BlockPosition pos = this.getSnapshot().exitPortal;
@ -59,4 +63,9 @@ public class CraftEndGateway extends CraftBlockEntityState<TileEntityEndGateway>
endGateway.exitPortal = null;
}
}
@Override
public CraftEndGateway copy() {
return new CraftEndGateway(this);
}
}

View File

@ -8,4 +8,13 @@ public class CraftEndPortal extends CraftBlockEntityState<TileEntityEnderPortal>
public CraftEndPortal(World world, TileEntityEnderPortal tileEntity) {
super(world, tileEntity);
}
protected CraftEndPortal(CraftEndPortal state) {
super(state);
}
@Override
public CraftEndPortal copy() {
return new CraftEndPortal(this);
}
}

View File

@ -11,6 +11,10 @@ public class CraftEnderChest extends CraftBlockEntityState<TileEntityEnderChest>
super(world, tileEntity);
}
protected CraftEnderChest(CraftEnderChest state) {
super(state);
}
@Override
public void open() {
requirePlaced();
@ -36,4 +40,9 @@ public class CraftEnderChest extends CraftBlockEntityState<TileEntityEnderChest>
}
getTileEntity().openersCounter.opened = false;
}
@Override
public CraftEnderChest copy() {
return new CraftEnderChest(this);
}
}

View File

@ -20,6 +20,10 @@ public abstract class CraftFurnace<T extends TileEntityFurnace> extends CraftCon
super(world, tileEntity);
}
protected CraftFurnace(CraftFurnace<T> state) {
super(state);
}
@Override
public FurnaceInventory getSnapshotInventory() {
return new CraftInventoryFurnace(this.getSnapshot());
@ -78,4 +82,7 @@ public abstract class CraftFurnace<T extends TileEntityFurnace> extends CraftCon
return recipesUsed.build();
}
@Override
public abstract CraftFurnace<T> copy();
}

View File

@ -8,4 +8,13 @@ public class CraftFurnaceFurnace extends CraftFurnace<TileEntityFurnaceFurnace>
public CraftFurnaceFurnace(World world, TileEntityFurnaceFurnace tileEntity) {
super(world, tileEntity);
}
protected CraftFurnaceFurnace(CraftFurnaceFurnace state) {
super(state);
}
@Override
public CraftFurnaceFurnace copy() {
return new CraftFurnaceFurnace(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftHangingSign extends CraftSign<HangingSignBlockEntity> implemen
public CraftHangingSign(World world, HangingSignBlockEntity tileEntity) {
super(world, tileEntity);
}
protected CraftHangingSign(CraftHangingSign state) {
super(state);
}
@Override
public CraftHangingSign copy() {
return new CraftHangingSign(this);
}
}

View File

@ -12,6 +12,10 @@ public class CraftHopper extends CraftLootable<TileEntityHopper> implements Hopp
super(world, tileEntity);
}
protected CraftHopper(CraftHopper state) {
super(state);
}
@Override
public Inventory getSnapshotInventory() {
return new CraftInventory(this.getSnapshot());
@ -25,4 +29,9 @@ public class CraftHopper extends CraftLootable<TileEntityHopper> implements Hopp
return new CraftInventory(this.getTileEntity());
}
@Override
public CraftHopper copy() {
return new CraftHopper(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftJigsaw extends CraftBlockEntityState<TileEntityJigsaw> impleme
public CraftJigsaw(World world, TileEntityJigsaw tileEntity) {
super(world, tileEntity);
}
protected CraftJigsaw(CraftJigsaw state) {
super(state);
}
@Override
public CraftJigsaw copy() {
return new CraftJigsaw(this);
}
}

View File

@ -20,6 +20,10 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
super(world, tileEntity);
}
protected CraftJukebox(CraftJukebox state) {
super(state);
}
@Override
public JukeboxInventory getSnapshotInventory() {
return new CraftInventoryJukebox(this.getSnapshot());
@ -147,4 +151,9 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
jukebox.popOutRecord();
return result;
}
@Override
public CraftJukebox copy() {
return new CraftJukebox(this);
}
}

View File

@ -14,6 +14,10 @@ public class CraftLectern extends CraftBlockEntityState<TileEntityLectern> imple
super(world, tileEntity);
}
protected CraftLectern(CraftLectern state) {
super(state);
}
@Override
public int getPage() {
return getSnapshot().getPage();
@ -48,4 +52,9 @@ public class CraftLectern extends CraftBlockEntityState<TileEntityLectern> imple
return result;
}
@Override
public CraftLectern copy() {
return new CraftLectern(this);
}
}

View File

@ -15,6 +15,10 @@ public abstract class CraftLootable<T extends TileEntityLootable> extends CraftC
super(world, tileEntity);
}
protected CraftLootable(CraftLootable<T> state) {
super(state);
}
@Override
public void applyTo(T lootable) {
super.applyTo(lootable);
@ -53,4 +57,7 @@ public abstract class CraftLootable<T extends TileEntityLootable> extends CraftC
MinecraftKey key = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
getSnapshot().setLootTable(key, seed);
}
@Override
public abstract CraftLootable<T> copy();
}

View File

@ -8,4 +8,13 @@ public class CraftMovingPiston extends CraftBlockEntityState<TileEntityPiston> {
public CraftMovingPiston(World world, TileEntityPiston tileEntity) {
super(world, tileEntity);
}
protected CraftMovingPiston(CraftMovingPiston state) {
super(state);
}
@Override
public CraftMovingPiston copy() {
return new CraftMovingPiston(this);
}
}

View File

@ -13,6 +13,10 @@ public class CraftSculkCatalyst extends CraftBlockEntityState<SculkCatalystBlock
super(world, tileEntity);
}
protected CraftSculkCatalyst(CraftSculkCatalyst state) {
super(state);
}
@Override
public void bloom(Block block, int charge) {
Preconditions.checkArgument(block != null, "block cannot be null");
@ -23,4 +27,9 @@ public class CraftSculkCatalyst extends CraftBlockEntityState<SculkCatalystBlock
getTileEntity().getListener().bloom(world.getHandle(), getPosition(), getHandle(), world.getHandle().getRandom());
getTileEntity().getListener().getSculkSpreader().addCursors(new BlockPosition(block.getX(), block.getY(), block.getZ()), charge);
}
@Override
public CraftSculkCatalyst copy() {
return new CraftSculkCatalyst(this);
}
}

View File

@ -11,6 +11,10 @@ public class CraftSculkSensor<T extends SculkSensorBlockEntity> extends CraftBlo
super(world, tileEntity);
}
protected CraftSculkSensor(CraftSculkSensor<T> state) {
super(state);
}
@Override
public int getLastVibrationFrequency() {
return getSnapshot().getLastVibrationFrequency();
@ -21,4 +25,9 @@ public class CraftSculkSensor<T extends SculkSensorBlockEntity> extends CraftBlo
Preconditions.checkArgument(0 <= lastVibrationFrequency && lastVibrationFrequency <= 15, "Vibration frequency must be between 0-15");
getSnapshot().lastVibrationFrequency = lastVibrationFrequency;
}
@Override
public CraftSculkSensor<T> copy() {
return new CraftSculkSensor<>(this);
}
}

View File

@ -13,6 +13,10 @@ public class CraftSculkShrieker extends CraftBlockEntityState<SculkShriekerBlock
super(world, tileEntity);
}
protected CraftSculkShrieker(CraftSculkShrieker state) {
super(state);
}
@Override
public int getWarningLevel() {
return getSnapshot().warningLevel;
@ -30,4 +34,9 @@ public class CraftSculkShrieker extends CraftBlockEntityState<SculkShriekerBlock
EntityPlayer entityPlayer = (player == null) ? null : ((CraftPlayer) player).getHandle();
getTileEntity().tryShriek(world.getHandle(), entityPlayer);
}
@Override
public CraftSculkShrieker copy() {
return new CraftSculkShrieker(this);
}
}

View File

@ -18,6 +18,10 @@ public class CraftShulkerBox extends CraftLootable<TileEntityShulkerBox> impleme
super(world, tileEntity);
}
protected CraftShulkerBox(CraftShulkerBox state) {
super(state);
}
@Override
public Inventory getSnapshotInventory() {
return new CraftInventory(this.getSnapshot());
@ -60,4 +64,9 @@ public class CraftShulkerBox extends CraftLootable<TileEntityShulkerBox> impleme
}
getTileEntity().opened = false;
}
@Override
public CraftShulkerBox copy() {
return new CraftShulkerBox(this);
}
}

View File

@ -27,6 +27,12 @@ public class CraftSign<T extends TileEntitySign> extends CraftBlockEntityState<T
this.back = new CraftSignSide(this.getSnapshot().getBackText());
}
protected CraftSign(CraftSign<T> state) {
super(state);
this.front = new CraftSignSide(this.getSnapshot().getFrontText());
this.back = new CraftSignSide(this.getSnapshot().getBackText());
}
@Override
public String[] getLines() {
return front.getLines();
@ -105,6 +111,11 @@ public class CraftSign<T extends TileEntitySign> extends CraftBlockEntityState<T
super.applyTo(sign);
}
@Override
public CraftSign<T> copy() {
return new CraftSign<T>(this);
}
public static void openSign(Sign sign, Player player, Side side) {
Preconditions.checkArgument(sign != null, "sign == null");
Preconditions.checkArgument(side != null, "side == null");

View File

@ -31,6 +31,10 @@ public class CraftSkull extends CraftBlockEntityState<TileEntitySkull> implement
super(world, tileEntity);
}
protected CraftSkull(CraftSkull state) {
super(state);
}
@Override
public void load(TileEntitySkull skull) {
super.load(skull);
@ -199,4 +203,9 @@ public class CraftSkull extends CraftBlockEntityState<TileEntitySkull> implement
skull.setOwner(profile);
}
}
@Override
public CraftSkull copy() {
return new CraftSkull(this);
}
}

View File

@ -9,4 +9,13 @@ public class CraftSmoker extends CraftFurnace<TileEntitySmoker> implements Smoke
public CraftSmoker(World world, TileEntitySmoker tileEntity) {
super(world, tileEntity);
}
protected CraftSmoker(CraftSmoker state) {
super(state);
}
@Override
public CraftSmoker copy() {
return new CraftSmoker(this);
}
}

View File

@ -23,6 +23,10 @@ public class CraftStructureBlock extends CraftBlockEntityState<TileEntityStructu
super(world, tileEntity);
}
protected CraftStructureBlock(CraftStructureBlock state) {
super(state);
}
@Override
public String getStructureName() {
return getSnapshot().getStructureName();
@ -193,6 +197,11 @@ public class CraftStructureBlock extends CraftBlockEntityState<TileEntityStructu
}
}
@Override
public CraftStructureBlock copy() {
return new CraftStructureBlock(this);
}
private static boolean isBetween(int num, int min, int max) {
return num >= min && num <= max;
}

View File

@ -9,4 +9,13 @@ public class CraftSuspiciousSand extends CraftBrushableBlock implements Suspicio
public CraftSuspiciousSand(World world, BrushableBlockEntity tileEntity) {
super(world, tileEntity);
}
protected CraftSuspiciousSand(CraftSuspiciousSand state) {
super(state);
}
@Override
public CraftSuspiciousSand copy() {
return new CraftSuspiciousSand(this);
}
}

View File

@ -0,0 +1,125 @@
package org.bukkit.craftbukkit.util;
import java.util.Objects;
import net.minecraft.core.BlockPosition;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkCoordIntPair;
import net.minecraft.world.level.GeneratorAccessSeed;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.StructureBoundingBox;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.block.CraftBlockState;
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.generator.CraftLimitedRegion;
import org.bukkit.craftbukkit.generator.structure.CraftStructure;
import org.bukkit.event.world.AsyncStructureGenerateEvent;
import org.bukkit.event.world.AsyncStructureGenerateEvent.Cause;
import org.bukkit.util.BlockTransformer;
import org.bukkit.util.BlockTransformer.TransformationState;
import org.bukkit.util.EntityTransformer;
public class CraftStructureTransformer {
private static class CraftTransformationState implements TransformationState {
private final BlockState original;
private final BlockState world;
private BlockState originalCopy;
private BlockState worldCopy;
private CraftTransformationState(BlockState original, BlockState world) {
this.original = original;
this.world = world;
}
@Override
public BlockState getOriginal() {
if (originalCopy != null) {
return originalCopy;
}
return originalCopy = original.copy();
}
@Override
public BlockState getWorld() {
if (worldCopy != null) {
return worldCopy;
}
return worldCopy = world.copy();
}
private void destroyCopies() {
originalCopy = null;
worldCopy = null;
}
}
private CraftLimitedRegion limitedRegion;
private BlockTransformer[] blockTransformers;
private EntityTransformer[] entityTransformers;
public CraftStructureTransformer(Cause cause, GeneratorAccessSeed generatoraccessseed, StructureManager structuremanager, Structure structure, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) {
AsyncStructureGenerateEvent event = new AsyncStructureGenerateEvent(structuremanager.level.getMinecraftWorld().getWorld(), !Bukkit.isPrimaryThread(), cause, CraftStructure.minecraftToBukkit(structure, structuremanager.registryAccess()), new org.bukkit.util.BoundingBox(structureboundingbox.minX(), structureboundingbox.minY(), structureboundingbox.minZ(), structureboundingbox.maxX(), structureboundingbox.maxY(), structureboundingbox.maxZ()), chunkcoordintpair.x, chunkcoordintpair.z);
Bukkit.getPluginManager().callEvent(event);
this.blockTransformers = event.getBlockTransformers().values().toArray(BlockTransformer[]::new);
this.entityTransformers = event.getEntityTransformers().values().toArray(EntityTransformer[]::new);
this.limitedRegion = new CraftLimitedRegion(generatoraccessseed, chunkcoordintpair);
}
public boolean transformEntity(Entity entity) {
EntityTransformer[] transformers = entityTransformers;
if (transformers == null || transformers.length == 0) {
return true;
}
CraftLimitedRegion region = limitedRegion;
if (region == null) {
return true;
}
entity.generation = true;
CraftEntity craftEntity = entity.getBukkitEntity();
int x = entity.getBlockX();
int y = entity.getBlockY();
int z = entity.getBlockZ();
boolean allowedToSpawn = true;
for (EntityTransformer transformer : transformers) {
allowedToSpawn = transformer.transform(region, x, y, z, craftEntity, allowedToSpawn);
}
return allowedToSpawn;
}
public boolean canTransformBlocks() {
return blockTransformers != null && blockTransformers.length != 0 && limitedRegion != null;
}
public CraftBlockState transformCraftState(CraftBlockState originalState) {
BlockTransformer[] transformers = blockTransformers;
if (transformers == null || transformers.length == 0) {
return originalState;
}
CraftLimitedRegion region = limitedRegion;
if (region == null) {
return originalState;
}
originalState.setWorldHandle(region.getHandle());
BlockPosition position = originalState.getPosition();
BlockState blockState = originalState.copy();
CraftTransformationState transformationState = new CraftTransformationState(originalState, region.getBlockState(position.getX(), position.getY(), position.getZ()));
for (BlockTransformer transformer : transformers) {
blockState = Objects.requireNonNull(transformer.transform(region, position.getX(), position.getY(), position.getZ(), blockState, transformationState), "BlockState can't be null");
transformationState.destroyCopies();
}
return (CraftBlockState) blockState;
}
public void discard() {
limitedRegion.saveEntities();
limitedRegion.breakLink();
this.limitedRegion = null;
this.blockTransformers = null;
this.entityTransformers = null;
}
}

View File

@ -0,0 +1,821 @@
package org.bukkit.craftbukkit.util;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.EnumDirection;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.IRegistry;
import net.minecraft.core.IRegistryCustom;
import net.minecraft.core.particles.ParticleParam;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.WorldServer;
import net.minecraft.sounds.SoundCategory;
import net.minecraft.sounds.SoundEffect;
import net.minecraft.util.RandomSource;
import net.minecraft.world.DifficultyDamageScaler;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityLiving;
import net.minecraft.world.entity.ai.targeting.PathfinderTargetCondition;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.level.ClipBlockStateContext;
import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.EnumSkyBlock;
import net.minecraft.world.level.GeneratorAccessSeed;
import net.minecraft.world.level.IBlockAccess;
import net.minecraft.world.level.RayTrace;
import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.TileEntity;
import net.minecraft.world.level.block.entity.TileEntityTypes;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.IChunkAccess;
import net.minecraft.world.level.chunk.IChunkProvider;
import net.minecraft.world.level.dimension.DimensionManager;
import net.minecraft.world.level.entity.EntityTypeTest;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.levelgen.HeightMap;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidType;
import net.minecraft.world.level.storage.WorldData;
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.MovingObjectPositionBlock;
import net.minecraft.world.phys.Vec3D;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.phys.shapes.VoxelShapeCollision;
import net.minecraft.world.ticks.LevelTickAccess;
import net.minecraft.world.ticks.NextTickListEntry;
import net.minecraft.world.ticks.TickListPriority;
import org.bukkit.event.entity.CreatureSpawnEvent;
public abstract class DelegatedGeneratorAccess implements GeneratorAccessSeed {
private GeneratorAccessSeed handle;
public void setHandle(GeneratorAccessSeed worldAccess) {
this.handle = worldAccess;
}
public GeneratorAccessSeed getHandle() {
return handle;
}
@Override
public long getSeed() {
return handle.getSeed();
}
@Override
public void setCurrentlyGenerating(Supplier<String> arg0) {
handle.setCurrentlyGenerating(arg0);
}
@Override
public boolean ensureCanWrite(BlockPosition arg0) {
return handle.ensureCanWrite(arg0);
}
@Override
public WorldServer getLevel() {
return handle.getLevel();
}
@Override
public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
handle.addFreshEntityWithPassengers(arg0, arg1);
}
@Override
public void addFreshEntityWithPassengers(Entity arg0) {
handle.addFreshEntityWithPassengers(arg0);
}
@Override
public WorldServer getMinecraftWorld() {
return handle.getMinecraftWorld();
}
@Override
public DifficultyDamageScaler getCurrentDifficultyAt(BlockPosition arg0) {
return handle.getCurrentDifficultyAt(arg0);
}
@Override
public void neighborShapeChanged(EnumDirection arg0, IBlockData arg1, BlockPosition arg2, BlockPosition arg3, int arg4, int arg5) {
handle.neighborShapeChanged(arg0, arg1, arg2, arg3, arg4, arg5);
}
@Override
public long dayTime() {
return handle.dayTime();
}
@Override
public WorldData getLevelData() {
return handle.getLevelData();
}
@Override
public boolean hasChunk(int arg0, int arg1) {
return handle.hasChunk(arg0, arg1);
}
@Override
public IChunkProvider getChunkSource() {
return handle.getChunkSource();
}
@Override
public void scheduleTick(BlockPosition arg0, Block arg1, int arg2, TickListPriority arg3) {
handle.scheduleTick(arg0, arg1, arg2, arg3);
}
@Override
public void scheduleTick(BlockPosition arg0, Block arg1, int arg2) {
handle.scheduleTick(arg0, arg1, arg2);
}
@Override
public void scheduleTick(BlockPosition arg0, FluidType arg1, int arg2, TickListPriority arg3) {
handle.scheduleTick(arg0, arg1, arg2, arg3);
}
@Override
public void scheduleTick(BlockPosition arg0, FluidType arg1, int arg2) {
handle.scheduleTick(arg0, arg1, arg2);
}
@Override
public EnumDifficulty getDifficulty() {
return handle.getDifficulty();
}
@Override
public void blockUpdated(BlockPosition arg0, Block arg1) {
handle.blockUpdated(arg0, arg1);
}
@Override
public MinecraftServer getServer() {
return handle.getServer();
}
@Override
public RandomSource getRandom() {
return handle.getRandom();
}
@Override
public LevelTickAccess<Block> getBlockTicks() {
return handle.getBlockTicks();
}
@Override
public long nextSubTickCount() {
return handle.nextSubTickCount();
}
@Override
public <T> NextTickListEntry<T> createTick(BlockPosition arg0, T arg1, int arg2) {
return handle.createTick(arg0, arg1, arg2);
}
@Override
public <T> NextTickListEntry<T> createTick(BlockPosition arg0, T arg1, int arg2, TickListPriority arg3) {
return handle.createTick(arg0, arg1, arg2, arg3);
}
@Override
public LevelTickAccess<FluidType> getFluidTicks() {
return handle.getFluidTicks();
}
@Override
public void playSound(EntityHuman arg0, BlockPosition arg1, SoundEffect arg2, SoundCategory arg3) {
handle.playSound(arg0, arg1, arg2, arg3);
}
@Override
public void playSound(EntityHuman arg0, BlockPosition arg1, SoundEffect arg2, SoundCategory arg3, float arg4, float arg5) {
handle.playSound(arg0, arg1, arg2, arg3, arg4, arg5);
}
@Override
public void levelEvent(int arg0, BlockPosition arg1, int arg2) {
handle.levelEvent(arg0, arg1, arg2);
}
@Override
public void levelEvent(EntityHuman arg0, int arg1, BlockPosition arg2, int arg3) {
handle.levelEvent(arg0, arg1, arg2, arg3);
}
@Override
public void addParticle(ParticleParam arg0, double arg1, double arg2, double arg3, double arg4, double arg5, double arg6) {
handle.addParticle(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
@Override
public void gameEvent(GameEvent arg0, Vec3D arg1, GameEvent.a arg2) {
handle.gameEvent(arg0, arg1, arg2);
}
@Override
public void gameEvent(GameEvent arg0, BlockPosition arg1, GameEvent.a arg2) {
handle.gameEvent(arg0, arg1, arg2);
}
@Override
public void gameEvent(Entity arg0, GameEvent arg1, BlockPosition arg2) {
handle.gameEvent(arg0, arg1, arg2);
}
@Override
public void gameEvent(Entity arg0, GameEvent arg1, Vec3D arg2) {
handle.gameEvent(arg0, arg1, arg2);
}
@Override
public List<VoxelShape> getEntityCollisions(Entity arg0, AxisAlignedBB arg1) {
return handle.getEntityCollisions(arg0, arg1);
}
@Override
public <T extends TileEntity> Optional<T> getBlockEntity(BlockPosition arg0, TileEntityTypes<T> arg1) {
return handle.getBlockEntity(arg0, arg1);
}
@Override
public BlockPosition getHeightmapPos(HeightMap.Type arg0, BlockPosition arg1) {
return handle.getHeightmapPos(arg0, arg1);
}
@Override
public boolean isUnobstructed(Entity arg0, VoxelShape arg1) {
return handle.isUnobstructed(arg0, arg1);
}
@Override
public boolean hasNearbyAlivePlayer(double arg0, double arg1, double arg2, double arg3) {
return handle.hasNearbyAlivePlayer(arg0, arg1, arg2, arg3);
}
@Override
public List<? extends EntityHuman> players() {
return handle.players();
}
@Override
public List<Entity> getEntities(Entity arg0, AxisAlignedBB arg1, Predicate<? super Entity> arg2) {
return handle.getEntities(arg0, arg1, arg2);
}
@Override
public <T extends Entity> List<T> getEntities(EntityTypeTest<Entity, T> arg0, AxisAlignedBB arg1, Predicate<? super T> arg2) {
return handle.getEntities(arg0, arg1, arg2);
}
@Override
public List<Entity> getEntities(Entity arg0, AxisAlignedBB arg1) {
return handle.getEntities(arg0, arg1);
}
@Override
public <T extends Entity> List<T> getEntitiesOfClass(Class<T> arg0, AxisAlignedBB arg1) {
return handle.getEntitiesOfClass(arg0, arg1);
}
@Override
public <T extends Entity> List<T> getEntitiesOfClass(Class<T> arg0, AxisAlignedBB arg1, Predicate<? super T> arg2) {
return handle.getEntitiesOfClass(arg0, arg1, arg2);
}
@Override
public EntityHuman getNearestPlayer(PathfinderTargetCondition arg0, EntityLiving arg1, double arg2, double arg3, double arg4) {
return handle.getNearestPlayer(arg0, arg1, arg2, arg3, arg4);
}
@Override
public EntityHuman getNearestPlayer(PathfinderTargetCondition arg0, double arg1, double arg2, double arg3) {
return handle.getNearestPlayer(arg0, arg1, arg2, arg3);
}
@Override
public EntityHuman getNearestPlayer(Entity arg0, double arg1) {
return handle.getNearestPlayer(arg0, arg1);
}
@Override
public EntityHuman getNearestPlayer(double arg0, double arg1, double arg2, double arg3, Predicate<Entity> arg4) {
return handle.getNearestPlayer(arg0, arg1, arg2, arg3, arg4);
}
@Override
public EntityHuman getNearestPlayer(double arg0, double arg1, double arg2, double arg3, boolean arg4) {
return handle.getNearestPlayer(arg0, arg1, arg2, arg3, arg4);
}
@Override
public EntityHuman getNearestPlayer(PathfinderTargetCondition arg0, EntityLiving arg1) {
return handle.getNearestPlayer(arg0, arg1);
}
@Override
public <T extends EntityLiving> T getNearestEntity(Class<? extends T> arg0, PathfinderTargetCondition arg1, EntityLiving arg2, double arg3, double arg4, double arg5, AxisAlignedBB arg6) {
return handle.getNearestEntity(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
@Override
public <T extends EntityLiving> T getNearestEntity(List<? extends T> arg0, PathfinderTargetCondition arg1, EntityLiving arg2, double arg3, double arg4, double arg5) {
return handle.getNearestEntity(arg0, arg1, arg2, arg3, arg4, arg5);
}
@Override
public EntityHuman getPlayerByUUID(UUID arg0) {
return handle.getPlayerByUUID(arg0);
}
@Override
public List<EntityHuman> getNearbyPlayers(PathfinderTargetCondition arg0, EntityLiving arg1, AxisAlignedBB arg2) {
return handle.getNearbyPlayers(arg0, arg1, arg2);
}
@Override
public <T extends EntityLiving> List<T> getNearbyEntities(Class<T> arg0, PathfinderTargetCondition arg1, EntityLiving arg2, AxisAlignedBB arg3) {
return handle.getNearbyEntities(arg0, arg1, arg2, arg3);
}
@Override
@Deprecated
public float getLightLevelDependentMagicValue(BlockPosition arg0) {
return handle.getLightLevelDependentMagicValue(arg0);
}
@Override
public IBlockAccess getChunkForCollisions(int arg0, int arg1) {
return handle.getChunkForCollisions(arg0, arg1);
}
@Override
public int getMaxLocalRawBrightness(BlockPosition arg0) {
return handle.getMaxLocalRawBrightness(arg0);
}
@Override
public int getMaxLocalRawBrightness(BlockPosition arg0, int arg1) {
return handle.getMaxLocalRawBrightness(arg0, arg1);
}
@Override
public boolean canSeeSkyFromBelowWater(BlockPosition arg0) {
return handle.canSeeSkyFromBelowWater(arg0);
}
@Override
public float getPathfindingCostFromLightLevels(BlockPosition arg0) {
return handle.getPathfindingCostFromLightLevels(arg0);
}
@Override
public Stream<IBlockData> getBlockStatesIfLoaded(AxisAlignedBB arg0) {
return handle.getBlockStatesIfLoaded(arg0);
}
@Override
public Holder<BiomeBase> getUncachedNoiseBiome(int arg0, int arg1, int arg2) {
return handle.getUncachedNoiseBiome(arg0, arg1, arg2);
}
@Override
@Deprecated
public int getSeaLevel() {
return handle.getSeaLevel();
}
@Override
public boolean containsAnyLiquid(AxisAlignedBB arg0) {
return handle.containsAnyLiquid(arg0);
}
@Override
public int getMinBuildHeight() {
return handle.getMinBuildHeight();
}
@Override
public boolean isWaterAt(BlockPosition arg0) {
return handle.isWaterAt(arg0);
}
@Override
public boolean isEmptyBlock(BlockPosition arg0) {
return handle.isEmptyBlock(arg0);
}
@Override
public boolean isClientSide() {
return handle.isClientSide();
}
@Override
public DimensionManager dimensionType() {
return handle.dimensionType();
}
@Override
public FeatureFlagSet enabledFeatures() {
return handle.enabledFeatures();
}
@Override
@Deprecated
public boolean hasChunkAt(int arg0, int arg1) {
return handle.hasChunkAt(arg0, arg1);
}
@Override
@Deprecated
public boolean hasChunkAt(BlockPosition arg0) {
return handle.hasChunkAt(arg0);
}
@Override
public <T> HolderLookup<T> holderLookup(ResourceKey<? extends IRegistry<? extends T>> arg0) {
return handle.holderLookup(arg0);
}
@Override
public IRegistryCustom registryAccess() {
return handle.registryAccess();
}
@Override
public Holder<BiomeBase> getNoiseBiome(int arg0, int arg1, int arg2) {
return handle.getNoiseBiome(arg0, arg1, arg2);
}
@Override
public int getBlockTint(BlockPosition arg0, ColorResolver arg1) {
return handle.getBlockTint(arg0, arg1);
}
@Override
@Deprecated
public boolean hasChunksAt(BlockPosition arg0, BlockPosition arg1) {
return handle.hasChunksAt(arg0, arg1);
}
@Override
@Deprecated
public boolean hasChunksAt(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5) {
return handle.hasChunksAt(arg0, arg1, arg2, arg3, arg4, arg5);
}
@Override
@Deprecated
public boolean hasChunksAt(int arg0, int arg1, int arg2, int arg3) {
return handle.hasChunksAt(arg0, arg1, arg2, arg3);
}
@Override
public IChunkAccess getChunk(int arg0, int arg1, ChunkStatus arg2, boolean arg3) {
return handle.getChunk(arg0, arg1, arg2, arg3);
}
@Override
public IChunkAccess getChunk(int arg0, int arg1, ChunkStatus arg2) {
return handle.getChunk(arg0, arg1, arg2);
}
@Override
public IChunkAccess getChunk(BlockPosition arg0) {
return handle.getChunk(arg0);
}
@Override
public IChunkAccess getChunk(int arg0, int arg1) {
return handle.getChunk(arg0, arg1);
}
@Override
public int getHeight(HeightMap.Type arg0, int arg1, int arg2) {
return handle.getHeight(arg0, arg1, arg2);
}
@Override
public int getHeight() {
return handle.getHeight();
}
@Override
public Holder<BiomeBase> getBiome(BlockPosition arg0) {
return handle.getBiome(arg0);
}
@Override
public int getSkyDarken() {
return handle.getSkyDarken();
}
@Override
public BiomeManager getBiomeManager() {
return handle.getBiomeManager();
}
@Override
public boolean canSeeSky(BlockPosition arg0) {
return handle.canSeeSky(arg0);
}
@Override
public int getRawBrightness(BlockPosition arg0, int arg1) {
return handle.getRawBrightness(arg0, arg1);
}
@Override
public LevelLightEngine getLightEngine() {
return handle.getLightEngine();
}
@Override
public int getBrightness(EnumSkyBlock arg0, BlockPosition arg1) {
return handle.getBrightness(arg0, arg1);
}
@Override
public float getShade(EnumDirection arg0, boolean arg1) {
return handle.getShade(arg0, arg1);
}
@Override
public TileEntity getBlockEntity(BlockPosition arg0) {
return handle.getBlockEntity(arg0);
}
@Override
public double getBlockFloorHeight(VoxelShape arg0, Supplier<VoxelShape> arg1) {
return handle.getBlockFloorHeight(arg0, arg1);
}
@Override
public double getBlockFloorHeight(BlockPosition arg0) {
return handle.getBlockFloorHeight(arg0);
}
@Override
public MovingObjectPositionBlock clipWithInteractionOverride(Vec3D arg0, Vec3D arg1, BlockPosition arg2, VoxelShape arg3, IBlockData arg4) {
return handle.clipWithInteractionOverride(arg0, arg1, arg2, arg3, arg4);
}
@Override
public IBlockData getBlockState(BlockPosition arg0) {
return handle.getBlockState(arg0);
}
@Override
public Fluid getFluidState(BlockPosition arg0) {
return handle.getFluidState(arg0);
}
@Override
public int getLightEmission(BlockPosition arg0) {
return handle.getLightEmission(arg0);
}
@Override
public MovingObjectPositionBlock clip(RayTrace arg0) {
return handle.clip(arg0);
}
@Override
public MovingObjectPositionBlock clip(RayTrace arg0, BlockPosition arg1) {
return handle.clip(arg0, arg1);
}
@Override
public int getMaxLightLevel() {
return handle.getMaxLightLevel();
}
@Override
public MovingObjectPositionBlock isBlockInLine(ClipBlockStateContext arg0) {
return handle.isBlockInLine(arg0);
}
@Override
public Stream<IBlockData> getBlockStates(AxisAlignedBB arg0) {
return handle.getBlockStates(arg0);
}
@Override
public boolean isOutsideBuildHeight(int arg0) {
return handle.isOutsideBuildHeight(arg0);
}
@Override
public boolean isOutsideBuildHeight(BlockPosition arg0) {
return handle.isOutsideBuildHeight(arg0);
}
@Override
public int getSectionIndexFromSectionY(int arg0) {
return handle.getSectionIndexFromSectionY(arg0);
}
@Override
public int getSectionYFromSectionIndex(int arg0) {
return handle.getSectionYFromSectionIndex(arg0);
}
@Override
public int getMaxSection() {
return handle.getMaxSection();
}
@Override
public int getMinSection() {
return handle.getMinSection();
}
@Override
public int getSectionIndex(int arg0) {
return handle.getSectionIndex(arg0);
}
@Override
public int getSectionsCount() {
return handle.getSectionsCount();
}
@Override
public int getMaxBuildHeight() {
return handle.getMaxBuildHeight();
}
@Override
public boolean isUnobstructed(IBlockData arg0, BlockPosition arg1, VoxelShapeCollision arg2) {
return handle.isUnobstructed(arg0, arg1, arg2);
}
@Override
public boolean isUnobstructed(Entity arg0) {
return handle.isUnobstructed(arg0);
}
@Override
public WorldBorder getWorldBorder() {
return handle.getWorldBorder();
}
@Override
public Optional<Vec3D> findFreePosition(Entity arg0, VoxelShape arg1, Vec3D arg2, double arg3, double arg4, double arg5) {
return handle.findFreePosition(arg0, arg1, arg2, arg3, arg4, arg5);
}
@Override
public Iterable<VoxelShape> getCollisions(Entity arg0, AxisAlignedBB arg1) {
return handle.getCollisions(arg0, arg1);
}
@Override
public Iterable<VoxelShape> getBlockCollisions(Entity arg0, AxisAlignedBB arg1) {
return handle.getBlockCollisions(arg0, arg1);
}
@Override
public boolean noCollision(AxisAlignedBB arg0) {
return handle.noCollision(arg0);
}
@Override
public boolean noCollision(Entity arg0) {
return handle.noCollision(arg0);
}
@Override
public boolean noCollision(Entity arg0, AxisAlignedBB arg1) {
return handle.noCollision(arg0, arg1);
}
@Override
public boolean collidesWithSuffocatingBlock(Entity arg0, AxisAlignedBB arg1) {
return handle.collidesWithSuffocatingBlock(arg0, arg1);
}
@Override
public Optional<BlockPosition> findSupportingBlock(Entity arg0, AxisAlignedBB arg1) {
return handle.findSupportingBlock(arg0, arg1);
}
@Override
public int getBestNeighborSignal(BlockPosition arg0) {
return handle.getBestNeighborSignal(arg0);
}
@Override
public int getControlInputSignal(BlockPosition arg0, EnumDirection arg1, boolean arg2) {
return handle.getControlInputSignal(arg0, arg1, arg2);
}
@Override
public int getDirectSignal(BlockPosition arg0, EnumDirection arg1) {
return handle.getDirectSignal(arg0, arg1);
}
@Override
public int getDirectSignalTo(BlockPosition arg0) {
return handle.getDirectSignalTo(arg0);
}
@Override
public boolean hasNeighborSignal(BlockPosition arg0) {
return handle.hasNeighborSignal(arg0);
}
@Override
public boolean hasSignal(BlockPosition arg0, EnumDirection arg1) {
return handle.hasSignal(arg0, arg1);
}
@Override
public int getSignal(BlockPosition arg0, EnumDirection arg1) {
return handle.getSignal(arg0, arg1);
}
@Override
public boolean isStateAtPosition(BlockPosition arg0, Predicate<IBlockData> arg1) {
return handle.isStateAtPosition(arg0, arg1);
}
@Override
public boolean isFluidAtPosition(BlockPosition arg0, Predicate<Fluid> arg1) {
return handle.isFluidAtPosition(arg0, arg1);
}
@Override
public boolean addFreshEntity(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
return handle.addFreshEntity(arg0, arg1);
}
@Override
public boolean addFreshEntity(Entity arg0) {
return handle.addFreshEntity(arg0);
}
@Override
public boolean removeBlock(BlockPosition arg0, boolean arg1) {
return handle.removeBlock(arg0, arg1);
}
@Override
public boolean destroyBlock(BlockPosition arg0, boolean arg1, Entity arg2, int arg3) {
return handle.destroyBlock(arg0, arg1, arg2, arg3);
}
@Override
public boolean destroyBlock(BlockPosition arg0, boolean arg1, Entity arg2) {
return handle.destroyBlock(arg0, arg1, arg2);
}
@Override
public boolean destroyBlock(BlockPosition arg0, boolean arg1) {
return handle.destroyBlock(arg0, arg1);
}
@Override
public boolean setBlock(BlockPosition arg0, IBlockData arg1, int arg2) {
return handle.setBlock(arg0, arg1, arg2);
}
@Override
public boolean setBlock(BlockPosition arg0, IBlockData arg1, int arg2, int arg3) {
return handle.setBlock(arg0, arg1, arg2, arg3);
}
@Override
public float getTimeOfDay(float arg0) {
return handle.getTimeOfDay(arg0);
}
@Override
public float getMoonBrightness() {
return handle.getMoonBrightness();
}
@Override
public int getMoonPhase() {
return handle.getMoonPhase();
}
}

View File

@ -0,0 +1,96 @@
package org.bukkit.craftbukkit.util;
import net.minecraft.core.BlockPosition;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.entity.TileEntity;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.levelgen.structure.StructurePiece;
import net.minecraft.world.level.material.Fluid;
import org.bukkit.craftbukkit.block.CraftBlockEntityState;
import org.bukkit.craftbukkit.block.CraftBlockState;
import org.bukkit.craftbukkit.block.CraftBlockStates;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
public class TransformerGeneratorAccess extends DelegatedGeneratorAccess {
private CraftStructureTransformer structureTransformer;
public void setStructureTransformer(CraftStructureTransformer structureTransformer) {
this.structureTransformer = structureTransformer;
}
public CraftStructureTransformer getStructureTransformer() {
return structureTransformer;
}
@Override
public boolean addFreshEntity(Entity arg0) {
if (structureTransformer != null && !structureTransformer.transformEntity(arg0)) {
return false;
}
return super.addFreshEntity(arg0);
}
@Override
public boolean addFreshEntity(Entity arg0, SpawnReason arg1) {
if (structureTransformer != null && !structureTransformer.transformEntity(arg0)) {
return false;
}
return super.addFreshEntity(arg0, arg1);
}
@Override
public void addFreshEntityWithPassengers(Entity arg0) {
if (structureTransformer != null && !structureTransformer.transformEntity(arg0)) {
return;
}
super.addFreshEntityWithPassengers(arg0);
}
@Override
public void addFreshEntityWithPassengers(Entity arg0, SpawnReason arg1) {
if (structureTransformer != null && !structureTransformer.transformEntity(arg0)) {
return;
}
super.addFreshEntityWithPassengers(arg0, arg1);
}
public boolean setCraftBlock(BlockPosition position, CraftBlockState craftBlockState, int i, int j) {
if (structureTransformer != null) {
craftBlockState = structureTransformer.transformCraftState(craftBlockState);
}
// This code is based on the method 'net.minecraft.world.level.levelgen.structure.StructurePiece#placeBlock'
// It ensures that any kind of block is updated correctly upon placing it
IBlockData iblockdata = craftBlockState.getHandle();
boolean result = super.setBlock(position, iblockdata, i, j);
Fluid fluid = getFluidState(position);
if (!fluid.isEmpty()) {
scheduleTick(position, fluid.getType(), 0);
}
if (StructurePiece.SHAPE_CHECK_BLOCKS.contains(iblockdata.getBlock())) {
getChunk(position).markPosForPostprocessing(position);
}
TileEntity tileEntity = getBlockEntity(position);
if (tileEntity != null && craftBlockState instanceof CraftBlockEntityState<?> craftEntityState) {
tileEntity.load(craftEntityState.getSnapshotNBT());
}
return result;
}
public boolean setCraftBlock(BlockPosition position, CraftBlockState craftBlockState, int i) {
return setCraftBlock(position, craftBlockState, i, 512);
}
@Override
public boolean setBlock(BlockPosition position, IBlockData iblockdata, int i, int j) {
if (structureTransformer == null || !structureTransformer.canTransformBlocks()) {
return super.setBlock(position, iblockdata, i, j);
}
return setCraftBlock(position, (CraftBlockState) CraftBlockStates.getBlockState(position, iblockdata, null), i, j);
}
@Override
public boolean setBlock(BlockPosition position, IBlockData iblockdata, int i) {
return setBlock(position, iblockdata, i, 512);
}
}