diff --git a/build.gradle b/build.gradle index d77a896ea..1c8e7c0e4 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = '0.0.2' +version = '0.0.3' group = 'com.simibubi.create' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'create' @@ -89,7 +89,7 @@ dependencies { // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.14.3-27.0.57' + minecraft 'net.minecraftforge:forge:1.14.3-27.0.60' // You may put jars on which you depend on in ./libs or you may define them like so.. // compile "some.group:artifact:version:classifier" diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index 3c8fc9e56..25120eed0 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -35,7 +35,7 @@ public class Create { public static final String ID = "create"; public static final String NAME = "Create"; - public static final String VERSION = "0.0.2"; + public static final String VERSION = "0.0.3"; public static Logger logger = LogManager.getLogger(); diff --git a/src/main/java/com/simibubi/create/block/SchematicannonTileEntity.java b/src/main/java/com/simibubi/create/block/SchematicannonTileEntity.java index e68f6a2b1..fb88827c9 100644 --- a/src/main/java/com/simibubi/create/block/SchematicannonTileEntity.java +++ b/src/main/java/com/simibubi/create/block/SchematicannonTileEntity.java @@ -15,6 +15,7 @@ import com.simibubi.create.utility.TileEntitySynced; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.PistonHeadBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; @@ -26,6 +27,9 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.NBTUtil; import net.minecraft.network.PacketBuffer; +import net.minecraft.state.properties.BedPart; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.state.properties.DoubleBlockHalf; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; @@ -229,8 +233,8 @@ public class SchematicannonTileEntity extends TileEntitySynced implements ITicka state = State.valueOf(compound.getString("State")); blocksPlaced = compound.getInt("AmountPlaced"); blocksToPlace = compound.getInt("AmountToPlace"); - - if (compound.contains("MissingBlock")) + + if (compound.contains("MissingBlock")) missingBlock = NBTUtil.readBlockState(compound.getCompound("MissingBlock")); else missingBlock = null; @@ -311,7 +315,7 @@ public class SchematicannonTileEntity extends TileEntitySynced implements ITicka compound.putString("State", state.name()); compound.putInt("AmountPlaced", blocksPlaced); compound.putInt("AmountToPlace", blocksToPlace); - + if (missingBlock != null) compound.put("MissingBlock", NBTUtil.writeBlockState(missingBlock)); @@ -424,7 +428,7 @@ public class SchematicannonTileEntity extends TileEntitySynced implements ITicka state = State.RUNNING; } } - + if (missingBlock == null && !blockNotLoaded) { advanceCurrentPos(); @@ -602,8 +606,7 @@ public class SchematicannonTileEntity extends TileEntitySynced implements ITicka if (!replaceTileEntities && toReplace.hasTileEntity()) return false; - // Block doesnt have a mapping (Water, lava, etc) - if (getItemForBlock(state).getItem() == Items.AIR && state.getBlock() != Blocks.AIR) + if (shouldIgnoreBlockState(state)) return false; if (replaceMode == 3) @@ -619,12 +622,37 @@ public class SchematicannonTileEntity extends TileEntitySynced implements ITicka return false; } + protected boolean shouldIgnoreBlockState(BlockState state) { + // Block doesnt have a mapping (Water, lava, etc) + if (getItemForBlock(state).getItem() == Items.AIR && state.getBlock() != Blocks.AIR) + return true; + + // Block doesnt need to be placed twice (Doors, beds, double plants) + if (state.has(BlockStateProperties.DOUBLE_BLOCK_HALF) + && state.get(BlockStateProperties.DOUBLE_BLOCK_HALF) == DoubleBlockHalf.UPPER) + return true; + if (state.has(BlockStateProperties.BED_PART) + && state.get(BlockStateProperties.BED_PART) == BedPart.HEAD) + return true; + if (state.getBlock() instanceof PistonHeadBlock) + return true; + + return false; + } + protected void tickFlyingBlocks() { List toRemove = new LinkedList<>(); for (LaunchedBlock b : flyingBlocks) { b.update(); if (b.ticksRemaining <= 0 && !world.isRemote) { + + // Piston + if (b.state.has(BlockStateProperties.EXTENDED)) { + b.state = b.state.with(BlockStateProperties.EXTENDED, false); + } + world.setBlockState(b.target, b.state, 18); + b.state.getBlock().onBlockPlacedBy(world, b.target, b.state, null, getItemForBlock(b.state)); toRemove.add(b); } } diff --git a/src/main/java/com/simibubi/create/networking/AllPackets.java b/src/main/java/com/simibubi/create/networking/AllPackets.java index fa070d7df..c4f74c2ea 100644 --- a/src/main/java/com/simibubi/create/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/networking/AllPackets.java @@ -19,6 +19,8 @@ public class AllPackets { PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals); channel.registerMessage(i++, NbtPacket.class, NbtPacket::toBytes, NbtPacket::new, NbtPacket::handle); + channel.registerMessage(i++, SchematicPlacePacket.class, SchematicPlacePacket::toBytes, + SchematicPlacePacket::new, SchematicPlacePacket::handle); channel.registerMessage(i++, ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::toBytes, ConfigureSchematicannonPacket::new, ConfigureSchematicannonPacket::handle); channel.registerMessage(i++, SchematicUploadPacket.class, SchematicUploadPacket::toBytes, diff --git a/src/main/java/com/simibubi/create/networking/SchematicPlacePacket.java b/src/main/java/com/simibubi/create/networking/SchematicPlacePacket.java new file mode 100644 index 000000000..eba78109b --- /dev/null +++ b/src/main/java/com/simibubi/create/networking/SchematicPlacePacket.java @@ -0,0 +1,39 @@ +package com.simibubi.create.networking; + +import java.util.function.Supplier; + +import com.simibubi.create.item.BlueprintItem; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.network.PacketBuffer; +import net.minecraft.world.gen.feature.template.Template; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class SchematicPlacePacket { + + public ItemStack stack; + + public SchematicPlacePacket(ItemStack stack) { + this.stack = stack; + } + + public SchematicPlacePacket(PacketBuffer buffer) { + stack = buffer.readItemStack(); + } + + public void toBytes(PacketBuffer buffer) { + buffer.writeItemStack(stack); + } + + public void handle(Supplier context) { + context.get().enqueueWork(() -> { + ServerPlayerEntity player = context.get().getSender(); + Template t = BlueprintItem.getSchematic(stack); + t.addBlocksToWorld(player.getServerWorld(), NBTUtil.readBlockPos(stack.getTag().getCompound("Anchor")), + BlueprintItem.getSettings(stack)); + }); + } + +} diff --git a/src/main/java/com/simibubi/create/schematic/BlueprintHandler.java b/src/main/java/com/simibubi/create/schematic/BlueprintHandler.java index 0e9361cbf..5064679dc 100644 --- a/src/main/java/com/simibubi/create/schematic/BlueprintHandler.java +++ b/src/main/java/com/simibubi/create/schematic/BlueprintHandler.java @@ -12,6 +12,7 @@ import com.simibubi.create.gui.BlueprintHotbarOverlay; import com.simibubi.create.gui.ToolSelectionScreen; import com.simibubi.create.item.BlueprintItem; import com.simibubi.create.networking.NbtPacket; +import com.simibubi.create.networking.SchematicPlacePacket; import com.simibubi.create.networking.AllPackets; import com.simibubi.create.schematic.tools.Tools; import com.simibubi.create.utility.Keyboard; @@ -109,7 +110,7 @@ public class BlueprintHandler { event.getPlayer().unlockRecipes(new ResourceLocation[] { AllItems.SYMMETRY_WAND.get().getRegistryName() }); } } - + @SubscribeEvent public static void onClientTick(ClientTickEvent event) { ClientPlayerEntity player = Minecraft.getInstance().player; @@ -136,7 +137,8 @@ public class BlueprintHandler { instance.active = true; if (instance.deployed) { Tools toolBefore = instance.currentTool; - instance.selectionScreen = new ToolSelectionScreen(Tools.getTools(), instance::equip); + instance.selectionScreen = new ToolSelectionScreen(Tools.getTools(player.isCreative()), + instance::equip); if (toolBefore != null) { instance.selectionScreen.setSelectedElement(toolBefore); instance.equip(toolBefore); @@ -221,14 +223,15 @@ public class BlueprintHandler { } @SubscribeEvent - // TODO: This is a fabricated event call by ScrollFixer until a proper event exists + // TODO: This is a fabricated event call by ScrollFixer until a proper event + // exists public static void onMouseScrolled(MouseScrollEvent.Post event) { if (event.getGui() != null) return; if (instance.onScroll(event.getScrollDelta())) event.setCanceled(true); } - + public boolean onScroll(double delta) { if (!active) return false; @@ -382,7 +385,8 @@ public class BlueprintHandler { public void moveTo(BlockPos anchor) { if (!deployed) - instance.selectionScreen = new ToolSelectionScreen(Tools.getTools(), instance::equip); + instance.selectionScreen = new ToolSelectionScreen( + Tools.getTools(Minecraft.getInstance().player.isCreative()), instance::equip); deployed = true; this.anchor = anchor; @@ -390,6 +394,15 @@ public class BlueprintHandler { item.getTag().put("Anchor", NBTUtil.writeBlockPos(anchor)); markDirty(); } + + public void printInstantly() { + AllPackets.channel.sendToServer(new SchematicPlacePacket(item.copy())); + CompoundNBT nbt = item.getTag(); + nbt.putBoolean("Deployed", false); + item.setTag(nbt); + SchematicHologram.reset(); + active = false; + } public BlockPos getTransformedSize() { BlockPos flipped = size; diff --git a/src/main/java/com/simibubi/create/schematic/SchematicHologram.java b/src/main/java/com/simibubi/create/schematic/SchematicHologram.java index 1d69826e5..0c3640817 100644 --- a/src/main/java/com/simibubi/create/schematic/SchematicHologram.java +++ b/src/main/java/com/simibubi/create/schematic/SchematicHologram.java @@ -10,7 +10,9 @@ import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.platform.GlStateManager; +import net.minecraft.block.BedBlock; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.BlockRendererDispatcher; @@ -65,7 +67,7 @@ public class SchematicHologram { active = true; changed = true; } - + public void startHologram(SchematicWorld world) { this.anchor = world.anchor; this.schematic = world; @@ -77,11 +79,6 @@ public class SchematicHologram { return instance; } -// public static void display(Schematic schematic) { -// instance = new SchematicHologram(); -// instance.startHologram(schematic); -// } - public static void reset() { instance = null; } @@ -119,7 +116,7 @@ public class SchematicHologram { for (BlockPos localPos : BlockPos.getAllInBoxMutable(blockAccess.getBounds().getOrigin(), blockAccess.getBounds().getOrigin().add(blockAccess.getBounds().getSize()))) { BlockPos pos = localPos.add(instance.anchor); - final BlockState state = blockAccess.getBlockState(pos); + BlockState state = blockAccess.getBlockState(pos); for (BlockRenderLayer blockRenderLayer : BlockRenderLayer.values()) { if (!state.getBlock().canRenderInLayer(state, blockRenderLayer)) { continue; @@ -137,6 +134,12 @@ public class SchematicHologram { // OptiFine Shaders compatibility // if (Config.isShaders()) SVertexBuilder.pushEntity(state, pos, // blockAccess, bufferBuilder); + + // Block transformations + if (state.getBlock() instanceof BedBlock) { + state = Blocks.QUARTZ_SLAB.getDefaultState(); + } + usedBlockRenderLayers[blockRenderLayerId] |= blockRendererDispatcher.renderBlock(state, pos, blockAccess, bufferBuilder, minecraft.world.rand, EmptyModelData.INSTANCE); blockstates.add(state); @@ -205,7 +208,7 @@ public class SchematicHologram { bytebuffer.position(vertexformat.getOffset(index)); usage.preDraw(vertexformat, index, size, bytebuffer); } - + GlStateManager.drawArrays(bufferBuilder.getDrawMode(), 0, bufferBuilder.getVertexCount()); for (int index = 0; index < list.size(); ++index) { diff --git a/src/main/java/com/simibubi/create/schematic/SchematicWorld.java b/src/main/java/com/simibubi/create/schematic/SchematicWorld.java index be0b71e01..8a7f370f4 100644 --- a/src/main/java/com/simibubi/create/schematic/SchematicWorld.java +++ b/src/main/java/com/simibubi/create/schematic/SchematicWorld.java @@ -1,7 +1,6 @@ package com.simibubi.create.schematic; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -51,19 +50,8 @@ public class SchematicWorld implements IWorld { this.blocks = blocks; this.setBounds(bounds); this.anchor = anchor; - updateBlockstates(); } - private void updateBlockstates() { - Set keySet = new HashSet<>(blocks.keySet()); - keySet.forEach(pos -> { - BlockState blockState = blocks.get(pos); - if (blockState == null) - return; - blockState.updateNeighbors(this, pos.add(anchor), 16); - }); - } - public Set getAllPositions() { return blocks.keySet(); } @@ -76,6 +64,11 @@ public class SchematicWorld implements IWorld { @Override public BlockState getBlockState(BlockPos globalPos) { BlockPos pos = globalPos.subtract(anchor); + + if (pos.getY() - bounds.y == -1) { + return Blocks.GRASS_BLOCK.getDefaultState(); + } + if (getBounds().contains(pos) && blocks.containsKey(pos)) { return blocks.get(pos); } else { diff --git a/src/main/java/com/simibubi/create/schematic/tools/PlaceTool.java b/src/main/java/com/simibubi/create/schematic/tools/PlaceTool.java new file mode 100644 index 000000000..422e9a3f1 --- /dev/null +++ b/src/main/java/com/simibubi/create/schematic/tools/PlaceTool.java @@ -0,0 +1,16 @@ +package com.simibubi.create.schematic.tools; + +public class PlaceTool extends SchematicToolBase { + + @Override + public boolean handleRightClick() { + blueprint.printInstantly(); + return true; + } + + @Override + public boolean handleMouseWheel(double delta) { + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/schematic/tools/Tools.java b/src/main/java/com/simibubi/create/schematic/tools/Tools.java index 9b41898bc..b99617b03 100644 --- a/src/main/java/com/simibubi/create/schematic/tools/Tools.java +++ b/src/main/java/com/simibubi/create/schematic/tools/Tools.java @@ -7,6 +7,8 @@ import java.util.List; import com.google.common.collect.ImmutableList; import com.simibubi.create.gui.ScreenResources; +import net.minecraft.util.text.TextFormatting; + public enum Tools { Deploy(new DeployTool(), "Deploy", ScreenResources.ICON_TOOL_DEPLOY, ImmutableList.of( @@ -27,6 +29,11 @@ public enum Tools { "Rotates the Schematic around its center.", "[CTRL]-Scroll to rotate by 90 Degrees" )), + Print(new PlaceTool(), "Print", ScreenResources.ICON_CONFIRM, ImmutableList.of( + "Instantly places the structure in the world", + "[Right-Click] to confirm placement at the current location.", + TextFormatting.ITALIC + "(Creative only)" + )), Flip(new FlipTool(), "Flip", ScreenResources.ICON_TOOL_MIRROR, ImmutableList.of( "Flips the Schematic along the face you select.", "Point at the Schematic and [CTRL]-Scroll to flip it." @@ -56,9 +63,11 @@ public enum Tools { return icon; } - public static List getTools() { + public static List getTools(boolean creative) { List tools = new ArrayList<>(); Collections.addAll(tools, Move, MoveY, Deploy, Rotate, Flip); + if (creative) + tools.add(Print); return tools; } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 663474da3..1eb284e24 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -14,7 +14,7 @@ loaderVersion="[26,)" #mandatory (26 is current forge version) # The modid of the mod modId="create" #mandatory # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it -version="0.0.2" #mandatory +version="0.0.3" #mandatory # A display name for the mod displayName="Create" #mandatory # A URL to query for updates for this mod. See the JSON update specification @@ -25,8 +25,7 @@ displayName="Create" #mandatory authors="simibubi" #optional # The description text for the mod (multi line!) (#mandatory) description=''' -A handful of additions to aid the creative survivalist. -''' +A handful of additions to aid the creative survivalist.''' # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.examplemod]] #optional # the modid of the dependency