From 1abd1736e380eca97bfa424f204fefa270c0bb57 Mon Sep 17 00:00:00 2001 From: SD Date: Sun, 20 Sep 2020 14:20:09 +0530 Subject: [PATCH] Move block entities to RelativeBlockSample Changes to be committed: new file: src/main/java/org/dimdev/dimcore/schematic/v2/RelativeBlockSample.java modified: src/main/java/org/dimdev/dimcore/schematic/v2/Schematic.java deleted: src/main/java/org/dimdev/dimcore/schematic/v2/SchematicBlockSample.java modified: src/main/java/org/dimdev/dimcore/schematic/v2/SchematicPlacer.java modified: src/main/java/org/dimdev/dimdoors/util/Codecs.java modified: src/main/java/org/dimdev/dimdoors/world/feature/ModFeatures.java --- .../schematic/v2/RelativeBlockSample.java | 134 ++++++++++++++++++ .../dimcore/schematic/v2/Schematic.java | 18 +-- .../schematic/v2/SchematicBlockSample.java | 101 ------------- .../dimcore/schematic/v2/SchematicPlacer.java | 59 +------- .../java/org/dimdev/dimdoors/util/Codecs.java | 4 +- .../dimdoors/world/feature/ModFeatures.java | 11 +- 6 files changed, 157 insertions(+), 170 deletions(-) create mode 100644 src/main/java/org/dimdev/dimcore/schematic/v2/RelativeBlockSample.java delete mode 100644 src/main/java/org/dimdev/dimcore/schematic/v2/SchematicBlockSample.java diff --git a/src/main/java/org/dimdev/dimcore/schematic/v2/RelativeBlockSample.java b/src/main/java/org/dimdev/dimcore/schematic/v2/RelativeBlockSample.java new file mode 100644 index 00000000..68f3223f --- /dev/null +++ b/src/main/java/org/dimdev/dimcore/schematic/v2/RelativeBlockSample.java @@ -0,0 +1,134 @@ +package org.dimdev.dimcore.schematic.v2; + +import java.util.Map; +import java.util.Objects; + +import io.github.boogiemonster1o1.libcbe.api.ConditionalBlockEntityProvider; +import org.jetbrains.annotations.Nullable; +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.BlockView; +import net.minecraft.world.StructureWorldAccess; + +public class RelativeBlockSample implements BlockView { + public final Schematic schematic; + private final int[][][] blockData; + private final BiMap blockPalette; + private final Map blockContainer; + private final Map blockEntityContainer; + private StructureWorldAccess world; + + public RelativeBlockSample(Schematic schematic) { + this.schematic = schematic; + this.blockData = SchematicPlacer.getBlockData(schematic, schematic.getWidth(), schematic.getHeight(), schematic.getLength()); + this.blockPalette = ImmutableBiMap.copyOf(schematic.getBlockPalette()); + this.blockContainer = Maps.newHashMap(); + this.blockEntityContainer = Maps.newHashMap(); + int width = schematic.getWidth(); + int height = schematic.getHeight(); + int length = schematic.getLength(); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < length; z++) { + this.blockContainer.put(new BlockPos(x, y, z), this.blockPalette.inverse().get(this.blockData[x][y][z])); + } + } + } + for (CompoundTag blockEntityTag : schematic.getBlockEntities()) { + if (blockEntityTag.contains("Pos") && (!blockEntityTag.contains("x") && !blockEntityTag.contains("y") && !blockEntityTag.contains("z"))) { + IntArrayTag pos = Objects.requireNonNull((IntArrayTag) blockEntityTag.get("Pos")); + blockEntityTag.putInt("x", pos.get(0).getInt()); + blockEntityTag.putInt("y", pos.get(1).getInt()); + blockEntityTag.putInt("z", pos.get(2).getInt()); + } else if (!blockEntityTag.contains("Pos") && (blockEntityTag.contains("x") && blockEntityTag.contains("y") && blockEntityTag.contains("z"))) { + blockEntityTag.putIntArray("Pos", ImmutableList.of( + blockEntityTag.getInt("x"), + blockEntityTag.getInt("y"), + blockEntityTag.getInt("z") + ) + ); + } + int[] arr = blockEntityTag.getIntArray("Pos"); + BlockPos position = new BlockPos(arr[0], arr[1], arr[2]); + this.blockEntityContainer.put(position, blockEntityTag); + } + } + + @Override + public @Nullable BlockEntity getBlockEntity(BlockPos pos) { + Block block = this.getBlockState(pos).getBlock(); + if (block.hasBlockEntity()) { + if (block instanceof ConditionalBlockEntityProvider && ((ConditionalBlockEntityProvider) block).hasBlockEntity(this.getBlockState(pos)) && ((ConditionalBlockEntityProvider) block).hasBlockEntity(pos, this)) { + return ((ConditionalBlockEntityProvider) block).createBlockEntity(this.world); + } else { + return ((BlockEntityProvider)block).createBlockEntity(this.world); + } + } + return null; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return this.blockContainer.get(pos); + } + + @Override + public FluidState getFluidState(BlockPos pos) { + return this.blockContainer.get(pos).getFluidState(); + } + + public void place(BlockPos origin) { + if (this.world == null) { + throw new UnsupportedOperationException("Can not place in a null world!"); + } + this.blockContainer.forEach((pos, state) -> this.world.setBlockState(origin.add(pos), state, 0b0000011)); + for (Map.Entry entry : this.blockEntityContainer.entrySet()) { + BlockPos pos = entry.getKey(); + BlockPos actualPos = origin.add(pos); + CompoundTag tag = entry.getValue(); + tag.putInt("x", actualPos.getX()); + tag.putInt("y", actualPos.getY()); + tag.putInt("z", actualPos.getZ()); + BlockEntity blockEntity = BlockEntity.createFromTag(this.getBlockState(pos), tag); + if (blockEntity != null) { + this.world.toServerWorld().setBlockEntity(blockEntity.getPos(), blockEntity); + } + } + } + + public int[][][] getBlockData() { + return this.blockData; + } + + public BiMap getBlockPalette() { + return this.blockPalette; + } + + public Map getBlockContainer() { + return this.blockContainer; + } + + public Map getBlockEntityContainer() { + return this.blockEntityContainer; + } + + public StructureWorldAccess getWorld() { + return this.world; + } + + public RelativeBlockSample setWorld(StructureWorldAccess world) { + this.world = world; + return this; + } +} diff --git a/src/main/java/org/dimdev/dimcore/schematic/v2/Schematic.java b/src/main/java/org/dimdev/dimcore/schematic/v2/Schematic.java index adaee960..3596f480 100644 --- a/src/main/java/org/dimdev/dimcore/schematic/v2/Schematic.java +++ b/src/main/java/org/dimdev/dimcore/schematic/v2/Schematic.java @@ -3,6 +3,7 @@ package org.dimdev.dimcore.schematic.v2; import java.nio.ByteBuffer; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import com.google.common.collect.ImmutableList; import com.google.gson.JsonObject; @@ -19,6 +20,7 @@ import net.minecraft.world.StructureWorldAccess; @SuppressWarnings("CodeBlock2Expr") public class Schematic { + private static final Consumer PRINT_TO_STDERR = System.err::println; public static final Codec CODEC = RecordCodecBuilder.create((instance) -> { return instance.group( Codec.INT.fieldOf("Version").forGetter(Schematic::getVersion), @@ -112,27 +114,27 @@ public class Schematic { return this.entities; } - public static SchematicBlockSample blockSample(Schematic schem) { - return new SchematicBlockSample(schem); + public static RelativeBlockSample getBlockSample(Schematic schem) { + return new RelativeBlockSample(schem); } - public static SchematicBlockSample blockSample(Schematic schem, StructureWorldAccess world) { - return blockSample(schem).withWorld(world); + public static RelativeBlockSample getBlockSample(Schematic schem, StructureWorldAccess world) { + return getBlockSample(schem).setWorld(world); } public static Schematic fromTag(CompoundTag tag) { - return CODEC.decode(NbtOps.INSTANCE, tag).getOrThrow(false, System.err::println).getFirst(); + return CODEC.decode(NbtOps.INSTANCE, tag).getOrThrow(false, PRINT_TO_STDERR).getFirst(); } public static CompoundTag toTag(Schematic schem) { - return (CompoundTag) CODEC.encodeStart(NbtOps.INSTANCE, schem).getOrThrow(false, System.err::println); + return (CompoundTag) CODEC.encodeStart(NbtOps.INSTANCE, schem).getOrThrow(false, PRINT_TO_STDERR); } public static Schematic fromJson(JsonObject json) { - return CODEC.decode(JsonOps.INSTANCE, json).getOrThrow(false, System.err::println).getFirst(); + return CODEC.decode(JsonOps.INSTANCE, json).getOrThrow(false, PRINT_TO_STDERR).getFirst(); } public static JsonObject toJson(Schematic schem) { - return (JsonObject) CODEC.encodeStart(JsonOps.INSTANCE, schem).getOrThrow(false, System.err::println); + return (JsonObject) CODEC.encodeStart(JsonOps.INSTANCE, schem).getOrThrow(false, PRINT_TO_STDERR); } } diff --git a/src/main/java/org/dimdev/dimcore/schematic/v2/SchematicBlockSample.java b/src/main/java/org/dimdev/dimcore/schematic/v2/SchematicBlockSample.java deleted file mode 100644 index 4d3a4961..00000000 --- a/src/main/java/org/dimdev/dimcore/schematic/v2/SchematicBlockSample.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.dimdev.dimcore.schematic.v2; - -import java.util.Map; - -import io.github.boogiemonster1o1.libcbe.api.ConditionalBlockEntityProvider; -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.Maps; -import org.jetbrains.annotations.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockEntityProvider; -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.fluid.FluidState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockView; -import net.minecraft.world.StructureWorldAccess; - -public class SchematicBlockSample implements BlockView { - public final Schematic schematic; - private final int[][][] blockData; - private final BiMap palette; - private final Map container; - private StructureWorldAccess world; - - public SchematicBlockSample(Schematic schematic) { - this.schematic = schematic; - this.blockData = SchematicPlacer.getBlockData(schematic, schematic.getWidth(), schematic.getHeight(), schematic.getLength()); - this.palette = ImmutableBiMap.copyOf(schematic.getBlockPalette()); - this.container = Maps.newHashMap(); - int width = schematic.getWidth(); - int height = schematic.getHeight(); - int length = schematic.getLength(); - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - this.container.put(new BlockPos(x, y, z), this.palette.inverse().get(this.blockData[x][y][z])); - } - } - } - } - - @Override - public @Nullable BlockEntity getBlockEntity(BlockPos pos) { - Block block = this.getBlockState(pos).getBlock(); - if (block.hasBlockEntity()) { - if (block instanceof ConditionalBlockEntityProvider && ((ConditionalBlockEntityProvider) block).hasBlockEntity(this.getBlockState(pos)) && ((ConditionalBlockEntityProvider) block).hasBlockEntity(pos, this)) { - return ((ConditionalBlockEntityProvider) block).createBlockEntity(this.world); - } else { - return ((BlockEntityProvider)block).createBlockEntity(this.world); - } - } - return null; - } - - @Override - public BlockState getBlockState(BlockPos pos) { - return this.container.get(pos); - } - - @Override - public FluidState getFluidState(BlockPos pos) { - return this.container.get(pos).getFluidState(); - } - - public void place(BlockPos origin) { - if (this.world == null) { - throw new UnsupportedOperationException("Can not place in a null world!"); - } - for (Map.Entry entry : this.container.entrySet()) { - BlockPos pos = entry.getKey(); - BlockState state = entry.getValue(); - this.world.setBlockState(origin.add(pos), state, 2); - this.world.toServerWorld().markDirty(origin.add(pos), null); - this.world.toServerWorld().getChunkManager().markForUpdate(origin.add(pos)); - this.world.toServerWorld().getLightingProvider().checkBlock(origin.add(pos)); - } - } - - public int[][][] getBlockData() { - return this.blockData; - } - - public BiMap getPalette() { - return this.palette; - } - - public Map getBlockContainer() { - return this.container; - } - - public StructureWorldAccess getWorld() { - return this.world; - } - - public SchematicBlockSample withWorld(StructureWorldAccess world) { - this.world = world; - return this; - } -} diff --git a/src/main/java/org/dimdev/dimcore/schematic/v2/SchematicPlacer.java b/src/main/java/org/dimdev/dimcore/schematic/v2/SchematicPlacer.java index d65935ff..2d310177 100644 --- a/src/main/java/org/dimdev/dimcore/schematic/v2/SchematicPlacer.java +++ b/src/main/java/org/dimdev/dimcore/schematic/v2/SchematicPlacer.java @@ -1,22 +1,18 @@ package org.dimdev.dimcore.schematic.v2; -import java.io.IOException; -import java.io.InputStream; import java.util.List; import java.util.Objects; -import net.minecraft.nbt.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dimdev.dimdoors.mixin.ListTagAccessor; -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableList; -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.ListTag; import net.minecraft.util.math.BlockPos; import net.minecraft.world.StructureWorldAccess; @@ -35,18 +31,12 @@ public final class SchematicPlacer { LOGGER.warn("Schematic \"" + schematic.getMetadata().getName() + "\" depends on mod \"" + id + "\", which is missing!"); } } - int width = schematic.getWidth(); - int height = schematic.getHeight(); - int length = schematic.getLength(); int originX = origin.getX(); int originY = origin.getY(); int originZ = origin.getZ(); - int[][][] blockData = SchematicPlacer.getBlockData(schematic, width, height, length); - SchematicBlockSample blockSample = Schematic.blockSample(schematic, world); - BiMap palette = ImmutableBiMap.copyOf(schematic.getBlockPalette()); + RelativeBlockSample blockSample = Schematic.getBlockSample(schematic, world); blockSample.place(origin); SchematicPlacer.placeEntities(originX, originY, originZ, schematic, world); - SchematicPlacer.placeBlockEntities(originX, originY, originZ, schematic, blockSample); } static int[][][] getBlockData(Schematic schematic, int width, int height, int length) { @@ -84,30 +74,6 @@ public final class SchematicPlacer { } } - private static void placeBlockEntities(int originX, int originY, int originZ, Schematic schematic, SchematicBlockSample blockSample) { - List blockEntityTags = schematic.getBlockEntities(); - for (CompoundTag tag : blockEntityTags) { - if (SchematicPlacer.fixId(tag)) { - System.err.println("An unexpected error occurred parsing this block entity"); - System.err.println(tag.toString()); - throw new IllegalStateException("Block Entity in schematic \"" + schematic.getMetadata().getName() + "\" did not have an Id tag, nor an id tag!"); - } - if (fixPos(tag)) { - throw new IllegalStateException("Block Entity in schematic \"" + schematic.getMetadata().getName() + "\" did not have a Pos tag, nor x, y and z tags!"); - } - ListTag listTag = Objects.requireNonNull(tag.getList("Pos", 6)); - SchematicPlacer.processPos(listTag, originX, originY, originZ, tag); - - BlockPos pos = new BlockPos(tag.getInt("x"),tag.getInt("y"),tag.getInt("z")); - BlockEntity blockEntity = blockSample.getBlockEntity(pos); - // TODO: fail with an exception - if (blockEntity != null) { - blockEntity.fromTag(blockSample.getWorld().getBlockState(pos), tag); - blockSample.getWorld().getChunk(pos).setBlockEntity(pos, blockEntity); - } - } - } - private static boolean fixId(CompoundTag tag) { if (!tag.contains("Id") && tag.contains("id")) { tag.putString("Id", tag.getString("id")); @@ -117,23 +83,6 @@ public final class SchematicPlacer { return !tag.contains("Id") || !tag.contains("id"); } - private static boolean fixPos(CompoundTag tag) { - if (!tag.contains("Pos") && tag.contains("x") && tag.contains("y") && tag.contains("z")) { - tag.put("Pos", new IntArrayTag( - ImmutableList.of( - ((Number) tag.getDouble("x")).intValue(), - ((Number) tag.getDouble("y")).intValue(), - ((Number) tag.getDouble("z")).intValue() - ) - )); - } else if (tag.contains("Pos") && !tag.contains("x") && !tag.contains("y") && !tag.contains("z")) { - tag.put("x", ((IntArrayTag) Objects.requireNonNull(tag.get("Pos"))).get(0)); - tag.put("y", ((IntArrayTag) Objects.requireNonNull(tag.get("Pos"))).get(1)); - tag.put("z", ((IntArrayTag) Objects.requireNonNull(tag.get("Pos"))).get(2)); - } - return !tag.contains("Pos") || !(tag.contains("x") && tag.contains("y") && tag.contains("z")); - } - private static void processPos(ListTag listTag, int originX, int originY, int originZ, CompoundTag tag) { double x = listTag.getDouble(0); double y = listTag.getDouble(1); diff --git a/src/main/java/org/dimdev/dimdoors/util/Codecs.java b/src/main/java/org/dimdev/dimdoors/util/Codecs.java index a9c9c22c..82e284da 100644 --- a/src/main/java/org/dimdev/dimdoors/util/Codecs.java +++ b/src/main/java/org/dimdev/dimdoors/util/Codecs.java @@ -11,9 +11,9 @@ import net.minecraft.util.DyeColor; import net.minecraft.util.math.BlockBox; public class Codecs { - public static Codec> INT_SET = Codec.INT_STREAM.>comapFlatMap(a -> DataResult.success(a.boxed().collect(Collectors.toSet())), a -> a.stream().mapToInt(Integer::intValue)); + public static Codec> INT_SET = Codec.INT_STREAM.comapFlatMap(a -> DataResult.success(a.boxed().collect(Collectors.toSet())), a -> a.stream().mapToInt(Integer::intValue)); - public static Codec BLOCK_BOX = Codec.INT_STREAM.comapFlatMap(a -> DataResult.success(new BlockBox(a.toArray())), a -> IntStream.of(a.minX, a.minY, a.minZ, a.maxX, a.maxY, a.maxZ)); + public static Codec BLOCK_BOX = Codec.INT_STREAM.comapFlatMap(a -> DataResult.success(new BlockBox(a.toArray())), a -> IntStream.of(a.minX, a.minY, a.minZ, a.maxX, a.maxY, a.maxZ)); public static Codec DYE_COLOR = Codec.INT.xmap(DyeColor::byId, DyeColor::getId); } diff --git a/src/main/java/org/dimdev/dimdoors/world/feature/ModFeatures.java b/src/main/java/org/dimdev/dimdoors/world/feature/ModFeatures.java index 30de5783..285cf608 100644 --- a/src/main/java/org/dimdev/dimdoors/world/feature/ModFeatures.java +++ b/src/main/java/org/dimdev/dimdoors/world/feature/ModFeatures.java @@ -19,6 +19,8 @@ import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.ConfiguredFeatures; import net.minecraft.world.gen.feature.Feature; +import net.fabricmc.loader.api.FabricLoader; + public final class ModFeatures { public static final Feature GATEWAY_FEATURE = Registry.register(Registry.FEATURE, new Identifier("dimdoors", "gateway"), new SchematicGatewayFeature(SchematicGatewayFeatureConfig.CODEC)); public static final Feature GATEWAY_FEATURE_V2 = Registry.register(Registry.FEATURE, new Identifier("dimdoors", "gateway_v2"), new SchematicV2GatewayFeature(SchematicV2GatewayFeatureConfig.CODEC)); @@ -41,15 +43,16 @@ public final class ModFeatures { SANDSTONE_PILLARS_GATEWAY = new SandstonePillarsGateway(); TWO_PILLARS_GATEWAY = new TwoPillarsGateway(); SANDSTONE_PILLARS_GATEWAY_V2 = new SandstonePillarsV2Gateway(); - + + int gatewayChance = FabricLoader.getInstance().isDevelopmentEnvironment() ? 50 : ModConfig.WORLD.gatewayGenChance; SANDSTONE_PILLARS_FEATURE_V2 = GATEWAY_FEATURE_V2.configure(new SchematicV2GatewayFeatureConfig(SchematicV2Gateway.SCHEMATIC_ID_MAP.get(SANDSTONE_PILLARS_GATEWAY_V2))) .decorate(ConfiguredFeatures.Decorators.SQUARE_TOP_SOLID_HEIGHTMAP - .applyChance(ModConfig.WORLD.gatewayGenChance)); + .applyChance(gatewayChance)); SANDSTONE_PILLARS_FEATURE = GATEWAY_FEATURE.configure(new SchematicGatewayFeatureConfig(SchematicGateway.SCHEMATIC_ID_MAP.get(SANDSTONE_PILLARS_GATEWAY))) .decorate(ConfiguredFeatures.Decorators.SQUARE_TOP_SOLID_HEIGHTMAP - .applyChance(ModConfig.WORLD.gatewayGenChance)); + .applyChance(gatewayChance)); TWO_PILLARS_FEATURE = GATEWAY_FEATURE.configure(new SchematicGatewayFeatureConfig(SchematicGateway.SCHEMATIC_ID_MAP.get(TWO_PILLARS_GATEWAY))) .decorate(ConfiguredFeatures.Decorators.SQUARE_TOP_SOLID_HEIGHTMAP - .applyChance(ModConfig.WORLD.gatewayGenChance)); + .applyChance(gatewayChance)); } }