Schematicannon and Complex blocks

- Fixed double blocks being counted twice as requirement
- Fixed beds not showing in Hologram
- Fixed Blocks like flowers not showing in Hologram at certain conditions
- Added a print option to blueprints in creative (Bypassing the cannon)
- Fixed pistons placed by the cannon
This commit is contained in:
simibubi 2019-07-22 14:40:28 +02:00
parent 558a36fb47
commit a9c710f81d
11 changed files with 140 additions and 38 deletions

View file

@ -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"

View file

@ -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();

View file

@ -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<LaunchedBlock> 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);
}
}

View file

@ -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,

View file

@ -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) {
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));
});
}
}

View file

@ -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;

View file

@ -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) {

View file

@ -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<BlockPos> 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<BlockPos> 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 {

View file

@ -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;
}
}

View file

@ -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<Tools> getTools() {
public static List<Tools> getTools(boolean creative) {
List<Tools> tools = new ArrayList<>();
Collections.addAll(tools, Move, MoveY, Deploy, Rotate, Flip);
if (creative)
tools.add(Print);
return tools;
}

View file

@ -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 <here>
@ -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