From b1aeba61c0f1623f31f46fc51c088038f5330c1c Mon Sep 17 00:00:00 2001 From: Paul Fulham Date: Fri, 20 Nov 2020 23:03:13 -0800 Subject: [PATCH 01/31] Add network direction designation --- .../foundation/networking/AllPackets.java | 70 ++++++++++--------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 8feb79656..f7c6ed4af 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -25,8 +25,8 @@ import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket; import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; -import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; import com.simibubi.create.content.schematics.packet.SchematicSyncPacket; +import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; import com.simibubi.create.foundation.command.ConfigureConfigPacket; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket; @@ -36,44 +36,48 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkDirection; import net.minecraftforge.fml.network.NetworkEvent.Context; import net.minecraftforge.fml.network.NetworkRegistry; import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor.TargetPoint; import net.minecraftforge.fml.network.simple.SimpleChannel; +import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER; +import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_CLIENT; + public enum AllPackets { // Client to Server - NBT(NbtPacket.class, NbtPacket::new), - CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::new), - CONFIGURE_FLEXCRATE(ConfigureFlexcratePacket.class, ConfigureFlexcratePacket::new), - CONFIGURE_STOCKSWITCH(ConfigureStockswitchPacket.class, ConfigureStockswitchPacket::new), - CONFIGURE_SEQUENCER(ConfigureSequencedGearshiftPacket.class, ConfigureSequencedGearshiftPacket::new), - PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new), - UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new), - CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new), - CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new), - CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), - EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new), - CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new), - CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new), - PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new), - MINECART_COUPLING_CREATION(CouplingCreationPacket.class, CouplingCreationPacket::new), - INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket::new), - SYNC_SCHEMATIC(SchematicSyncPacket.class, SchematicSyncPacket::new), + NBT(NbtPacket.class, NbtPacket::new, PLAY_TO_SERVER), + CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::new, PLAY_TO_SERVER), + CONFIGURE_FLEXCRATE(ConfigureFlexcratePacket.class, ConfigureFlexcratePacket::new, PLAY_TO_SERVER), + CONFIGURE_STOCKSWITCH(ConfigureStockswitchPacket.class, ConfigureStockswitchPacket::new, PLAY_TO_SERVER), + CONFIGURE_SEQUENCER(ConfigureSequencedGearshiftPacket.class, ConfigureSequencedGearshiftPacket::new, PLAY_TO_SERVER), + PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new, PLAY_TO_SERVER), + UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new, PLAY_TO_SERVER), + CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new, PLAY_TO_SERVER), + CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new, PLAY_TO_SERVER), + CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new, PLAY_TO_SERVER), + EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new, PLAY_TO_SERVER), + CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new, PLAY_TO_SERVER), + CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new, PLAY_TO_SERVER), + PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new, PLAY_TO_SERVER), + MINECART_COUPLING_CREATION(CouplingCreationPacket.class, CouplingCreationPacket::new, PLAY_TO_SERVER), + INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket::new, PLAY_TO_SERVER), + SYNC_SCHEMATIC(SchematicSyncPacket.class, SchematicSyncPacket::new, PLAY_TO_SERVER), // Server to Client - SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new), - SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new), - BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new), - CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new), - CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new), - GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new), - CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new), - LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new), - MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket::new), - FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new), + SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), + SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new, PLAY_TO_CLIENT), + BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new, PLAY_TO_CLIENT), + CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new, PLAY_TO_CLIENT), + CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new, PLAY_TO_CLIENT), + GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new, PLAY_TO_CLIENT), + CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new, PLAY_TO_CLIENT), + LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new, PLAY_TO_CLIENT), + MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket::new, PLAY_TO_CLIENT), + FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT), ; @@ -83,8 +87,8 @@ public enum AllPackets { private LoadedPacket packet; - private AllPackets(Class type, Function factory) { - packet = new LoadedPacket<>(type, factory); + private AllPackets(Class type, Function factory, NetworkDirection direction) { + packet = new LoadedPacket<>(type, factory, direction); } public static void registerPackets() { @@ -110,16 +114,18 @@ public enum AllPackets { Function decoder; BiConsumer> handler; Class type; + NetworkDirection direction; - private LoadedPacket(Class type, Function factory) { + private LoadedPacket(Class type, Function factory, NetworkDirection direction) { encoder = T::write; decoder = factory; handler = T::handle; this.type = type; + this.direction = direction; } private void register() { - channel.messageBuilder(type, index++) + channel.messageBuilder(type, index++, direction) .encoder(encoder) .decoder(decoder) .consumer(handler) From e1d1b062f8fc5b18f3ae83b381396a3970304953 Mon Sep 17 00:00:00 2001 From: Paul Fulham Date: Sat, 21 Nov 2020 18:20:49 -0800 Subject: [PATCH 02/31] Enforce network version --- .../com/simibubi/create/foundation/networking/AllPackets.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index f7c6ed4af..8bb4a5f83 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -93,8 +93,8 @@ public enum AllPackets { public static void registerPackets() { channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME) - .serverAcceptedVersions(s -> true) - .clientAcceptedVersions(s -> true) + .serverAcceptedVersions(NETWORK_VERSION::equals) + .clientAcceptedVersions(NETWORK_VERSION::equals) .networkProtocolVersion(() -> NETWORK_VERSION) .simpleChannel(); for (AllPackets packet : values()) From 7c8bd28421040a783e2637df083a86c63bc326cd Mon Sep 17 00:00:00 2001 From: Paul Fulham Date: Sat, 21 Nov 2020 18:28:05 -0800 Subject: [PATCH 03/31] Restrict schematicannon configuration --- .../packet/ConfigureSchematicannonPacket.java | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/schematics/packet/ConfigureSchematicannonPacket.java b/src/main/java/com/simibubi/create/content/schematics/packet/ConfigureSchematicannonPacket.java index 4a5984e77..2e66fc255 100644 --- a/src/main/java/com/simibubi/create/content/schematics/packet/ConfigureSchematicannonPacket.java +++ b/src/main/java/com/simibubi/create/content/schematics/packet/ConfigureSchematicannonPacket.java @@ -2,15 +2,13 @@ package com.simibubi.create.content.schematics.packet; import java.util.function.Supplier; +import com.simibubi.create.content.schematics.block.SchematicannonContainer; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity.State; import com.simibubi.create.foundation.networking.SimplePacketBase; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.network.PacketBuffer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import net.minecraftforge.fml.network.NetworkEvent.Context; public class ConfigureSchematicannonPacket extends SimplePacketBase { @@ -21,45 +19,28 @@ public class ConfigureSchematicannonPacket extends SimplePacketBase { private Option option; private boolean set; - private BlockPos pos; - public static ConfigureSchematicannonPacket setOption(BlockPos pos, Option option, boolean set) { - ConfigureSchematicannonPacket packet = new ConfigureSchematicannonPacket(pos); - packet.option = option; - packet.set = set; - return packet; - } - - public ConfigureSchematicannonPacket(BlockPos pos) { - this.pos = pos; + public ConfigureSchematicannonPacket(Option option, boolean set) { + this.option = option; + this.set = set; } public ConfigureSchematicannonPacket(PacketBuffer buffer) { - pos = buffer.readBlockPos(); - option = Option.values()[buffer.readInt()]; - set = buffer.readBoolean(); + this(buffer.readEnumValue(Option.class), buffer.readBoolean()); } public void write(PacketBuffer buffer) { - buffer.writeBlockPos(pos); - buffer.writeInt(option.ordinal()); + buffer.writeEnumValue(option); buffer.writeBoolean(set); } public void handle(Supplier context) { context.get().enqueueWork(() -> { ServerPlayerEntity player = context.get().getSender(); - if (player == null) - return; - World world = player.world; - if (world == null || !world.isBlockPresent(pos)) + if (player == null || !(player.openContainer instanceof SchematicannonContainer)) return; - TileEntity tileEntity = world.getTileEntity(pos); - if (!(tileEntity instanceof SchematicannonTileEntity)) - return; - - SchematicannonTileEntity te = (SchematicannonTileEntity) tileEntity; + SchematicannonTileEntity te = ((SchematicannonContainer) player.openContainer).getTileEntity(); switch (option) { case DONT_REPLACE: case REPLACE_ANY: From fe8c3d4e73360aa48d75a51677ee393af13fd2e1 Mon Sep 17 00:00:00 2001 From: Paul Fulham Date: Sat, 21 Nov 2020 19:28:54 -0800 Subject: [PATCH 04/31] Add nbt privilege checks --- .../schematics/SchematicProcessor.java | 59 +++++++++++++++++++ .../schematics/item/SchematicItem.java | 2 + 2 files changed, 61 insertions(+) create mode 100644 src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java new file mode 100644 index 000000000..f6d1a61d3 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java @@ -0,0 +1,59 @@ +package com.simibubi.create.content.schematics; + +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.DynamicOps; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorldReader; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.template.IStructureProcessorType; +import net.minecraft.world.gen.feature.template.PlacementSettings; +import net.minecraft.world.gen.feature.template.StructureProcessor; +import net.minecraft.world.gen.feature.template.Template; + +import javax.annotation.Nullable; +import java.util.Optional; + +public class SchematicProcessor extends StructureProcessor { + public static final SchematicProcessor INSTANCE = new SchematicProcessor(); + + @Nullable + @Override + public Template.BlockInfo process(IWorldReader world, BlockPos pos, Template.BlockInfo rawInfo, Template.BlockInfo info, PlacementSettings settings, @Nullable Template template) { + if (info.nbt != null) { + TileEntity te = info.state.createTileEntity(world); + if (te != null && te.onlyOpsCanSetNbt()) { + return new Template.BlockInfo(info.pos, info.state, null); + } + } + return info; + } + + @Nullable + @Override + public Template.EntityInfo processEntity(IWorldReader world, BlockPos pos, Template.EntityInfo rawInfo, Template.EntityInfo info, PlacementSettings settings, Template template) { + return EntityType.readEntityType(info.nbt) + .flatMap(type -> { + if (world instanceof World) { + Entity e = type.create((World) world); + if (e != null && !e.ignoreItemEntityData()) { + return Optional.of(info); + } + } + return Optional.empty(); + }) + .orElse(null); + } + + @Override + protected IStructureProcessorType getType() { + return dynamic -> INSTANCE; + } + + @Override + protected Dynamic serialize0(DynamicOps ops) { + return new Dynamic<>(ops, ops.emptyMap()); + } +} diff --git a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java index 2ddf14b10..ac7771002 100644 --- a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java +++ b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java @@ -12,6 +12,7 @@ import javax.annotation.Nonnull; import org.apache.commons.io.IOUtils; import com.simibubi.create.AllItems; +import com.simibubi.create.content.schematics.SchematicProcessor; import com.simibubi.create.content.schematics.client.SchematicEditScreen; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.utility.Lang; @@ -94,6 +95,7 @@ public class SchematicItem extends Item { PlacementSettings settings = new PlacementSettings(); settings.setRotation(Rotation.valueOf(tag.getString("Rotation"))); settings.setMirror(Mirror.valueOf(tag.getString("Mirror"))); + settings.addProcessor(SchematicProcessor.INSTANCE); return settings; } From 6e131583dd39bf5e7359c4de031261a240ce15c0 Mon Sep 17 00:00:00 2001 From: Paul Fulham Date: Sat, 21 Nov 2020 21:19:38 -0800 Subject: [PATCH 05/31] Fix path handling --- .../schematics/ServerSchematicLoader.java | 79 ++++++++++--------- .../schematics/item/SchematicItem.java | 38 +++++---- .../foundation/utility/FilesHelper.java | 15 +--- 3 files changed, 67 insertions(+), 65 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java index 8c8e117fa..5c2ee7466 100644 --- a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java +++ b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java @@ -91,10 +91,8 @@ public class ServerSchematicLoader { } public void handleNewUpload(ServerPlayerEntity player, String schematic, long size, BlockPos pos) { - String playerPath = getSchematicPath() + "/" + player.getName() - .getFormattedText(); - String playerSchematicId = player.getName() - .getFormattedText() + "/" + schematic; + String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName(); + String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; FilesHelper.createFolderIfMissing(playerPath); // Unsupported Format @@ -103,6 +101,14 @@ public class ServerSchematicLoader { return; } + Path schematicPath = Paths.get(getSchematicPath()).toAbsolutePath(); + + Path uploadPath = schematicPath.resolve(playerSchematicId).normalize(); + if (!uploadPath.startsWith(schematicPath)) { + Create.logger.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId); + return; + } + // Too big if (!validateSchematicSizeOnServer(player, size)) return; @@ -117,12 +123,13 @@ public class ServerSchematicLoader { if (table == null) return; - // Delete schematic with same name - Files.deleteIfExists(Paths.get(getSchematicPath(), playerSchematicId)); - // Too many Schematics - Stream list = Files.list(Paths.get(playerPath)); - if (list.count() >= getConfig().maxSchematics.get()) { + long count; + try (Stream list = Files.list(Paths.get(playerPath))) { + count = list.count(); + } + + if (count >= getConfig().maxSchematics.get()) { Stream list2 = Files.list(Paths.get(playerPath)); Optional lastFilePath = list2.filter(f -> !Files.isDirectory(f)) .min(Comparator.comparingLong(f -> f.toFile() @@ -132,11 +139,9 @@ public class ServerSchematicLoader { Files.deleteIfExists(lastFilePath.get()); } } - list.close(); // Open Stream - OutputStream writer = - Files.newOutputStream(Paths.get(getSchematicPath(), playerSchematicId), StandardOpenOption.CREATE_NEW); + OutputStream writer = Files.newOutputStream(uploadPath); activeUploads.put(playerSchematicId, new SchematicUploadEntry(writer, size, player.getServerWorld(), pos)); // Notify Tile Entity @@ -165,8 +170,7 @@ public class ServerSchematicLoader { } public void handleWriteRequest(ServerPlayerEntity player, String schematic, byte[] data) { - String playerSchematicId = player.getName() - .getFormattedText() + "/" + schematic; + String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; if (activeUploads.containsKey(playerSchematicId)) { SchematicUploadEntry entry = activeUploads.get(playerSchematicId); @@ -236,8 +240,7 @@ public class ServerSchematicLoader { } public void handleFinishedUpload(ServerPlayerEntity player, String schematic) { - String playerSchematicId = player.getName() - .getFormattedText() + "/" + schematic; + String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; if (activeUploads.containsKey(playerSchematicId)) { try { @@ -258,8 +261,7 @@ public class ServerSchematicLoader { if (table == null) return; table.finishUpload(); - table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getName() - .getFormattedText())); + table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getGameProfile().getName())); } catch (IOException e) { Create.logger.error("Exception Thrown when finishing Upload: " + playerSchematicId); @@ -270,15 +272,21 @@ public class ServerSchematicLoader { public void handleInstantSchematic(ServerPlayerEntity player, String schematic, World world, BlockPos pos, BlockPos bounds) { - String playerPath = getSchematicPath() + "/" + player.getName() - .getFormattedText(); - String playerSchematicId = player.getName() - .getFormattedText() + "/" + schematic; + String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName(); + String playerSchematicId = player.getGameProfile().getName() + "/" + schematic; FilesHelper.createFolderIfMissing(playerPath); // Unsupported Format if (!schematic.endsWith(".nbt")) { - Create.logger.warn("Attempted Schematic Upload with non-supported Format: " + playerSchematicId); + Create.logger.warn("Attempted Schematic Upload with non-supported Format: {}", playerSchematicId); + return; + } + + Path schematicPath = Paths.get(getSchematicPath()).toAbsolutePath(); + + Path path = schematicPath.resolve(playerSchematicId).normalize(); + if (!path.startsWith(schematicPath)) { + Create.logger.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId); return; } @@ -287,39 +295,32 @@ public class ServerSchematicLoader { return; try { - // Delete schematic with same name - Path path = Paths.get(getSchematicPath(), playerSchematicId); - Files.deleteIfExists(path); - // Too many Schematics - Stream list = Files.list(Paths.get(playerPath)); - if (list.count() >= getConfig().maxSchematics.get()) { + long count; + try (Stream list = Files.list(Paths.get(playerPath))) { + count = list.count(); + } + + if (count >= getConfig().maxSchematics.get()) { Stream list2 = Files.list(Paths.get(playerPath)); Optional lastFilePath = list2.filter(f -> !Files.isDirectory(f)) .min(Comparator.comparingLong(f -> f.toFile() .lastModified())); list2.close(); - if (lastFilePath.isPresent()) + if (lastFilePath.isPresent()) Files.deleteIfExists(lastFilePath.get()); } - list.close(); Template t = new Template(); t.takeBlocksFromWorld(world, pos, bounds, true, Blocks.AIR); - OutputStream outputStream = null; - try { - outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE); + try (OutputStream outputStream = Files.newOutputStream(path)) { CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT()); CompressedStreamTools.writeCompressed(nbttagcompound, outputStream); - player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getName() - .getFormattedText())); + player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getGameProfile().getName())); } catch (IOException e) { e.printStackTrace(); - } finally { - if (outputStream != null) - IOUtils.closeQuietly(outputStream); } } catch (IOException e) { Create.logger.error("Exception Thrown in direct Schematic Upload: " + playerSchematicId); diff --git a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java index ac7771002..a07437758 100644 --- a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java +++ b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java @@ -3,13 +3,15 @@ package com.simibubi.create.content.schematics.item; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.List; import javax.annotation.Nonnull; -import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.simibubi.create.AllItems; import com.simibubi.create.content.schematics.SchematicProcessor; @@ -46,6 +48,8 @@ import net.minecraftforge.fml.common.thread.SidedThreadGroups; public class SchematicItem extends Item { + private static final Logger LOGGER = LogManager.getLogger(); + public SchematicItem(Properties properties) { super(properties.maxStackSize(1)); } @@ -106,25 +110,29 @@ public class SchematicItem extends Item { String schematic = blueprint.getTag() .getString("File"); - String filepath = ""; + if (!schematic.endsWith(".nbt")) + return t; - if (Thread.currentThread() - .getThreadGroup() == SidedThreadGroups.SERVER) - filepath = "schematics/uploaded/" + owner + "/" + schematic; - else - filepath = "schematics/" + schematic; + Path dir; + Path file; - InputStream stream = null; - try { - stream = Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ); + if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER) { + dir = Paths.get("schematics", "uploaded").toAbsolutePath(); + file = Paths.get(owner, schematic); + } else { + dir = Paths.get("schematics").toAbsolutePath(); + file = Paths.get(schematic); + } + + Path path = dir.resolve(file).normalize(); + if (!path.startsWith(dir)) + return t; + + try (InputStream stream = Files.newInputStream(path, StandardOpenOption.READ)) { CompoundNBT nbt = CompressedStreamTools.readCompressed(stream); t.read(nbt); - } catch (IOException e) { - // Player/Server doesnt have schematic saved - } finally { - if (stream != null) - IOUtils.closeQuietly(stream); + LOGGER.warn("Failed to read schematic", e); } return t; diff --git a/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java b/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java index 67bc3f1fa..e59a45521 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java @@ -21,17 +21,10 @@ import net.minecraft.nbt.CompoundNBT; public class FilesHelper { public static void createFolderIfMissing(String name) { - Path path = Paths.get(name); - if (path.getParent() != null) - createFolderIfMissing(path.getParent() - .toString()); - - if (!Files.isDirectory(path)) { - try { - Files.createDirectory(path); - } catch (IOException e) { - Create.logger.warn("Could not create Folder: " + name); - } + try { + Files.createDirectories(Paths.get(name)); + } catch (IOException e) { + Create.logger.warn("Could not create Folder: {}", name); } } From 18b768b32f3703f14ea22ed509c014332736fa1a Mon Sep 17 00:00:00 2001 From: Paul Fulham Date: Sat, 21 Nov 2020 22:00:05 -0800 Subject: [PATCH 06/31] Fix upload handling --- .../content/schematics/ServerSchematicLoader.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java index 5c2ee7466..743cc5a3b 100644 --- a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java +++ b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java @@ -101,10 +101,10 @@ public class ServerSchematicLoader { return; } - Path schematicPath = Paths.get(getSchematicPath()).toAbsolutePath(); + Path playerSchematicsPath = Paths.get(getSchematicPath(), player.getGameProfile().getName()).toAbsolutePath(); - Path uploadPath = schematicPath.resolve(playerSchematicId).normalize(); - if (!uploadPath.startsWith(schematicPath)) { + Path uploadPath = playerSchematicsPath.resolve(schematic).normalize(); + if (!uploadPath.startsWith(playerSchematicsPath)) { Create.logger.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId); return; } @@ -123,6 +123,9 @@ public class ServerSchematicLoader { if (table == null) return; + // Delete schematic with same name + Files.deleteIfExists(uploadPath); + // Too many Schematics long count; try (Stream list = Files.list(Paths.get(playerPath))) { @@ -295,6 +298,9 @@ public class ServerSchematicLoader { return; try { + // Delete schematic with same name + Files.deleteIfExists(path); + // Too many Schematics long count; try (Stream list = Files.list(Paths.get(playerPath))) { From bc6513a098f3fb2007f365f23c9f222e5aef93c4 Mon Sep 17 00:00:00 2001 From: Paul Fulham Date: Sat, 21 Nov 2020 22:13:50 -0800 Subject: [PATCH 07/31] Limit schematic memory usage --- .../create/content/schematics/item/SchematicItem.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java index a07437758..1bef9185f 100644 --- a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java +++ b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java @@ -1,12 +1,14 @@ package com.simibubi.create.content.schematics.item; +import java.io.BufferedInputStream; +import java.io.DataInputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.List; +import java.util.zip.GZIPInputStream; import javax.annotation.Nonnull; @@ -27,6 +29,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTSizeTracker; import net.minecraft.nbt.NBTUtil; import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResultType; @@ -128,8 +131,9 @@ public class SchematicItem extends Item { if (!path.startsWith(dir)) return t; - try (InputStream stream = Files.newInputStream(path, StandardOpenOption.READ)) { - CompoundNBT nbt = CompressedStreamTools.readCompressed(stream); + try (DataInputStream stream = new DataInputStream(new BufferedInputStream( + new GZIPInputStream(Files.newInputStream(path, StandardOpenOption.READ))))) { + CompoundNBT nbt = CompressedStreamTools.read(stream, new NBTSizeTracker(0x20000000L)); t.read(nbt); } catch (IOException e) { LOGGER.warn("Failed to read schematic", e); From 2c3a866494bdd238ac50cbffab753cb2b00e4754 Mon Sep 17 00:00:00 2001 From: Snownee Date: Tue, 26 Jan 2021 14:43:33 +0800 Subject: [PATCH 08/31] Fix contraption sticky block connectivity. Add support to PUSH_ONLY push reaction --- .../BlockMovementTraits.java | 6 ++++++ .../structureMovement/Contraption.java | 20 +++++++++++++++---- .../piston/PistonContraption.java | 3 +++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java index 93a4dac0d..ad25a1b97 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java @@ -227,6 +227,12 @@ public class BlockMovementTraits { if (state.getBlock() instanceof SailBlock) return facing.getAxis() == state.get(SailBlock.FACING) .getAxis(); + if (AllBlocks.PISTON_EXTENSION_POLE.has(state)) + return facing.getAxis() != state.get(BlockStateProperties.FACING) + .getAxis(); + if (AllBlocks.MECHANICAL_PISTON_HEAD.has(state)) + return facing.getAxis() != state.get(BlockStateProperties.FACING) + .getAxis(); return isBrittle(state); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index bf4a6124f..bb4dadb7f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -59,6 +59,7 @@ import net.minecraft.block.ChestBlock; import net.minecraft.block.DoorBlock; import net.minecraft.block.IWaterLoggable; import net.minecraft.block.PressurePlateBlock; +import net.minecraft.block.material.PushReaction; import net.minecraft.entity.Entity; import net.minecraft.fluid.Fluids; import net.minecraft.fluid.IFluidState; @@ -240,7 +241,7 @@ public abstract class Contraption { fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote)); } - protected boolean moveBlock(World world, BlockPos pos, Direction forcedDirection, List frontier, + protected boolean moveBlock(World world, BlockPos pos, @Nullable Direction forcedDirection, List frontier, Set visited) { visited.add(pos); frontier.remove(pos); @@ -296,14 +297,13 @@ public abstract class Contraption { Map superglue = SuperGlueHandler.gatherGlue(world, pos); // Slime blocks and super glue drag adjacent blocks if possible - boolean isStickyBlock = state.isStickyBlock(); for (Direction offset : Iterate.directions) { BlockPos offsetPos = pos.offset(offset); BlockState blockState = world.getBlockState(offsetPos); if (isAnchoringBlockAt(offsetPos)) continue; if (!movementAllowed(world, offsetPos)) { - if (offset == forcedDirection && isStickyBlock) + if (offset == forcedDirection) return false; continue; } @@ -313,8 +313,20 @@ public abstract class Contraption { boolean blockAttachedTowardsFace = BlockMovementTraits.isBlockAttachedTowards(world, offsetPos, blockState, offset.getOpposite()); boolean brittle = BlockMovementTraits.isBrittle(blockState); + boolean canStick = !brittle && state.canStickTo(blockState) && blockState.canStickTo(state); + if (canStick) { + if (state.getPushReaction() == PushReaction.PUSH_ONLY || blockState.getPushReaction() == PushReaction.PUSH_ONLY) { + canStick = false; + } + if (BlockMovementTraits.notSupportive(state, offset)) { + canStick = false; + } + if (BlockMovementTraits.notSupportive(blockState, offset.getOpposite())) { + canStick = false; + } + } - if (!wasVisited && ((isStickyBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue)) + if (!wasVisited && (canStick || blockAttachedTowardsFace || faceHasGlue || (offset == forcedDirection && !BlockMovementTraits.notSupportive(state, forcedDirection)))) frontier.add(offsetPos); if (faceHasGlue) addGlue(superglue.get(offset)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java index 2895fb9bd..1e101fd94 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java @@ -8,6 +8,7 @@ import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.block.CarpetBlock; +import net.minecraft.block.material.PushReaction; import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.PistonType; @@ -164,6 +165,8 @@ public class PistonContraption extends TranslatingContraption { return true; if (!BlockMovementTraits.movementAllowed(world, currentPos)) return retracting; + if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY) + return true; frontier.add(currentPos); if (BlockMovementTraits.notSupportive(state, orientation)) return true; From 92a1395b147cbf1e204eb3ba480694836c2f9357 Mon Sep 17 00:00:00 2001 From: Snownee Date: Tue, 26 Jan 2021 15:26:01 +0800 Subject: [PATCH 09/31] Fix spectator can interact with blocks --- .../block/mechanicalArm/ArmInteractionPointHandler.java | 4 +++- .../behaviour/edgeInteraction/EdgeInteractionHandler.java | 2 +- .../tileEntity/behaviour/filtering/FilteringHandler.java | 2 +- .../foundation/tileEntity/behaviour/linked/LinkHandler.java | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPointHandler.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPointHandler.java index 7cf1e883b..a6d305883 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPointHandler.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPointHandler.java @@ -48,6 +48,9 @@ public class ArmInteractionPointHandler { World world = event.getWorld(); if (!world.isRemote) return; + PlayerEntity player = event.getPlayer(); + if (player != null && player.isSpectator()) + return; ArmInteractionPoint selected = getSelected(pos); @@ -60,7 +63,6 @@ public class ArmInteractionPointHandler { } selected.cycleMode(); - PlayerEntity player = event.getPlayer(); if (player != null) { String key = selected.mode == Mode.DEPOSIT ? "mechanical_arm.deposit_to" : "mechanical_arm.extract_from"; TextFormatting colour = selected.mode == Mode.DEPOSIT ? TextFormatting.GOLD : TextFormatting.AQUA; diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java index 3c7c90323..53124201c 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java @@ -37,7 +37,7 @@ public class EdgeInteractionHandler { Hand hand = event.getHand(); ItemStack heldItem = player.getHeldItem(hand); - if (player.isSneaking()) + if (player.isSneaking() || player.isSpectator()) return; EdgeInteractionBehaviour behaviour = TileEntityBehaviour.get(world, pos, EdgeInteractionBehaviour.TYPE); if (behaviour == null) diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java index dd605d425..d542f5039 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java @@ -43,7 +43,7 @@ public class FilteringHandler { PlayerEntity player = event.getPlayer(); Hand hand = event.getHand(); - if (player.isSneaking()) + if (player.isSneaking() || player.isSpectator()) return; FilteringBehaviour behaviour = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE); diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/linked/LinkHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/linked/LinkHandler.java index b7538fdd7..30a88de18 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/linked/LinkHandler.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/linked/LinkHandler.java @@ -28,7 +28,7 @@ public class LinkHandler { PlayerEntity player = event.getPlayer(); Hand hand = event.getHand(); - if (player.isSneaking()) + if (player.isSneaking() || player.isSpectator()) return; LinkBehaviour behaviour = TileEntityBehaviour.get(world, pos, LinkBehaviour.TYPE); From 8f7945ff4eff59d0de5f1eaab668bfb999d2e538 Mon Sep 17 00:00:00 2001 From: Snownee Date: Tue, 26 Jan 2021 16:48:03 +0800 Subject: [PATCH 10/31] Fix rope pulley breaking bedrock --- .../structureMovement/pulley/PulleyTileEntity.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index a416edadc..e2d4b7c0d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -48,6 +48,17 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { return; if (speed == 0) return; + int maxLength = AllConfigs.SERVER.kinetics.maxRopeLength.get(); + int i = 1; + while (i <= maxLength) { + BlockPos ropePos = pos.down(i); + BlockState ropeState = world.getBlockState(ropePos); + if (!AllBlocks.ROPE.has(ropeState) && !AllBlocks.PULLEY_MAGNET.has(ropeState)) { + break; + } + ++i; + } + offset = i - 1; if (offset >= getExtensionRange() && getSpeed() > 0) return; if (offset <= 0 && getSpeed() < 0) @@ -70,7 +81,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { if (!canAssembleStructure && getSpeed() > 0) return; - for (int i = ((int) offset); i > 0; i--) { + for (i = ((int) offset); i > 0; i--) { BlockPos offset = pos.down(i); BlockState oldState = world.getBlockState(offset); if (oldState.getBlock() instanceof IWaterLoggable && oldState.has(BlockStateProperties.WATERLOGGED) From b958be07123f136b33a9ae333641a31173f218bf Mon Sep 17 00:00:00 2001 From: Snownee Date: Tue, 26 Jan 2021 18:00:47 +0800 Subject: [PATCH 11/31] Fix desync of FilteringBehaviour --- .../tileEntity/behaviour/filtering/FilteringHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java index d542f5039..b71159441 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java @@ -75,12 +75,12 @@ public class FilteringHandler { if (event.getSide() != LogicalSide.CLIENT) { if (!player.isCreative()) { - if (behaviour.getFilter() - .getItem() instanceof FilterItem) - player.inventory.placeItemBackInInventory(world, behaviour.getFilter()); if (toApply.getItem() instanceof FilterItem) player.getHeldItem(hand) .shrink(1); + if (behaviour.getFilter() + .getItem() instanceof FilterItem) + player.inventory.placeItemBackInInventory(world, behaviour.getFilter()); } if (toApply.getItem() instanceof FilterItem) toApply.setCount(1); From 08a20972aa7f93bee34bf8b1f042b8628a646cf1 Mon Sep 17 00:00:00 2001 From: Snownee Date: Sat, 30 Jan 2021 18:51:44 +0800 Subject: [PATCH 12/31] Fix broken render state in RenderWorldLastEvent --- src/main/java/com/simibubi/create/events/ClientEvents.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index e3399d191..6ff99a9dc 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -1,6 +1,7 @@ package com.simibubi.create.events; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllFluids; import com.simibubi.create.Create; import com.simibubi.create.CreateClient; @@ -124,6 +125,7 @@ public class ClientEvents { CreateClient.outliner.renderOutlines(ms, buffer); // CollisionDebugger.render(ms, buffer); buffer.draw(); + RenderSystem.enableCull(); ms.pop(); } From 7221f72ddfac9a59ad78103cdf94b36c31117a4f Mon Sep 17 00:00:00 2001 From: Snownee Date: Sat, 30 Jan 2021 21:09:04 +0800 Subject: [PATCH 13/31] Optimize contraption assembling --- .../base/GeneratingKineticTileEntity.java | 2 +- .../BlockMovementTraits.java | 20 ++++----- .../structureMovement/Contraption.java | 45 ++++++++++--------- .../bearing/ClockworkContraption.java | 10 +++-- .../chassis/ChassisTileEntity.java | 11 ++--- .../glue/SuperGlueEntity.java | 2 +- .../mounted/MountedContraption.java | 13 +++--- .../piston/PistonContraption.java | 9 ++-- .../pulley/PulleyTileEntity.java | 5 ++- 9 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java index 279f177cc..fa0d6f017 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/GeneratingKineticTileEntity.java @@ -38,7 +38,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity { if (!(tileEntity instanceof KineticTileEntity)) return; KineticTileEntity sourceTe = (KineticTileEntity) tileEntity; - if (reActivateSource && sourceTe != null && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed())) + if (reActivateSource && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed())) reActivateSource = false; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java index ad25a1b97..aaaef728b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java @@ -53,8 +53,7 @@ import net.minecraft.world.World; public class BlockMovementTraits { - public static boolean movementNecessary(World world, BlockPos pos) { - BlockState state = world.getBlockState(pos); + public static boolean movementNecessary(BlockState state, World world, BlockPos pos) { if (isBrittle(state)) return true; if (state.getBlock() instanceof FenceGateBlock) @@ -68,18 +67,17 @@ public class BlockMovementTraits { return true; } - public static boolean movementAllowed(World world, BlockPos pos) { - BlockState blockState = world.getBlockState(pos); - Block block = blockState.getBlock(); + public static boolean movementAllowed(BlockState state, World world, BlockPos pos) { + Block block = state.getBlock(); if (block instanceof AbstractChassisBlock) return true; - if (blockState.getBlockHardness(world, pos) == -1) + if (state.getBlockHardness(world, pos) == -1) return false; - if (AllBlockTags.NON_MOVABLE.matches(blockState)) + if (AllBlockTags.NON_MOVABLE.matches(state)) return false; // Move controllers only when they aren't moving - if (block instanceof MechanicalPistonBlock && blockState.get(MechanicalPistonBlock.STATE) != PistonState.MOVING) + if (block instanceof MechanicalPistonBlock && state.get(MechanicalPistonBlock.STATE) != PistonState.MOVING) return true; if (block instanceof MechanicalBearingBlock) { TileEntity te = world.getTileEntity(pos); @@ -97,11 +95,11 @@ public class BlockMovementTraits { return !((PulleyTileEntity) te).running; } - if (AllBlocks.BELT.has(blockState)) + if (AllBlocks.BELT.has(state)) return true; - if (blockState.getBlock() instanceof GrindstoneBlock) + if (state.getBlock() instanceof GrindstoneBlock) return true; - return blockState.getPushReaction() != PushReaction.BLOCK; + return state.getPushReaction() != PushReaction.BLOCK; } /** diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index bb4dadb7f..8ed8f16fe 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -8,9 +8,11 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Queue; import java.util.Set; import java.util.UUID; import java.util.function.BiConsumer; @@ -148,7 +150,7 @@ public abstract class Contraption { } protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection, - List frontier) { + Queue frontier) { return true; } @@ -161,7 +163,7 @@ public abstract class Contraption { public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) { initialPassengers.clear(); - List frontier = new ArrayList<>(); + Queue frontier = new LinkedList<>(); Set visited = new HashSet<>(); anchor = pos; @@ -175,7 +177,7 @@ public abstract class Contraption { for (int limit = 100000; limit > 0; limit--) { if (frontier.isEmpty()) return true; - if (!moveBlock(world, frontier.remove(0), forcedDirection, frontier, visited)) + if (!moveBlock(world, forcedDirection, frontier, visited)) return false; } return false; @@ -241,20 +243,22 @@ public abstract class Contraption { fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote)); } - protected boolean moveBlock(World world, BlockPos pos, @Nullable Direction forcedDirection, List frontier, + protected boolean moveBlock(World world, @Nullable Direction forcedDirection, Queue frontier, Set visited) { + BlockPos pos = frontier.poll(); + if (pos == null) + return false; visited.add(pos); - frontier.remove(pos); if (!world.isBlockPresent(pos)) return false; if (isAnchoringBlockAt(pos)) return true; - if (!BlockMovementTraits.movementNecessary(world, pos)) - return true; - if (!movementAllowed(world, pos)) - return false; BlockState state = world.getBlockState(pos); + if (!BlockMovementTraits.movementNecessary(state, world, pos)) + return true; + if (!movementAllowed(state, world, pos)) + return false; if (state.getBlock() instanceof AbstractChassisBlock && !moveChassis(world, pos, forcedDirection, frontier, visited)) return false; @@ -290,9 +294,10 @@ public abstract class Contraption { } // Cart assemblers attach themselves - BlockState stateBelow = world.getBlockState(pos.down()); - if (!visited.contains(pos.down()) && AllBlocks.CART_ASSEMBLER.has(stateBelow)) - frontier.add(pos.down()); + BlockPos posDown = pos.down(); + BlockState stateBelow = world.getBlockState(posDown); + if (!visited.contains(posDown) && AllBlocks.CART_ASSEMBLER.has(stateBelow)) + frontier.add(posDown); Map superglue = SuperGlueHandler.gatherGlue(world, pos); @@ -302,7 +307,7 @@ public abstract class Contraption { BlockState blockState = world.getBlockState(offsetPos); if (isAnchoringBlockAt(offsetPos)) continue; - if (!movementAllowed(world, offsetPos)) { + if (!movementAllowed(blockState, world, offsetPos)) { if (offset == forcedDirection) return false; continue; @@ -336,7 +341,7 @@ public abstract class Contraption { return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); } - private void moveBearing(BlockPos pos, List frontier, Set visited, BlockState state) { + private void moveBearing(BlockPos pos, Queue frontier, Set visited, BlockState state) { Direction facing = state.get(MechanicalBearingBlock.FACING); if (!canAxisBeStabilized(facing.getAxis())) { BlockPos offset = pos.offset(facing); @@ -347,7 +352,7 @@ public abstract class Contraption { pendingSubContraptions.add(new BlockFace(pos, facing)); } - private void moveBelt(BlockPos pos, List frontier, Set visited, BlockState state) { + private void moveBelt(BlockPos pos, Queue frontier, Set visited, BlockState state) { BlockPos nextPos = BeltBlock.nextSegmentPosition(state, pos, true); BlockPos prevPos = BeltBlock.nextSegmentPosition(state, pos, false); if (nextPos != null && !visited.contains(nextPos)) @@ -368,7 +373,7 @@ public abstract class Contraption { } } - private void movePulley(World world, BlockPos pos, List frontier, Set visited) { + private void movePulley(World world, BlockPos pos, Queue frontier, Set visited) { int limit = AllConfigs.SERVER.kinetics.maxRopeLength.get(); BlockPos ropePos = pos; while (limit-- >= 0) { @@ -386,7 +391,7 @@ public abstract class Contraption { } } - private boolean moveMechanicalPiston(World world, BlockPos pos, List frontier, Set visited, + private boolean moveMechanicalPiston(World world, BlockPos pos, Queue frontier, Set visited, BlockState state) { int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); Direction direction = state.get(MechanicalPistonBlock.FACING); @@ -432,7 +437,7 @@ public abstract class Contraption { return true; } - private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List frontier, + private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, Queue frontier, Set visited) { TileEntity te = world.getTileEntity(pos); if (!(te instanceof ChassisTileEntity)) @@ -517,8 +522,8 @@ public abstract class Contraption { return globalPos.subtract(anchor); } - protected boolean movementAllowed(World world, BlockPos pos) { - return BlockMovementTraits.movementAllowed(world, pos); + protected boolean movementAllowed(BlockState state, World world, BlockPos pos) { + return BlockMovementTraits.movementAllowed(state, world, pos); } protected boolean isAnchoringBlockAt(BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java index 31b7709f3..785a4c2ad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java @@ -1,7 +1,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.bearing; import java.util.HashSet; -import java.util.List; +import java.util.Queue; import java.util.Set; import org.apache.commons.lang3.tuple.Pair; @@ -92,11 +92,13 @@ public class ClockworkContraption extends Contraption { } @Override - protected boolean moveBlock(World world, BlockPos pos, Direction direction, List frontier, + protected boolean moveBlock(World world, Direction direction, Queue frontier, Set visited) { - if (ignoreBlocks.contains(pos)) + if (ignoreBlocks.contains(frontier.peek())) { + frontier.poll(); return true; - return super.moveBlock(world, pos, direction, frontier, visited); + } + return super.moveBlock(world, direction, frontier, visited); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java index 832b656da..fcb4f1c1b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java @@ -7,6 +7,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Queue; import java.util.Set; import com.simibubi.create.AllBlocks; @@ -76,12 +77,12 @@ public class ChassisTileEntity extends SmartTileEntity { } public List collectChassisGroup() { - List frontier = new ArrayList<>(); + Queue frontier = new LinkedList<>(); List collected = new ArrayList<>(); Set visited = new HashSet<>(); frontier.add(pos); while (!frontier.isEmpty()) { - BlockPos current = frontier.remove(0); + BlockPos current = frontier.poll(); if (visited.contains(current)) continue; visited.add(current); @@ -96,7 +97,7 @@ public class ChassisTileEntity extends SmartTileEntity { return collected; } - public boolean addAttachedChasses(List frontier, Set visited) { + public boolean addAttachedChasses(Queue frontier, Set visited) { BlockState state = getBlockState(); if (!(state.getBlock() instanceof AbstractChassisBlock)) return false; @@ -166,7 +167,7 @@ public class ChassisTileEntity extends SmartTileEntity { break; // Ignore replaceable Blocks and Air-like - if (!BlockMovementTraits.movementNecessary(world, current)) + if (!BlockMovementTraits.movementNecessary(currentState, world, current)) break; if (BlockMovementTraits.isBrittle(currentState)) break; @@ -207,7 +208,7 @@ public class ChassisTileEntity extends SmartTileEntity { continue; if (!searchPos.withinDistance(pos, chassisRange + .5f)) continue; - if (!BlockMovementTraits.movementNecessary(world, searchPos)) + if (!BlockMovementTraits.movementNecessary(searchedState, world, searchPos)) continue; if (BlockMovementTraits.isBrittle(searchedState)) continue; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java index f677487af..eba72ea54 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java @@ -180,7 +180,7 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat BlockState state = world.getBlockState(pos); if (BlockMovementTraits.isBlockAttachedTowards(world, pos, state, direction)) return true; - if (!BlockMovementTraits.movementNecessary(world, pos)) + if (!BlockMovementTraits.movementNecessary(state, world, pos)) return false; if (BlockMovementTraits.notSupportive(state, direction)) return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java index 3d6a28dd8..b8b219a5b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java @@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo import static com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock.RAIL_SHAPE; -import java.util.List; +import java.util.Queue; import org.apache.commons.lang3.tuple.Pair; @@ -70,7 +70,7 @@ public class MountedContraption extends Contraption { } @Override - protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List frontier) { + protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, Queue frontier) { frontier.clear(); frontier.add(pos.up()); return true; @@ -104,11 +104,10 @@ public class MountedContraption extends Contraption { } @Override - protected boolean movementAllowed(World world, BlockPos pos) { - BlockState blockState = world.getBlockState(pos); - if (!pos.equals(anchor) && AllBlocks.CART_ASSEMBLER.has(blockState)) - return testSecondaryCartAssembler(world, blockState, pos); - return super.movementAllowed(world, pos); + protected boolean movementAllowed(BlockState state, World world, BlockPos pos) { + if (!pos.equals(anchor) && AllBlocks.CART_ASSEMBLER.has(state)) + return testSecondaryCartAssembler(world, state, pos); + return super.movementAllowed(state, world, pos); } protected boolean testSecondaryCartAssembler(World world, BlockState state, BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java index 1e101fd94..0eada3483 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java @@ -23,6 +23,7 @@ import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; import java.util.List; +import java.util.Queue; import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD; import static com.simibubi.create.AllBlocks.PISTON_EXTENSION_POLE; @@ -144,7 +145,7 @@ public class PistonContraption extends TranslatingContraption { } @Override - protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List frontier) { + protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, Queue frontier) { frontier.clear(); boolean sticky = isStickyPiston(world.getBlockState(pos.offset(orientation, -1))); boolean retracting = direction != orientation; @@ -156,14 +157,14 @@ public class PistonContraption extends TranslatingContraption { BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress); if (!world.isBlockPresent(currentPos)) return false; - if (!BlockMovementTraits.movementNecessary(world, currentPos)) - return true; BlockState state = world.getBlockState(currentPos); + if (!BlockMovementTraits.movementNecessary(state, world, currentPos)) + return true; if (BlockMovementTraits.isBrittle(state) && !(state.getBlock() instanceof CarpetBlock)) return true; if (isPistonHead(state) && state.get(FACING) == direction.getOpposite()) return true; - if (!BlockMovementTraits.movementAllowed(world, currentPos)) + if (!BlockMovementTraits.movementAllowed(state, world, currentPos)) return retracting; if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY) return true; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index e2d4b7c0d..54cee9d6a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -176,9 +176,10 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { return; BlockPos posBelow = pos.down((int) (offset + getMovementSpeed()) + 1); - if (!BlockMovementTraits.movementNecessary(world, posBelow)) + BlockState state = world.getBlockState(posBelow); + if (!BlockMovementTraits.movementNecessary(state, world, posBelow)) return; - if (BlockMovementTraits.isBrittle(world.getBlockState(posBelow))) + if (BlockMovementTraits.isBrittle(state)) return; disassemble(); From c77e7c28d7fc666051ab27e0550501690322c491 Mon Sep 17 00:00:00 2001 From: Snownee Date: Sat, 30 Jan 2021 21:14:58 +0800 Subject: [PATCH 14/31] Fix gauge not rendering behind door --- .../create/content/contraptions/relays/gauge/GaugeBlock.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java index 1580b553e..fa8fe2f0b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeBlock.java @@ -14,7 +14,6 @@ import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.block.material.Material; import net.minecraft.block.material.MaterialColor; import net.minecraft.item.BlockItemUseContext; import net.minecraft.particles.RedstoneParticleData; @@ -114,6 +113,7 @@ public class GaugeBlock extends DirectionalAxisKineticBlock { return context.getFace(); } + @Override protected boolean getAxisAlignmentForPlacement(BlockItemUseContext context) { return context.getPlacementHorizontalFacing().getAxis() != Axis.X; } @@ -127,8 +127,7 @@ public class GaugeBlock extends DirectionalAxisKineticBlock { return false; if (getRotationAxis(state) == Axis.Y && face != state.get(FACING)) return false; - BlockState blockState = world.getBlockState(pos.offset(face)); - if (Block.hasSolidSide(blockState, world, pos, face.getOpposite()) && blockState.getMaterial() != Material.GLASS + if (!Block.shouldSideBeRendered(state, world, pos, face) && !(world instanceof WrappedWorld)) return false; return true; From 3525ce49ce9b7afba5e5ffb38edf439774de7cbe Mon Sep 17 00:00:00 2001 From: Snownee Date: Sun, 31 Jan 2021 02:12:31 +0800 Subject: [PATCH 15/31] Player Feedback, Part I --- .../structureMovement/AssemblyException.java | 23 +++++++++++++++ .../structureMovement/Contraption.java | 28 +++++++++++++------ .../bearing/BearingContraption.java | 3 +- .../bearing/ClockworkBearingTileEntity.java | 27 ++++++++++++++++-- .../bearing/ClockworkContraption.java | 5 ++-- .../bearing/MechanicalBearingTileEntity.java | 24 +++++++++++++++- .../bearing/StabilizedContraption.java | 3 +- .../mounted/CartAssemblerBlock.java | 14 ++++++++-- .../mounted/CartAssemblerTileEntity.java | 11 +++++++- .../mounted/MountedContraption.java | 3 +- .../piston/LinearActuatorTileEntity.java | 26 +++++++++++++++-- .../piston/MechanicalPistonTileEntity.java | 3 +- .../piston/PistonContraption.java | 18 ++++++++---- .../pulley/PulleyContraption.java | 3 +- .../pulley/PulleyTileEntity.java | 10 ++++++- 15 files changed, 169 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java new file mode 100644 index 000000000..67e595602 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java @@ -0,0 +1,23 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; + +public class AssemblyException extends RuntimeException { + public final ITextComponent message; + + public AssemblyException(ITextComponent message) { + this.message = message; + } + + public AssemblyException(String langKey, Object... objects) { + this(new TranslationTextComponent("gui.goggles.contraptions." + langKey, objects)); + } + + public static AssemblyException unmovableBlock(BlockPos pos, BlockState state) { + return new AssemblyException("unmovableBlock", pos.getX(), pos.getY(), pos.getZ(), + new TranslationTextComponent(state.getBlock().getTranslationKey())); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 8ed8f16fe..e2344c503 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -135,7 +135,7 @@ public abstract class Contraption { stabilizedSubContraptions = new HashMap<>(); } - public abstract boolean assemble(World world, BlockPos pos); + public abstract boolean assemble(World world, BlockPos pos) throws AssemblyException; protected abstract boolean canAxisBeStabilized(Axis axis); @@ -180,7 +180,7 @@ public abstract class Contraption { if (!moveBlock(world, forcedDirection, frontier, visited)) return false; } - return false; + throw new AssemblyException("structureTooLarge"); } public void onEntityCreated(AbstractContraptionEntity entity) { @@ -192,8 +192,12 @@ public abstract class Contraption { StabilizedContraption subContraption = new StabilizedContraption(face); World world = entity.world; BlockPos pos = blockFace.getPos(); - if (!subContraption.assemble(world, pos)) + try { + if (!subContraption.assemble(world, pos)) + continue; + } catch (AssemblyException e) { continue; + } subContraption.removeBlocksFromWorld(world, BlockPos.ZERO); OrientedContraptionEntity movedContraption = OrientedContraptionEntity.create(world, subContraption, Optional.of(face)); @@ -243,6 +247,7 @@ public abstract class Contraption { fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote)); } + /** move the first block in frontier queue */ protected boolean moveBlock(World world, @Nullable Direction forcedDirection, Queue frontier, Set visited) { BlockPos pos = frontier.poll(); @@ -250,15 +255,17 @@ public abstract class Contraption { return false; visited.add(pos); + if (World.isOutsideBuildHeight(pos)) + return true; if (!world.isBlockPresent(pos)) - return false; + throw new AssemblyException("chunkNotLoaded"); if (isAnchoringBlockAt(pos)) return true; BlockState state = world.getBlockState(pos); if (!BlockMovementTraits.movementNecessary(state, world, pos)) return true; if (!movementAllowed(state, world, pos)) - return false; + throw AssemblyException.unmovableBlock(pos, state); if (state.getBlock() instanceof AbstractChassisBlock && !moveChassis(world, pos, forcedDirection, frontier, visited)) return false; @@ -309,7 +316,7 @@ public abstract class Contraption { continue; if (!movementAllowed(blockState, world, offsetPos)) { if (offset == forcedDirection) - return false; + throw AssemblyException.unmovableBlock(pos, state); continue; } @@ -338,7 +345,10 @@ public abstract class Contraption { } addBlock(pos, capture(world, pos)); - return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); + if (blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get()) + return true; + else + throw new AssemblyException("structureTooLarge"); } private void moveBearing(BlockPos pos, Queue frontier, Set visited, BlockState state) { @@ -414,7 +424,7 @@ public abstract class Contraption { break; } if (limit <= -1) - return false; + throw new AssemblyException("tooManyPistonPoles"); } BlockPos searchPos = pos; @@ -433,7 +443,7 @@ public abstract class Contraption { } if (limit <= -1) - return false; + throw new AssemblyException("tooManyPistonPoles"); return true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java index 76db5bd8b..135a94ea0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java @@ -4,6 +4,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllTags.AllBlockTags; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import net.minecraft.nbt.CompoundNBT; @@ -29,7 +30,7 @@ public class BearingContraption extends Contraption { } @Override - public boolean assemble(World world, BlockPos pos) { + public boolean assemble(World world, BlockPos pos) throws AssemblyException { BlockPos offset = pos.offset(facing); if (!searchMovedStructure(world, offset, null)) return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java index aa465f4e9..35a036a50 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java @@ -6,6 +6,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkContraption.HandType; import com.simibubi.create.foundation.advancement.AllTriggers; @@ -25,6 +26,7 @@ import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.ITextComponent; public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity { @@ -37,6 +39,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe protected boolean running; protected boolean assembleNextTick; + protected ITextComponent lastException; protected ScrollOptionBehaviour operationMode; @@ -199,8 +202,14 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe Direction direction = getBlockState().get(BlockStateProperties.FACING); // Collect Construct - Pair contraption = - ClockworkContraption.assembleClockworkAt(world, pos, direction); + Pair contraption; + try { + contraption = ClockworkContraption.assembleClockworkAt(world, pos, direction); + lastException = null; + } catch (AssemblyException e) { + lastException = e.message; + return; + } if (contraption == null) return; if (contraption.getLeft() == null) @@ -284,6 +293,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe compound.putBoolean("Running", running); compound.putFloat("HourAngle", hourAngle); compound.putFloat("MinuteAngle", minuteAngle); + if (lastException != null) + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); super.write(compound, clientPacket); } @@ -295,6 +306,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe running = compound.getBoolean("Running"); hourAngle = compound.getFloat("HourAngle"); minuteAngle = compound.getFloat("MinuteAngle"); + if (compound.contains("LastException")) + lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + else + lastException = null; super.read(compound, clientPacket); if (!clientPacket) @@ -393,4 +408,12 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe return pos; } + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); + if (lastException != null) + tooltip.add(lastException.getFormattedText()); + return lastException != null || added; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java index 785a4c2ad..be481d66e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java @@ -7,6 +7,7 @@ import java.util.Set; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.foundation.utility.NBTHelper; @@ -39,7 +40,7 @@ public class ClockworkContraption extends Contraption { } public static Pair assembleClockworkAt(World world, BlockPos pos, - Direction direction) { + Direction direction) throws AssemblyException { int hourArmBlocks = 0; ClockworkContraption hourArm = new ClockworkContraption(); @@ -82,7 +83,7 @@ public class ClockworkContraption extends Contraption { } @Override - public boolean assemble(World world, BlockPos pos) { + public boolean assemble(World world, BlockPos pos) throws AssemblyException { return searchMovedStructure(world, pos, facing); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java index b4dde3bc4..1bb979484 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java @@ -6,6 +6,7 @@ import java.util.List; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.item.TooltipHelper; @@ -22,6 +23,7 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.ITextComponent; public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity { @@ -31,6 +33,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp protected boolean running; protected boolean assembleNextTick; protected float clientAngleDiff; + protected ITextComponent lastException; public MechanicalBearingTileEntity(TileEntityType type) { super(type); @@ -62,6 +65,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public void write(CompoundNBT compound, boolean clientPacket) { compound.putBoolean("Running", running); compound.putFloat("Angle", angle); + if (lastException != null) + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); super.write(compound, clientPacket); } @@ -70,6 +75,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp float angleBefore = angle; running = compound.getBoolean("Running"); angle = compound.getFloat("Angle"); + if (compound.contains("LastException")) + lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + else + lastException = null; super.read(compound, clientPacket); if (!clientPacket) return; @@ -120,8 +129,14 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp Direction direction = getBlockState().get(FACING); BearingContraption contraption = new BearingContraption(isWindmill(), direction); - if (!contraption.assemble(world, pos)) + try { + lastException = null; + if (!contraption.assemble(world, pos)) + return; + } catch (AssemblyException e) { + lastException = e.message; return; + } if (isWindmill()) AllTriggers.triggerForNearbyPlayers(AllTriggers.WINDMILL, world, pos, 5); @@ -282,4 +297,11 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp return true; } + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); + if (lastException != null) + tooltip.add(lastException.getFormattedText()); + return lastException != null || added; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java index f54d09beb..3e5aaab58 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.bearing; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import net.minecraft.nbt.CompoundNBT; @@ -20,7 +21,7 @@ public class StabilizedContraption extends Contraption { } @Override - public boolean assemble(World world, BlockPos pos) { + public boolean assemble(World world, BlockPos pos) throws AssemblyException { BlockPos offset = pos.offset(facing); if (!searchMovedStructure(world, offset, null)) return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java index 49c337697..5813f6afe 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingHandler; @@ -229,13 +230,20 @@ public class CartAssemblerBlock extends AbstractRailBlock .isCoupledThroughContraption()) return; - CartMovementMode mode = - getTileEntityOptional(world, pos).map(te -> CartMovementMode.values()[te.movementMode.value]) + + Optional assembler = getTileEntityOptional(world, pos); + CartMovementMode mode = assembler.map(te -> CartMovementMode.values()[te.movementMode.value]) .orElse(CartMovementMode.ROTATE); MountedContraption contraption = new MountedContraption(mode); - if (!contraption.assemble(world, pos)) + try { + assembler.ifPresent(te -> te.lastException = null); + if (!contraption.assemble(world, pos)) + return; + } catch (AssemblyException e) { + assembler.ifPresent(te -> te.lastException = e.message); return; + } boolean couplingFound = contraption.connectedCart != null; Optional initialOrientation = cart.getMotion() diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java index 4e98a97be..6e1c3be7a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mo import java.util.List; +import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -16,12 +17,14 @@ import net.minecraft.state.properties.RailShape; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; -public class CartAssemblerTileEntity extends SmartTileEntity { +public class CartAssemblerTileEntity extends SmartTileEntity implements IHaveGoggleInformation { private static final int assemblyCooldown = 8; protected ScrollOptionBehaviour movementMode; private int ticksSinceMinecartUpdate; + protected ITextComponent lastException; //TODO public CartAssemblerTileEntity(TileEntityType type) { super(type); @@ -104,4 +107,10 @@ public class CartAssemblerTileEntity extends SmartTileEntity { return ticksSinceMinecartUpdate >= assemblyCooldown; } + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + if (lastException != null) + tooltip.add(lastException.getFormattedText()); + return lastException != null; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java index b8b219a5b..a38ad48fe 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java @@ -8,6 +8,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; import com.simibubi.create.foundation.utility.Iterate; @@ -52,7 +53,7 @@ public class MountedContraption extends Contraption { } @Override - public boolean assemble(World world, BlockPos pos) { + public boolean assemble(World world, BlockPos pos) throws AssemblyException { BlockState state = world.getBlockState(pos); if (!state.has(RAIL_SHAPE)) return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java index 603f5b5e6..e92f2d807 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java @@ -4,6 +4,7 @@ import java.util.List; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.IControlContraption; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -17,6 +18,7 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption { @@ -27,6 +29,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme protected boolean forceMove; protected ScrollOptionBehaviour movementMode; protected boolean waitingForSpeedChange; + protected ITextComponent lastException; // Custom position sync protected float clientOffsetDiff; @@ -80,7 +83,12 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme return; } else { if (getSpeed() != 0) - assemble(); + try { + assemble(); + lastException = null; + } catch (AssemblyException e) { + lastException = e.message; + } } return; } @@ -153,6 +161,8 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme compound.putBoolean("Running", running); compound.putBoolean("Waiting", waitingForSpeedChange); compound.putFloat("Offset", offset); + if (lastException != null) + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); super.write(compound, clientPacket); if (clientPacket && forceMove) { @@ -169,6 +179,10 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme running = compound.getBoolean("Running"); waitingForSpeedChange = compound.getBoolean("Waiting"); offset = compound.getFloat("Offset"); + if (compound.contains("LastException")) + lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + else + lastException = null; super.read(compound, clientPacket); if (!clientPacket) @@ -185,7 +199,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme public abstract void disassemble(); - protected abstract void assemble(); + protected abstract void assemble() throws AssemblyException; protected abstract int getExtensionRange(); @@ -289,4 +303,12 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme return pos; } + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); + if (lastException != null) + tooltip.add(lastException.getFormattedText()); + return lastException != null || added; + } + } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/MechanicalPistonTileEntity.java index f84a04b97..b04120c7d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/MechanicalPistonTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/MechanicalPistonTileEntity.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pi import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.IRotate; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.DirectionalExtenderScrollOptionSlot; @@ -41,7 +42,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { } @Override - public void assemble() { + public void assemble() throws AssemblyException { if (!(world.getBlockState(pos) .getBlock() instanceof MechanicalPistonBlock)) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java index 0eada3483..39a48d58e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.piston; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.*; @@ -52,7 +53,7 @@ public class PistonContraption extends TranslatingContraption { } @Override - public boolean assemble(World world, BlockPos pos) { + public boolean assemble(World world, BlockPos pos) throws AssemblyException { if (!collectExtensions(world, pos, orientation)) return false; int count = blocks.size(); @@ -90,7 +91,7 @@ public class PistonContraption extends TranslatingContraption { nextBlock = world.getBlockState(actualStart.offset(direction)); if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles()) - return false; + throw new AssemblyException("tooManyPistonPoles"); } } @@ -113,7 +114,7 @@ public class PistonContraption extends TranslatingContraption { nextBlock = world.getBlockState(end.offset(direction.getOpposite())); if (extensionsInFront + extensionsInBack > MechanicalPistonBlock.maxAllowedPistonPoles()) - return false; + throw new AssemblyException("tooManyPistonPoles"); } anchor = pos.offset(direction, initialExtensionProgress + 1); @@ -125,7 +126,7 @@ public class PistonContraption extends TranslatingContraption { 1, 1); if (extensionLength == 0) - return false; + throw new AssemblyException("noPistonPoles"); bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0); @@ -155,8 +156,10 @@ public class PistonContraption extends TranslatingContraption { if (offset == 1 && retracting) return true; BlockPos currentPos = pos.offset(orientation, offset + initialExtensionProgress); + if (retracting && World.isOutsideBuildHeight(currentPos)) + return true; if (!world.isBlockPresent(currentPos)) - return false; + throw new AssemblyException("chunkNotLoaded"); BlockState state = world.getBlockState(currentPos); if (!BlockMovementTraits.movementNecessary(state, world, currentPos)) return true; @@ -165,7 +168,10 @@ public class PistonContraption extends TranslatingContraption { if (isPistonHead(state) && state.get(FACING) == direction.getOpposite()) return true; if (!BlockMovementTraits.movementAllowed(state, world, currentPos)) - return retracting; + if (retracting) + return true; + else + throw AssemblyException.unmovableBlock(currentPos, state); if (retracting && state.getPushReaction() == PushReaction.PUSH_ONLY) return true; frontier.add(currentPos); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java index d4a48a889..4453fdadd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pulley; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; import net.minecraft.nbt.CompoundNBT; @@ -23,7 +24,7 @@ public class PulleyContraption extends TranslatingContraption { } @Override - public boolean assemble(World world, BlockPos pos) { + public boolean assemble(World world, BlockPos pos) throws AssemblyException { if (!searchMovedStructure(world, pos, null)) return false; startMoving(world); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index 54cee9d6a..b1894d543 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pulley; import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; @@ -22,6 +23,7 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; public class PulleyTileEntity extends LinearActuatorTileEntity { @@ -42,7 +44,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { } @Override - protected void assemble() { + protected void assemble() throws AssemblyException { if (!(world.getBlockState(pos) .getBlock() instanceof PulleyBlock)) return; @@ -189,12 +191,18 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { @Override protected void read(CompoundNBT compound, boolean clientPacket) { initialOffset = compound.getInt("InitialOffset"); + if (compound.contains("LastException")) + lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + else + lastException = null; super.read(compound, clientPacket); } @Override public void write(CompoundNBT compound, boolean clientPacket) { compound.putInt("InitialOffset", initialOffset); + if (lastException != null) + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); super.write(compound, clientPacket); } From c5447d5b9cea85f32013bcd1f111dd5a983286c4 Mon Sep 17 00:00:00 2001 From: Snownee Date: Sun, 31 Jan 2021 14:56:46 +0800 Subject: [PATCH 16/31] Add NBTProcessors to enable detailed control to tile data. Add safe check when contraption blocks adding back to world --- .../data/create/tags/blocks/safe_nbt.json | 3 +- .../java/com/simibubi/create/AllTags.java | 2 + .../category/MechanicalCraftingCategory.java | 1 - .../components/fan/EncasedFanBlock.java | 1 - .../structureMovement/Contraption.java | 6 +- .../fluids/actors/SpoutTileEntity.java | 2 - .../curiosities/zapper/ZapperItem.java | 22 ++++--- .../zapper/blockzapper/BlockzapperItem.java | 2 +- .../zapper/terrainzapper/TerrainTools.java | 8 +-- .../block/redstone/RedstoneLinkBlock.java | 1 - .../schematics/SchematicProcessor.java | 9 ++- .../schematics/ServerSchematicLoader.java | 3 - .../block/SchematicannonTileEntity.java | 4 +- .../schematics/item/SchematicItem.java | 2 +- .../packet/SchematicPlacePacket.java | 3 + .../foundation/utility/FilesHelper.java | 1 - .../foundation/utility/NBTProcessors.java | 57 +++++++++++++++++++ 17 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java diff --git a/src/generated/resources/data/create/tags/blocks/safe_nbt.json b/src/generated/resources/data/create/tags/blocks/safe_nbt.json index 78c06756f..d834c9f41 100644 --- a/src/generated/resources/data/create/tags/blocks/safe_nbt.json +++ b/src/generated/resources/data/create/tags/blocks/safe_nbt.json @@ -23,6 +23,7 @@ "create:redstone_link", "create:analog_lever", "create:adjustable_repeater", - "create:adjustable_pulse_repeater" + "create:adjustable_pulse_repeater", + "#minecraft:signs" ] } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/AllTags.java b/src/main/java/com/simibubi/create/AllTags.java index fb7675b88..71bf7c9d2 100644 --- a/src/main/java/com/simibubi/create/AllTags.java +++ b/src/main/java/com/simibubi/create/AllTags.java @@ -187,5 +187,7 @@ public class AllTags { AllBlockTags.FAN_TRANSPARENT.add(Blocks.IRON_BARS); AllBlockTags.FAN_HEATERS.add(Blocks.MAGMA_BLOCK, Blocks.CAMPFIRE, Blocks.LAVA, Blocks.FIRE); + + AllBlockTags.SAFE_NBT.includeAll(BlockTags.SIGNS); } } diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java index ee3d7c168..db01bbd08 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java @@ -8,7 +8,6 @@ import java.util.stream.Collectors; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlocks; import com.simibubi.create.compat.jei.category.animations.AnimatedCrafter; -import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics; import com.simibubi.create.foundation.gui.AllGuiTextures; import mezz.jei.api.constants.VanillaTypes; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java index 27e3107b7..5d8a6faa4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java @@ -1,6 +1,5 @@ package com.simibubi.create.content.contraptions.components.fan; -import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index bf4a6124f..4f8ae92c3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -48,6 +48,7 @@ import com.simibubi.create.foundation.fluid.CombinedTankWrapper; import com.simibubi.create.foundation.utility.BlockFace; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.NBTProcessors; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; @@ -797,6 +798,8 @@ public abstract class Contraption { TileEntity tileEntity = world.getTileEntity(targetPos); CompoundNBT tag = block.nbt; + if (tileEntity != null) + tag = NBTProcessors.process(tileEntity, tag, false); if (tileEntity != null && tag != null) { tag.putInt("x", targetPos.getX()); tag.putInt("y", targetPos.getY()); @@ -828,7 +831,8 @@ public abstract class Contraption { } for (BlockInfo block : blocks.values()) { BlockPos targetPos = transform.apply(block.pos); - world.markAndNotifyBlock(targetPos, null, block.state, block.state, BlockFlags.IS_MOVING | BlockFlags.DEFAULT); + BlockState state = world.getBlockState(targetPos); + world.markAndNotifyBlock(targetPos, null, state, state, BlockFlags.IS_MOVING | BlockFlags.DEFAULT); } for (int i = 0; i < inventory.getSlots(); i++) diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java index 564ae6a33..f7f4e3d73 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/SpoutTileEntity.java @@ -21,9 +21,7 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.item.ItemStack; import net.minecraft.item.PotionItem; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.particles.BlockParticleData; import net.minecraft.particles.IParticleData; -import net.minecraft.particles.ParticleTypes; import net.minecraft.potion.PotionUtils; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java index 7dfb7dc06..13ed0a475 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java @@ -10,6 +10,7 @@ import com.simibubi.create.foundation.item.ItemDescription; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.NBTProcessors; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -115,7 +116,7 @@ public abstract class ZapperItem extends Item { }); applyCooldown(player, item, false); } - return new ActionResult(ActionResultType.SUCCESS, item); + return new ActionResult<>(ActionResultType.SUCCESS, item); } boolean mainHand = hand == Hand.MAIN_HAND; @@ -125,7 +126,7 @@ public abstract class ZapperItem extends Item { // Pass To Offhand if (mainHand && isSwap && gunInOtherHand) - return new ActionResult(ActionResultType.FAIL, item); + return new ActionResult<>(ActionResultType.FAIL, item); if (mainHand && !isSwap && gunInOtherHand) item.getTag() .putBoolean("_Swap", true); @@ -144,7 +145,7 @@ public abstract class ZapperItem extends Item { world.playSound(player, player.getPosition(), AllSoundEvents.BLOCKZAPPER_DENY.get(), SoundCategory.BLOCKS, 1f, 0.5f); player.sendStatusMessage(msg.applyTextStyle(TextFormatting.RED), true); - return new ActionResult(ActionResultType.FAIL, item); + return new ActionResult<>(ActionResultType.FAIL, item); } BlockState stateToUse = Blocks.AIR.getDefaultState(); @@ -169,7 +170,7 @@ public abstract class ZapperItem extends Item { // No target if (pos == null || stateReplaced.getBlock() == Blocks.AIR) { applyCooldown(player, item, gunInOtherHand); - return new ActionResult(ActionResultType.SUCCESS, item); + return new ActionResult<>(ActionResultType.SUCCESS, item); } // Find exact position of gun barrel for VFX @@ -183,7 +184,7 @@ public abstract class ZapperItem extends Item { // Client side if (world.isRemote) { ZapperRenderHandler.dontAnimateItem(hand); - return new ActionResult(ActionResultType.SUCCESS, item); + return new ActionResult<>(ActionResultType.SUCCESS, item); } // Server side @@ -195,7 +196,7 @@ public abstract class ZapperItem extends Item { new ZapperBeamPacket(barrelPos, raytrace.getHitVec(), hand, true)); } - return new ActionResult(ActionResultType.SUCCESS, item); + return new ActionResult<>(ActionResultType.SUCCESS, item); } public ITextComponent validateUsage(ItemStack item) { @@ -240,10 +241,13 @@ public abstract class ZapperItem extends Item { return UseAction.NONE; } - public static void setTileData(World world, BlockPos pos, CompoundNBT data) { - if (data != null) { + public static void setTileData(World world, BlockPos pos, BlockState state, CompoundNBT data) { + if (data != null && AllBlockTags.SAFE_NBT.matches(state)) { TileEntity tile = world.getTileEntity(pos); - if (tile != null && !tile.onlyOpsCanSetNbt()) { + if (tile != null) { + data = NBTProcessors.process(tile, data, true); + if (data == null) + return; data.putInt("x", pos.getX()); data.putInt("y", pos.getY()); data.putInt("z", pos.getZ()); diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java index 5e27ad20c..954d06daf 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java @@ -135,7 +135,7 @@ public class BlockzapperItem extends ZapperItem { blocksnapshot.restore(true, false); return false; } - setTileData(world, placed, data); + setTileData(world, placed, state, data); if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) { ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player; diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java index 51401b113..abd142734 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java @@ -47,7 +47,7 @@ public enum TerrainTools { if (!isReplaceable(toReplace)) return; world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, data); + ZapperItem.setTileData(world, p, paintedState, data); }); break; case Flatten: @@ -67,13 +67,13 @@ public enum TerrainTools { if (!isReplaceable(toReplace)) return; world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, data); + ZapperItem.setTileData(world, p, paintedState, data); }); break; case Place: targetPositions.forEach(p -> { world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, data); + ZapperItem.setTileData(world, p, paintedState, data); }); break; case Replace: @@ -82,7 +82,7 @@ public enum TerrainTools { if (isReplaceable(toReplace)) return; world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, data); + ZapperItem.setTileData(world, p, paintedState, data); }); break; } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java index de0eb97b4..3fb18767d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.logistics.block.redstone; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.content.logistics.block.funnel.FunnelBlock; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.utility.Iterate; diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java index f6d1a61d3..0a4612eab 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java @@ -2,8 +2,11 @@ package com.simibubi.create.content.schematics; import com.mojang.datafixers.Dynamic; import com.mojang.datafixers.types.DynamicOps; +import com.simibubi.create.foundation.utility.NBTProcessors; + import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorldReader; @@ -24,8 +27,10 @@ public class SchematicProcessor extends StructureProcessor { public Template.BlockInfo process(IWorldReader world, BlockPos pos, Template.BlockInfo rawInfo, Template.BlockInfo info, PlacementSettings settings, @Nullable Template template) { if (info.nbt != null) { TileEntity te = info.state.createTileEntity(world); - if (te != null && te.onlyOpsCanSetNbt()) { - return new Template.BlockInfo(info.pos, info.state, null); + if (te != null) { + CompoundNBT nbt = NBTProcessors.process(te, info.nbt, false); + if (nbt != info.nbt) + return new Template.BlockInfo(info.pos, info.state, nbt); } } return info; diff --git a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java index 743cc5a3b..d9ea129c2 100644 --- a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java +++ b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java @@ -5,7 +5,6 @@ import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -14,8 +13,6 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Stream; -import org.apache.commons.io.IOUtils; - import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; import com.simibubi.create.Create; diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java index 8069187b7..aad69e69a 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java @@ -27,6 +27,7 @@ import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.NBTProcessors; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -466,8 +467,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC CompoundNBT data = null; if (AllBlockTags.SAFE_NBT.matches(blockState)) { TileEntity tile = blockReader.getTileEntity(target); - if (tile != null && !tile.onlyOpsCanSetNbt()) { + if (tile != null) { data = tile.write(new CompoundNBT()); + data = NBTProcessors.process(tile, data, true); } } launchBlock(target, icon, blockState, data); diff --git a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java index 1bef9185f..21fb1871d 100644 --- a/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java +++ b/src/main/java/com/simibubi/create/content/schematics/item/SchematicItem.java @@ -154,7 +154,7 @@ public class SchematicItem extends Item { public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { if (!onItemUse(playerIn, handIn)) return super.onItemRightClick(worldIn, playerIn, handIn); - return new ActionResult(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn)); + return new ActionResult<>(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn)); } private boolean onItemUse(PlayerEntity player, Hand hand) { diff --git a/src/main/java/com/simibubi/create/content/schematics/packet/SchematicPlacePacket.java b/src/main/java/com/simibubi/create/content/schematics/packet/SchematicPlacePacket.java index 869f966f1..d15430671 100644 --- a/src/main/java/com/simibubi/create/content/schematics/packet/SchematicPlacePacket.java +++ b/src/main/java/com/simibubi/create/content/schematics/packet/SchematicPlacePacket.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.schematics.packet; import java.util.function.Supplier; +import com.simibubi.create.content.schematics.SchematicProcessor; import com.simibubi.create.content.schematics.item.SchematicItem; import com.simibubi.create.foundation.networking.SimplePacketBase; @@ -36,6 +37,8 @@ public class SchematicPlacePacket extends SimplePacketBase { return; Template t = SchematicItem.loadSchematic(stack); PlacementSettings settings = SchematicItem.getSettings(stack); + if (player.canUseCommandBlock()) + settings.func_215220_b(SchematicProcessor.INSTANCE); // remove processor settings.setIgnoreEntities(false); t.addBlocksToWorld(player.getServerWorld(), NBTUtil.readBlockPos(stack.getTag().getCompound("Anchor")), settings); diff --git a/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java b/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java index e59a45521..2cbff0055 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/FilesHelper.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; diff --git a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java new file mode 100644 index 000000000..8ca4d212f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java @@ -0,0 +1,57 @@ +package com.simibubi.create.foundation.utility; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.UnaryOperator; + +import javax.annotation.Nullable; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.text.ITextComponent; + +public final class NBTProcessors { + + private static final Map, UnaryOperator> processors = new HashMap<>(); + private static final Map, UnaryOperator> survivalProcessors = new HashMap<>(); + + public static synchronized void addProcessor(TileEntityType type, UnaryOperator processor) { + processors.put(type, processor); + } + + public static synchronized void addSurvivalProcessor(TileEntityType type, UnaryOperator processor) { + survivalProcessors.put(type, processor); + } + + static { + addProcessor(TileEntityType.SIGN, data -> { + for (int i = 0; i < 4; ++i) { + String s = data.getString("Text" + (i + 1)); + ITextComponent textcomponent = ITextComponent.Serializer.fromJson(s.isEmpty() ? "\"\"" : s); + if (textcomponent != null && textcomponent.getStyle() != null + && textcomponent.getStyle().getClickEvent() != null) + return null; + } + return data; + }); + } + + private NBTProcessors() { + } + + @Nullable + public static CompoundNBT process(TileEntity tileEntity, CompoundNBT compound, boolean survival) { + if (compound == null) + return null; + TileEntityType type = tileEntity.getType(); + if (survival && survivalProcessors.containsKey(type)) + compound = survivalProcessors.get(type).apply(compound); + if (processors.containsKey(type)) + return processors.get(type).apply(compound); + if (tileEntity.onlyOpsCanSetNbt()) + return null; + return compound; + } + +} From 4a15fbcec36974b7bae71d5e937568bd004a5079 Mon Sep 17 00:00:00 2001 From: Snownee Date: Sun, 31 Jan 2021 15:28:14 +0800 Subject: [PATCH 17/31] Fix funnel filter dupe --- .../content/curiosities/zapper/ZapperItem.java | 4 ++-- .../zapper/blockzapper/BlockzapperItem.java | 2 +- .../zapper/terrainzapper/TerrainTools.java | 11 ++++++----- .../zapper/terrainzapper/WorldshaperItem.java | 2 +- .../create/foundation/utility/NBTProcessors.java | 12 ++++++++++++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java index 13ed0a475..44303bf94 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperItem.java @@ -241,11 +241,11 @@ public abstract class ZapperItem extends Item { return UseAction.NONE; } - public static void setTileData(World world, BlockPos pos, BlockState state, CompoundNBT data) { + public static void setTileData(World world, BlockPos pos, BlockState state, CompoundNBT data, PlayerEntity player) { if (data != null && AllBlockTags.SAFE_NBT.matches(state)) { TileEntity tile = world.getTileEntity(pos); if (tile != null) { - data = NBTProcessors.process(tile, data, true); + data = NBTProcessors.process(tile, data, !player.isCreative()); if (data == null) return; data.putInt("x", pos.getX()); diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java index 954d06daf..21d555b6b 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperItem.java @@ -135,7 +135,7 @@ public class BlockzapperItem extends ZapperItem { blocksnapshot.restore(true, false); return false; } - setTileData(world, placed, state, data); + setTileData(world, placed, state, data, player); if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) { ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player; diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java index abd142734..3abb7fe27 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/TerrainTools.java @@ -10,6 +10,7 @@ import com.simibubi.create.foundation.utility.Lang; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -36,7 +37,7 @@ public enum TerrainTools { return this != Clear && this != Flatten; } - public void run(World world, List targetPositions, Direction facing, @Nullable BlockState paintedState, @Nullable CompoundNBT data) { + public void run(World world, List targetPositions, Direction facing, @Nullable BlockState paintedState, @Nullable CompoundNBT data, PlayerEntity player) { switch (this) { case Clear: targetPositions.forEach(p -> world.setBlockState(p, Blocks.AIR.getDefaultState())); @@ -47,7 +48,7 @@ public enum TerrainTools { if (!isReplaceable(toReplace)) return; world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, paintedState, data); + ZapperItem.setTileData(world, p, paintedState, data, player); }); break; case Flatten: @@ -67,13 +68,13 @@ public enum TerrainTools { if (!isReplaceable(toReplace)) return; world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, paintedState, data); + ZapperItem.setTileData(world, p, paintedState, data, player); }); break; case Place: targetPositions.forEach(p -> { world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, paintedState, data); + ZapperItem.setTileData(world, p, paintedState, data, player); }); break; case Replace: @@ -82,7 +83,7 @@ public enum TerrainTools { if (isReplaceable(toReplace)) return; world.setBlockState(p, paintedState); - ZapperItem.setTileData(world, p, paintedState, data); + ZapperItem.setTileData(world, p, paintedState, data, player); }); break; } diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperItem.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperItem.java index 9f2e4d019..4e5df7686 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperItem.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperItem.java @@ -77,7 +77,7 @@ public class WorldshaperItem extends ZapperItem { for (BlockPos blockPos : brush.getIncludedPositions()) affectedPositions.add(targetPos.add(blockPos)); PlacementPatterns.applyPattern(affectedPositions, stack); - tool.run(world, affectedPositions, raytrace.getFace(), stateToUse, data); + tool.run(world, affectedPositions, raytrace.getFace(), stateToUse, data, player); return true; } diff --git a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java index 8ca4d212f..1524913fb 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java +++ b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java @@ -6,6 +6,10 @@ import java.util.function.UnaryOperator; import javax.annotation.Nullable; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.logistics.item.filter.FilterItem; + +import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; @@ -35,6 +39,14 @@ public final class NBTProcessors { } return data; }); + addSurvivalProcessor(AllTileEntities.FUNNEL.get(), data -> { + if (data.contains("Filter")) { + ItemStack filter = ItemStack.read(data.getCompound("Filter")); + if (filter.getItem() instanceof FilterItem) + data.remove("Filter"); + } + return data; + }); } private NBTProcessors() { From 5c64c2d94209d94c8f95f335ac43e75515af70e1 Mon Sep 17 00:00:00 2001 From: Snownee Date: Sun, 31 Jan 2021 16:06:45 +0800 Subject: [PATCH 18/31] Add server-side check for extendo-grip and contraption interaction --- .../sync/ContraptionInteractionPacket.java | 37 ++++++++++-------- .../tools/ExtendoGripInteractionPacket.java | 39 +++++++++++-------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionInteractionPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionInteractionPacket.java index 5960d43fc..83e37704b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionInteractionPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionInteractionPacket.java @@ -6,6 +6,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Abs import com.simibubi.create.foundation.networking.SimplePacketBase; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.network.PacketBuffer; import net.minecraft.util.Direction; @@ -45,22 +46,26 @@ public class ContraptionInteractionPacket extends SimplePacketBase { @Override public void handle(Supplier context) { - context.get() - .enqueueWork(() -> { - ServerPlayerEntity sender = context.get() - .getSender(); - if (sender == null) - return; - Entity entityByID = sender.getServerWorld() - .getEntityByID(target); - if (!(entityByID instanceof AbstractContraptionEntity)) - return; - AbstractContraptionEntity contraptionEntity = (AbstractContraptionEntity) entityByID; - if (contraptionEntity.handlePlayerInteraction(sender, localPos, face, interactionHand)) - sender.swingHand(interactionHand, true); - }); - context.get() - .setPacketHandled(true); + context.get().enqueueWork(() -> { + ServerPlayerEntity sender = context.get().getSender(); + if (sender == null) + return; + Entity entityByID = sender.getServerWorld().getEntityByID(target); + if (!(entityByID instanceof AbstractContraptionEntity)) + return; + AbstractContraptionEntity contraptionEntity = (AbstractContraptionEntity) entityByID; + double d = sender.getAttribute(PlayerEntity.REACH_DISTANCE).getValue(); + if (!sender.canEntityBeSeen(entityByID)) + d -= 3; + d *= d; + if (sender.getDistanceSq(entityByID) > d) { + // TODO log? + return; + } + if (contraptionEntity.handlePlayerInteraction(sender, localPos, face, interactionHand)) + sender.swingHand(interactionHand, true); + }); + context.get().setPacketHandled(true); } } diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java index 63739b632..36364c95f 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java +++ b/src/main/java/com/simibubi/create/content/curiosities/tools/ExtendoGripInteractionPacket.java @@ -5,6 +5,7 @@ import java.util.function.Supplier; import com.simibubi.create.foundation.networking.SimplePacketBase; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.network.PacketBuffer; import net.minecraft.util.Hand; @@ -53,25 +54,29 @@ public class ExtendoGripInteractionPacket extends SimplePacketBase { @Override public void handle(Supplier context) { - context.get() - .enqueueWork(() -> { - ServerPlayerEntity sender = context.get() - .getSender(); - if (sender == null) + context.get().enqueueWork(() -> { + ServerPlayerEntity sender = context.get().getSender(); + if (sender == null) + return; + Entity entityByID = sender.getServerWorld().getEntityByID(target); + if (entityByID != null && ExtendoGripItem.isHoldingExtendoGrip(sender)) { + double d = sender.getAttribute(PlayerEntity.REACH_DISTANCE).getValue(); + if (!sender.canEntityBeSeen(entityByID)) + d -= 3; + d *= d; + if (sender.getDistanceSq(entityByID) > d) { + // TODO log? return; - Entity entityByID = sender.getServerWorld() - .getEntityByID(target); - if (entityByID != null && ExtendoGripItem.isHoldingExtendoGrip(sender)) { - if (interactionHand == null) - sender.attackTargetEntityWithCurrentItem(entityByID); - else if (specificPoint == null) - sender.interactOn(entityByID, interactionHand); - else - entityByID.applyPlayerInteraction(sender, specificPoint, interactionHand); } - }); - context.get() - .setPacketHandled(true); + if (interactionHand == null) + sender.attackTargetEntityWithCurrentItem(entityByID); + else if (specificPoint == null) + sender.interactOn(entityByID, interactionHand); + else + entityByID.applyPlayerInteraction(sender, specificPoint, interactionHand); + } + }); + context.get().setPacketHandled(true); } } From 7436ceb209ed53df82c366f96297b6a895c16e60 Mon Sep 17 00:00:00 2001 From: Snownee Date: Sun, 31 Jan 2021 19:24:44 +0800 Subject: [PATCH 19/31] Fix stabilized contraption moving bearing block --- .../components/structureMovement/Contraption.java | 4 ++-- .../structureMovement/TranslatingContraption.java | 3 +-- .../structureMovement/bearing/BearingContraption.java | 7 ++++--- .../structureMovement/bearing/ClockworkContraption.java | 9 +++++---- .../bearing/StabilizedBearingMovementBehaviour.java | 2 +- .../structureMovement/bearing/StabilizedContraption.java | 2 +- .../structureMovement/mounted/MountedContraption.java | 2 +- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index bb4dadb7f..54bab2c8d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -135,7 +135,7 @@ public abstract class Contraption { public abstract boolean assemble(World world, BlockPos pos); - protected abstract boolean canAxisBeStabilized(Axis axis); + public abstract boolean canBeStabilized(Direction facing, BlockPos localPos); protected abstract AllContraptionTypes getType(); @@ -338,7 +338,7 @@ public abstract class Contraption { private void moveBearing(BlockPos pos, List frontier, Set visited, BlockState state) { Direction facing = state.get(MechanicalBearingBlock.FACING); - if (!canAxisBeStabilized(facing.getAxis())) { + if (!canBeStabilized(facing, pos.subtract(anchor))) { BlockPos offset = pos.offset(facing); if (!visited.contains(offset)) frontier.add(offset); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java index 7e473df3b..9d889227b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/TranslatingContraption.java @@ -5,7 +5,6 @@ import java.util.HashSet; import java.util.Set; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -48,7 +47,7 @@ public abstract class TranslatingContraption extends Contraption { } @Override - protected boolean canAxisBeStabilized(Axis axis) { + public boolean canBeStabilized(Direction facing, BlockPos localPos) { return false; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java index 76db5bd8b..9559d8c90 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java @@ -9,7 +9,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -84,8 +83,10 @@ public class BearingContraption extends Contraption { } @Override - protected boolean canAxisBeStabilized(Axis axis) { - return axis == facing.getAxis(); + public boolean canBeStabilized(Direction facing, BlockPos localPos) { + if (facing.getOpposite() == this.facing && BlockPos.ZERO.equals(localPos)) + return false; + return facing.getAxis() == this.facing.getAxis(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java index 31b7709f3..ee625cc63 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java @@ -12,7 +12,6 @@ import com.simibubi.create.foundation.utility.NBTHelper; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -110,15 +109,17 @@ public class ClockworkContraption extends Contraption { @Override public void readNBT(World world, CompoundNBT tag, boolean spawnData) { - facing = Direction.byIndex(tag.getInt("Facing")); + facing = Direction.byIndex(tag.getInt("facing")); handType = NBTHelper.readEnum(tag, "HandType", HandType.class); offset = tag.getInt("offset"); super.readNBT(world, tag, spawnData); } @Override - protected boolean canAxisBeStabilized(Axis axis) { - return axis == facing.getAxis(); + public boolean canBeStabilized(Direction facing, BlockPos localPos) { + if (BlockPos.ZERO.equals(localPos) || BlockPos.ZERO.equals(localPos.offset(facing))) + return false; + return facing.getAxis() == this.facing.getAxis(); } public static enum HandType { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java index 35df5d517..3bec0cedf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedBearingMovementBehaviour.java @@ -45,7 +45,7 @@ public class StabilizedBearingMovementBehaviour extends MovementBehaviour { AbstractContraptionEntity entity = context.contraption.entity; if (entity instanceof ControlledContraptionEntity) { ControlledContraptionEntity controlledCE = (ControlledContraptionEntity) entity; - if (controlledCE.getRotationAxis() == axis) + if (context.contraption.canBeStabilized(facing, context.localPos)) offset = -controlledCE.getAngle(renderPartialTicks); } else if (entity instanceof OrientedContraptionEntity) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java index f54d09beb..a6b3ec837 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java @@ -55,7 +55,7 @@ public class StabilizedContraption extends Contraption { } @Override - protected boolean canAxisBeStabilized(Axis axis) { + public boolean canBeStabilized(Direction facing, BlockPos localPos) { return false; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java index 3d6a28dd8..8846e24b0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java @@ -149,7 +149,7 @@ public class MountedContraption extends Contraption { } @Override - protected boolean canAxisBeStabilized(Axis axis) { + public boolean canBeStabilized(Direction facing, BlockPos localPos) { return true; } From d1e9b76a248163f8fc109c58e80e3c335b64d4b8 Mon Sep 17 00:00:00 2001 From: Snownee Date: Sun, 31 Jan 2021 19:54:27 +0800 Subject: [PATCH 20/31] Make deployer still activate when it is triggering advancement --- .../contraptions/components/deployer/DeployerTileEntity.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java index 65beab8e3..1aa3a0330 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java @@ -183,8 +183,7 @@ public class DeployerTileEntity extends KineticTileEntity { if (state == State.EXPANDING) { if (boop) triggerBoop(); - else - activate(); + activate(); state = State.RETRACTING; timer = 1000; From fc459732fc274e69a643dcad245c82fef638c2f8 Mon Sep 17 00:00:00 2001 From: Snownee Date: Mon, 1 Feb 2021 16:46:36 +0800 Subject: [PATCH 21/31] Fix chute item dupe (#939) --- .../content/contraptions/components/fan/AirCurrent.java | 2 +- .../components/press/MechanicalPressTileEntity.java | 4 +++- .../create/content/logistics/block/chute/ChuteTileEntity.java | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java index ca4693b1a..8f499bce8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java @@ -82,7 +82,7 @@ public class AirCurrent { protected void tickAffectedEntities(World world, Direction facing) { for (Iterator iterator = caughtEntities.iterator(); iterator.hasNext();) { Entity entity = iterator.next(); - if (!entity.getBoundingBox() + if (!entity.isAlive() || !entity.getBoundingBox() .intersects(bounds)) { iterator.remove(); continue; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java index 3d320743a..ca52ae3a6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java @@ -153,6 +153,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { for (ItemEntity itemEntity : world.getEntitiesWithinAABB(ItemEntity.class, new AxisAlignedBB(pos.down()).shrink(.125f))) { + if (!itemEntity.isAlive() || !itemEntity.onGround) + continue; ItemStack stack = itemEntity.getItem(); Optional recipe = getRecipe(stack); if (!recipe.isPresent()) @@ -233,7 +235,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, bb)) { if (!(entity instanceof ItemEntity)) continue; - if (!entity.isAlive()) + if (!entity.isAlive() || !entity.onGround) continue; ItemEntity itemEntity = (ItemEntity) entity; pressedItems.add(itemEntity.getItem()); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java index 006097715..943f8345e 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java @@ -223,6 +223,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor AxisAlignedBB searchArea = new AxisAlignedBB(center.add(0, -bottomPullDistance - 0.5, 0), center.add(0, -0.5, 0)).grow(.45f); for (ItemEntity itemEntity : world.getEntitiesWithinAABB(ItemEntity.class, searchArea)) { + if (!itemEntity.isAlive()) + continue; ItemStack entityItem = itemEntity.getItem(); if (!canAcceptItem(entityItem)) continue; From 25daf28205c7bdc8f6e52fbe3f686bfba3dae12a Mon Sep 17 00:00:00 2001 From: Snownee Date: Sat, 6 Feb 2021 04:21:07 +0800 Subject: [PATCH 22/31] Format codes --- .../schematics/SchematicProcessor.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java index 0a4612eab..985338d5d 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java @@ -23,8 +23,9 @@ public class SchematicProcessor extends StructureProcessor { public static final SchematicProcessor INSTANCE = new SchematicProcessor(); @Nullable - @Override - public Template.BlockInfo process(IWorldReader world, BlockPos pos, Template.BlockInfo rawInfo, Template.BlockInfo info, PlacementSettings settings, @Nullable Template template) { + @Override + public Template.BlockInfo process(IWorldReader world, BlockPos pos, Template.BlockInfo rawInfo, + Template.BlockInfo info, PlacementSettings settings, @Nullable Template template) { if (info.nbt != null) { TileEntity te = info.state.createTileEntity(world); if (te != null) { @@ -33,26 +34,25 @@ public class SchematicProcessor extends StructureProcessor { return new Template.BlockInfo(info.pos, info.state, nbt); } } - return info; - } + return info; + } @Nullable - @Override - public Template.EntityInfo processEntity(IWorldReader world, BlockPos pos, Template.EntityInfo rawInfo, Template.EntityInfo info, PlacementSettings settings, Template template) { - return EntityType.readEntityType(info.nbt) - .flatMap(type -> { - if (world instanceof World) { - Entity e = type.create((World) world); - if (e != null && !e.ignoreItemEntityData()) { - return Optional.of(info); - } + @Override + public Template.EntityInfo processEntity(IWorldReader world, BlockPos pos, Template.EntityInfo rawInfo, + Template.EntityInfo info, PlacementSettings settings, Template template) { + return EntityType.readEntityType(info.nbt).flatMap(type -> { + if (world instanceof World) { + Entity e = type.create((World) world); + if (e != null && !e.ignoreItemEntityData()) { + return Optional.of(info); } - return Optional.empty(); - }) - .orElse(null); - } + } + return Optional.empty(); + }).orElse(null); + } - @Override + @Override protected IStructureProcessorType getType() { return dynamic -> INSTANCE; } From 3d8b10d9a7c39171ad1b3b0eda00a32c44ab6ca2 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 6 Feb 2021 16:07:22 +0100 Subject: [PATCH 23/31] Gantry improvements - Fixed gantry shafts not locking to correct orientations when placed near others - Gantry pinions can now be kickstarted by player interaction - Gantry pinions now update properly after being moved onto different gantry shafts - Fixed Encased Fans not providing kinetic power after being moved by contraption - Sticky Mechanical Pistons now drag attached structures with them - Mechanical piston heads and poles now drag their entire piston multiblock with them --- .../components/fan/EncasedFanBlock.java | 14 +- .../components/fan/EncasedFanTileEntity.java | 28 ++- .../structureMovement/Contraption.java | 160 ++++++++++++------ .../gantry/GantryPinionBlock.java | 23 ++- .../relays/advanced/GantryShaftBlock.java | 22 ++- 5 files changed, 173 insertions(+), 74 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java index 27e3107b7..b70de3e10 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanBlock.java @@ -1,6 +1,5 @@ package com.simibubi.create.content.contraptions.components.fan; -import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock; @@ -33,9 +32,16 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE te.updateGenerator(state.get(FACING))); + withTileEntityDo(worldIn, pos, te -> te.queueGeneratorUpdate()); } protected void notifyFanTile(IWorld world, BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java index db7f42639..132f9f65d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.fan; import javax.annotation.Nullable; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags.AllBlockTags; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; @@ -18,7 +19,6 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; - @MethodsReturnNonnullByDefault public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements IAirCurrentSource { @@ -27,18 +27,21 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements protected int entitySearchCooldown; protected boolean isGenerator; protected boolean updateAirFlow; + protected boolean updateGenerator; public EncasedFanTileEntity(TileEntityType type) { super(type); isGenerator = false; airCurrent = new AirCurrent(this); updateAirFlow = true; + updateGenerator = false; } @Override protected void read(CompoundNBT compound, boolean clientPacket) { super.read(compound, clientPacket); - isGenerator = compound.getBoolean("Generating"); + if (!wasMoved) + isGenerator = compound.getBoolean("Generating"); if (clientPacket) airCurrent.rebuild(); } @@ -64,12 +67,20 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements return isGenerator ? AllConfigs.SERVER.kinetics.generatingFanSpeed.get() : 0; } - public void updateGenerator(Direction facing) { - boolean shouldGenerate = world.isBlockPowered(pos) && facing == Direction.DOWN - && world.isBlockPresent(pos.down()) && blockBelowIsHot(); + public void queueGeneratorUpdate() { + updateGenerator = true; + } + + public void updateGenerator() { + BlockState blockState = getBlockState(); + if (!AllBlocks.ENCASED_FAN.has(blockState)) + return; + if (blockState.get(EncasedFanBlock.FACING) != Direction.DOWN) + return; + + boolean shouldGenerate = world.isBlockPowered(pos) && world.isBlockPresent(pos.down()) && blockBelowIsHot(); if (shouldGenerate == isGenerator) return; - isGenerator = shouldGenerate; updateGeneratedRotation(); } @@ -170,6 +181,11 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements airCurrent.rebuild(); sendData(); } + + if (updateGenerator) { + updateGenerator = false; + updateGenerator(); + } if (getSpeed() == 0 || isGenerator) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 67d6b929d..91daa8f04 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -23,6 +23,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllMovementBehaviours; +import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.actors.SeatBlock; import com.simibubi.create.content.contraptions.components.actors.SeatEntity; @@ -35,6 +36,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.glu import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueHandler; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; +import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonHeadBlock; import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.MagnetBlock; @@ -71,6 +73,7 @@ import net.minecraft.nbt.NBTUtil; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.ChestType; import net.minecraft.state.properties.DoubleBlockHalf; +import net.minecraft.state.properties.PistonType; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; @@ -266,25 +269,11 @@ public abstract class Contraption { if (AllBlocks.BELT.has(state)) moveBelt(pos, frontier, visited, state); - if (AllBlocks.GANTRY_PINION.has(state)) { - BlockPos offset = pos.offset(state.get(GantryPinionBlock.FACING)); - if (!visited.contains(offset)) - frontier.add(offset); - } + if (AllBlocks.GANTRY_PINION.has(state)) + moveGantryPinion(world, pos, frontier, visited, state); if (AllBlocks.GANTRY_SHAFT.has(state)) - for (Direction d : Iterate.directions) { - BlockPos offset = pos.offset(d); - if (!visited.contains(offset)) { - BlockState offsetState = world.getBlockState(offset); - Direction facing = state.get(GantryShaftBlock.FACING); - if (d.getAxis() == facing.getAxis() && AllBlocks.GANTRY_SHAFT.has(offsetState) - && offsetState.get(GantryShaftBlock.FACING) == facing) - frontier.add(offset); - else if (AllBlocks.GANTRY_PINION.has(offsetState) && offsetState.get(GantryPinionBlock.FACING) == d) - frontier.add(offset); - } - } + moveGantryShaft(world, pos, frontier, visited, state); // Bearings potentially create stabilized sub-contraptions if (AllBlocks.MECHANICAL_BEARING.has(state)) @@ -302,6 +291,10 @@ public abstract class Contraption { if (state.getBlock() instanceof MechanicalPistonBlock) if (!moveMechanicalPiston(world, pos, frontier, visited, state)) return false; + if (isExtensionPole(state)) + movePistonPole(world, pos, frontier, visited, state); + if (isPistonHead(state)) + movePistonHead(world, pos, frontier, visited, state); // Doors try to stay whole if (state.getBlock() instanceof DoorBlock) { @@ -346,6 +339,83 @@ public abstract class Contraption { return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); } + protected void movePistonHead(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + Direction direction = state.get(MechanicalPistonHeadBlock.FACING); + BlockPos offset = pos.offset(direction.getOpposite()); + if (!visited.contains(offset)) { + BlockState blockState = world.getBlockState(offset); + if (isExtensionPole(blockState) && blockState.get(PistonExtensionPoleBlock.FACING) + .getAxis() == direction.getAxis()) + frontier.add(offset); + if (blockState.getBlock() instanceof MechanicalPistonBlock) { + Direction pistonFacing = blockState.get(MechanicalPistonBlock.FACING); + if (pistonFacing == direction && blockState.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) + frontier.add(offset); + } + } + if (state.get(MechanicalPistonHeadBlock.TYPE) == PistonType.STICKY) { + BlockPos attached = pos.offset(direction); + if (!visited.contains(attached)) + frontier.add(attached); + } + } + + protected void movePistonPole(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + for (Direction d : Iterate.directionsInAxis(state.get(PistonExtensionPoleBlock.FACING) + .getAxis())) { + BlockPos offset = pos.offset(d); + if (!visited.contains(offset)) { + BlockState blockState = world.getBlockState(offset); + if (isExtensionPole(blockState) && blockState.get(PistonExtensionPoleBlock.FACING) + .getAxis() == d.getAxis()) + frontier.add(offset); + if (isPistonHead(blockState) && blockState.get(MechanicalPistonHeadBlock.FACING) + .getAxis() == d.getAxis()) + frontier.add(offset); + if (blockState.getBlock() instanceof MechanicalPistonBlock) { + Direction pistonFacing = blockState.get(MechanicalPistonBlock.FACING); + if (pistonFacing == d || pistonFacing == d.getOpposite() + && blockState.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) + frontier.add(offset); + } + } + } + } + + protected void moveGantryPinion(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + BlockPos offset = pos.offset(state.get(GantryPinionBlock.FACING)); + if (!visited.contains(offset)) + frontier.add(offset); + Axis rotationAxis = ((IRotate) state.getBlock()).getRotationAxis(state); + for (Direction d : Iterate.directionsInAxis(rotationAxis)) { + offset = pos.offset(d); + BlockState offsetState = world.getBlockState(offset); + if (AllBlocks.GANTRY_SHAFT.has(offsetState) && offsetState.get(GantryShaftBlock.FACING) + .getAxis() == d.getAxis()) + if (!visited.contains(offset)) + frontier.add(offset); + } + } + + protected void moveGantryShaft(World world, BlockPos pos, List frontier, Set visited, + BlockState state) { + for (Direction d : Iterate.directions) { + BlockPos offset = pos.offset(d); + if (!visited.contains(offset)) { + BlockState offsetState = world.getBlockState(offset); + Direction facing = state.get(GantryShaftBlock.FACING); + if (d.getAxis() == facing.getAxis() && AllBlocks.GANTRY_SHAFT.has(offsetState) + && offsetState.get(GantryShaftBlock.FACING) == facing) + frontier.add(offset); + else if (AllBlocks.GANTRY_PINION.has(offsetState) && offsetState.get(GantryPinionBlock.FACING) == d) + frontier.add(offset); + } + } + } + private void moveBearing(BlockPos pos, List frontier, Set visited, BlockState state) { Direction facing = state.get(MechanicalBearingBlock.FACING); if (!canAxisBeStabilized(facing.getAxis())) { @@ -398,47 +468,25 @@ public abstract class Contraption { private boolean moveMechanicalPiston(World world, BlockPos pos, List frontier, Set visited, BlockState state) { - int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); Direction direction = state.get(MechanicalPistonBlock.FACING); - if (state.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { - BlockPos searchPos = pos; - while (limit-- >= 0) { - searchPos = searchPos.offset(direction); - BlockState blockState = world.getBlockState(searchPos); - if (isExtensionPole(blockState)) { - if (blockState.get(PistonExtensionPoleBlock.FACING) - .getAxis() != direction.getAxis()) - break; - if (!visited.contains(searchPos)) - frontier.add(searchPos); - continue; - } - if (isPistonHead(blockState)) - if (!visited.contains(searchPos)) - frontier.add(searchPos); - break; - } - if (limit <= -1) - return false; - } - - BlockPos searchPos = pos; - while (limit-- >= 0) { - searchPos = searchPos.offset(direction.getOpposite()); - BlockState blockState = world.getBlockState(searchPos); - if (isExtensionPole(blockState)) { - if (blockState.get(PistonExtensionPoleBlock.FACING) - .getAxis() != direction.getAxis()) - break; - if (!visited.contains(searchPos)) - frontier.add(searchPos); - continue; - } - break; - } - - if (limit <= -1) + PistonState pistonState = state.get(MechanicalPistonBlock.STATE); + if (pistonState == PistonState.MOVING) return false; + + BlockPos offset = pos.offset(direction.getOpposite()); + if (!visited.contains(offset)) { + BlockState poleState = world.getBlockState(offset); + if (AllBlocks.PISTON_EXTENSION_POLE.has(poleState) && poleState.get(PistonExtensionPoleBlock.FACING) + .getAxis() == direction.getAxis()) + frontier.add(offset); + } + + if (pistonState == PistonState.EXTENDED || MechanicalPistonBlock.isStickyPiston(state)) { + offset = pos.offset(direction); + if (!visited.contains(offset)) + frontier.add(offset); + } + return true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java index 5f8874bcf..85c41d0af 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java @@ -10,11 +10,15 @@ import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; @@ -34,10 +38,15 @@ public class GantryPinionBlock extends DirectionalAxisKineticBlock implements IT .getAxis() != direction.getAxis(); } + @Override + public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { + super.updateNeighbors(stateIn, worldIn, pos, flags); + withTileEntityDo(worldIn, pos, GantryPinionTileEntity::checkValidGantryShaft); + } + @Override public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { super.onBlockAdded(state, worldIn, pos, oldState, isMoving); - withTileEntityDo(worldIn, pos, GantryPinionTileEntity::checkValidGantryShaft); } @Override @@ -50,6 +59,18 @@ public class GantryPinionBlock extends DirectionalAxisKineticBlock implements IT return context.getFace(); } + public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + if (!player.isAllowEdit() || player.isSneaking()) + return ActionResultType.PASS; + if (player.getHeldItem(handIn) + .isEmpty()) { + withTileEntityDo(worldIn, pos, te -> te.checkValidGantryShaft()); + return ActionResultType.SUCCESS; + } + return ActionResultType.PASS; + } + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState stateForPlacement = super.getStateForPlacement(context); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java index d231d00be..15cd24040 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java @@ -113,17 +113,25 @@ public class GantryShaftBlock extends DirectionalKineticBlock { @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState state = super.getStateForPlacement(context); + BlockPos pos = context.getPos(); + World world = context.getWorld(); Direction face = context.getFace(); - BlockState blockState = context.getWorld() - .getBlockState(context.getPos() - .offset(face.getOpposite())); - if (AllBlocks.GANTRY_SHAFT.has(blockState) && blockState.get(FACING) - .getAxis() == face.getAxis()) { - Direction facing = blockState.get(FACING); + + BlockState neighbour = world.getBlockState(pos.offset(state.get(FACING) + .getOpposite())); + + BlockState clickedState = + AllBlocks.GANTRY_SHAFT.has(neighbour) ? neighbour : world.getBlockState(pos.offset(face.getOpposite())); + + if (AllBlocks.GANTRY_SHAFT.has(clickedState) && clickedState.get(FACING) + .getAxis() == state.get(FACING) + .getAxis()) { + Direction facing = clickedState.get(FACING); state = state.with(FACING, context.getPlayer() == null || !context.getPlayer() .isSneaking() ? facing : facing.getOpposite()); } - return state.with(POWERED, shouldBePowered(state, context.getWorld(), context.getPos())); + + return state.with(POWERED, shouldBePowered(state, world, pos)); } @Override From 577c0e4912bca57b648d45943f41d2381a0a9ba2 Mon Sep 17 00:00:00 2001 From: Odin <66629792+dindin-glitch@users.noreply.github.com> Date: Sat, 6 Feb 2021 17:34:37 +0100 Subject: [PATCH 24/31] Update fr_fr.json 666 Unlocalized --- .../resources/assets/create/lang/fr_fr.json | 278 +++++++++++------- 1 file changed, 172 insertions(+), 106 deletions(-) diff --git a/src/main/resources/assets/create/lang/fr_fr.json b/src/main/resources/assets/create/lang/fr_fr.json index 410783a87..ddc79050d 100644 --- a/src/main/resources/assets/create/lang/fr_fr.json +++ b/src/main/resources/assets/create/lang/fr_fr.json @@ -1,5 +1,4 @@ { - "_": "->------------------------] Game Elements [------------------------<-", "block.create.acacia_window": "Fenêtre en acacia", @@ -8,49 +7,88 @@ "block.create.adjustable_pulse_repeater": "Répéteur d'impulsions réglable", "block.create.adjustable_repeater": "Répéteur réglable", "block.create.analog_lever": "Levier analogique", + "block.create.andesite_belt_funnel": "Entonnoir en andésite pour tapis roulant", "block.create.andesite_bricks": "Briques d'andésite", "block.create.andesite_bricks_slab": "Dalle en briques d'andésite", "block.create.andesite_bricks_stairs": "Escalier en briques d'andésite", "block.create.andesite_bricks_wall": "Mur en briques d'andésite", - "block.create.andesite_casing": "Boîtier en andésite", + "block.create.andesite_casing": "Revêtement en andésite", "block.create.andesite_cobblestone": "Pierres d'andésite", "block.create.andesite_cobblestone_slab": "Dalles en pierres d'andésite", "block.create.andesite_cobblestone_stairs": "Escaliers en pierres d'andésite", "block.create.andesite_cobblestone_wall": "Mur en pierres d'andésite", - "block.create.andesite_encased_shaft": "Arbre mécanique dans un revêtement en andésite", + "block.create.andesite_encased_shaft": "Rotor dans un revêtement en andésite", "block.create.andesite_funnel": "Entonnoir en andésite", "block.create.andesite_pillar": "Pilier en andésite", "block.create.andesite_tunnel": "Tunnel en andésite", "block.create.basin": "Bassin", "block.create.belt": "Tapis roulant", "block.create.birch_window": "Fenêtre en bouleau", - "block.create.brass_casing": "Boîtier en laiton", + "block.create.birch_window_pane": "Vitre en bouleau", + "block.create.black_sail": "Voile noire", + "block.create.black_seat": "Siège noir", + "block.create.black_valve_handle": "Vanne noire", + "block.create.blaze_burner": "Brûleur à blaze", + "block.create.blue_sail": "Voile bleue", + "block.create.blue_seat": "Siège bleu", + "block.create.blue_valve_handle": "Vanne bleue", + "block.create.brass_belt_funnel": "Entonnoir en laiton pour tapis roulant", + "block.create.brass_block": "Bloc de laiton", + "block.create.brass_casing": "Revêtement en laiton", + "block.create.brass_encased_shaft": "Rotor dans un revêtement en laiton", + "block.create.brass_funnel": "Entonnoir en laiton", + "block.create.brass_tunnel": "Tunnel en laiton", + "block.create.brown_sail": "Voile brune", + "block.create.brown_seat": "Siège brun", + "block.create.brown_valve_handle": "Vanne brune", "block.create.cart_assembler": "Assembleur de wagon", + "block.create.chiseled_dark_scoria": "Scoria sombre taillé", + "block.create.chiseled_dolomite": "Dolomite taillée", + "block.create.chiseled_gabbro": "Gabbro taillé", + "block.create.chiseled_limestone": "Calcaire taillé", + "block.create.chiseled_scoria": "Scoria taillé", + "block.create.chiseled_weathered_limestone": "Calcaire altéré taillé", + "block.create.chocolate": "Chocolat", + "block.create.chute": "Glissière", "block.create.clockwork_bearing": "Roulement mécanique horloger", "block.create.clutch": "Embrayage", "block.create.cogwheel": "Roue dentée", + "block.create.content_observer": "Observateur de contenu", + "block.create.controller_rail": "Rails controlleurs", "block.create.copper_block": "Bloc de cuivre", - "block.create.copper_casing": "Boîtier en cuivre", + "block.create.copper_casing": "Revêtement en cuivre", "block.create.copper_ore": "Minerai de cuivre", "block.create.copper_shingles": "Bardeaux de cuivre", + "block.create.copper_tiles": "Tuiles en cuivre", + "block.create.copper_valve_handle": "Vanne en cuivre", "block.create.creative_crate": "Créateur de schémacanon", + "block.create.creative_fluid_tank": "Réservoir créatif", "block.create.creative_motor": "Moteur", "block.create.crushing_wheel": "Roue de concassage", + "block.create.crushing_wheel_controller": "Contrôleur de roue de concassage", "block.create.cuckoo_clock": "Horloge à coucou", + "block.create.cyan_sail": "Voile cyan", + "block.create.cyan_seat": "Siège cyan", + "block.create.cyan_valve_handle": "Vanne cyan", + "block.create.dark_oak_window": "fenêtre en chêne sombre", + "block.create.dark_oak_window_pane": "Vitre en chêne sombre", "block.create.dark_scoria": "Scorie sombre", "block.create.dark_scoria_bricks": "Briques de scorie sombre", "block.create.dark_scoria_bricks_slab": "Dalles de briques de scorie sombre", "block.create.dark_scoria_bricks_stairs": "Escaliers de briques de scorie sombre", "block.create.dark_scoria_bricks_wall": "Muret de briques de scorie sombre", + "block.create.dark_scoria_cobblestone": "Pierres de scorie sombre", "block.create.deployer": "Déployeur", + "block.create.depot": "Dépot", "block.create.diorite_bricks": "Briques de diorite", - "block.create.dolomite": "Dolomie", - "block.create.dolomite_bricks": "Briques de dolomie", - "block.create.dolomite_bricks_slab": "Dalle de briques de dolomie", - "block.create.dolomite_bricks_stairs": "Escaliers de briques de dolomie", - "block.create.dolomite_bricks_wall": "Muret de briques de dolomie", - "block.create.dolomite_pillar": "Pillier de dolomie", - "block.create.encased_fan": "Ventilateur enfermé", + "block.create.dolomite": "Dolomite", + "block.create.dolomite_bricks": "Briques de dolomite", + "block.create.dolomite_bricks_slab": "Dalle de briques de dolomite", + "block.create.dolomite_bricks_stairs": "Escaliers de briques de dolomite", + "block.create.dolomite_bricks_wall": "Muret de briques de dolomite", + "block.create.dolomite_pillar": "Pillier de dolomite", + "block.create.encased_chain_drive": "Chaine de transmission", + "block.create.encased_fan": "Ventilateur enchâssé", "block.create.flywheel": "Volant d'inertie", "block.create.framed_glass": "Grande fenêtre en verre", "block.create.framed_glass_pane": "Grande vitre encadrée", @@ -85,23 +123,23 @@ "block.create.mechanical_saw": "Scie mécanique", "block.create.natural_scoria": "Scorie naturelle", "block.create.nozzle": "Buse", - "block.create.piston_extension_pole": "Pôle d'extension de piston", + "block.create.piston_extension_pole": "Barre d'extension de piston", "block.create.polished_dark_scoria": "Scorie sombre polie", - "block.create.polished_dolomite": "Dolomie polie", + "block.create.polished_dolomite": "Dolomite polie", "block.create.polished_gabbro": "Gabbro poli", "block.create.polished_limestone": "Calcaire poli", "block.create.polished_limestone_slab": "Dalle de calcaire polie", "block.create.polished_scoria": "Scorie polie", "block.create.polished_scoria_slab": "Dalle de scorie polie", - "block.create.polished_weathered_limestone": "Calcaire patinées polies", - "block.create.polished_weathered_limestone_slab": "Dalle de calcaire patinées", + "block.create.polished_weathered_limestone": "Calcaire altéré polies", + "block.create.polished_weathered_limestone_slab": "Dalle de calcaire altéré", "block.create.portable_storage_interface": "Interface de stockage portable", "block.create.powered_latch": "Verrou alimenté", "block.create.powered_toggle_latch": "Verrou alimenté à bascule", "block.create.pulley_magnet": "Aimant de poulie", "block.create.pulse_repeater": "Répéteur d'impulsions", "block.create.radial_chassis": "Châssis radial", - "block.create.redstone_contact": "redstone_contact Redstone", + "block.create.redstone_contact": "Contact de redstone", "block.create.redstone_link": "Liaison Redstone", "block.create.rope": "Corde", "block.create.rope_pulley": "Poulie à corde", @@ -112,7 +150,7 @@ "block.create.scoria_bricks": "Briques de scorie", "block.create.scoria_pillar": "Pillier de scorie", "block.create.sequenced_gearshift": "Décaleur de rotation séquencé", - "block.create.shaft": "Arbre mécanique", + "block.create.shaft": "Rotor", "block.create.speedometer": "Compteur de vitesse", "block.create.sticky_mechanical_piston": "Piston mécanique collant", "block.create.stockpile_switch": "Détecteur de stockage", @@ -123,12 +161,12 @@ "block.create.vertical_framed_glass": "Fenêtre en verre verticale", "block.create.vertical_framed_glass_pane": "Vitre encadrée verticale", "block.create.water_wheel": "Roue à eau", - "block.create.weathered_limestone": "Calcaire patinées", - "block.create.weathered_limestone_bricks": "Briques de calcaire patinées", - "block.create.weathered_limestone_bricks_slab": "Dalle de briques de calcaire patinées", - "block.create.weathered_limestone_bricks_stairs": "Escaliers de briques de calcaire patinées", - "block.create.weathered_limestone_bricks_wall": "Muret de briques de calcaire patinées", - "block.create.weathered_limestone_pillar": "Pillier de calcaire patinées", + "block.create.weathered_limestone": "Calcaire altéré", + "block.create.weathered_limestone_bricks": "Briques de Calcaire altéré", + "block.create.weathered_limestone_bricks_slab": "Dalle de briques de Calcaire altéré", + "block.create.weathered_limestone_bricks_stairs": "Escaliers de briques de Calcaire altéré", + "block.create.weathered_limestone_bricks_wall": "Muret de briques de Calcaire altéré", + "block.create.weathered_limestone_pillar": "Pillier de Calcaire altéré", "block.create.zinc_block": "Bloc de zinc", "block.create.zinc_ore": "Minerai de zinc", @@ -203,7 +241,7 @@ "item.create.schematic_and_quill": "Schéma et plume", "item.create.shadow_steel": "Acier sombre", "item.create.super_glue": "Colle extra-forte", - "item.create.tree_fertilizer": "Engrais pour arbre", + "item.create.tree_fertilizer": "Engrais pour arbres", "item.create.vertical_gearbox": "Boîte de transfert verticale", "item.create.wand_of_symmetry": "Bâton de symétrie", "item.create.wheat_flour": "Farine", @@ -220,7 +258,7 @@ "advancement.create.andesite_alloy.desc": "Certains matériaux de Create ont des noms bizzares; l'alliage d'andésite est l'un d'entre eux.", "advancement.create.its_alive": "Ça bouge!", "advancement.create.its_alive.desc": "Regardez vos bremiers composants tourner.", - "advancement.create.shifting_gears": "Arbre de transmission", + "advancement.create.shifting_gears": "rotor de transmission", "advancement.create.shifting_gears.desc": "Connectez une roue dentée à une grande roue dentée afin de changer la vitesse de votre engin", "advancement.create.overstressed": "Surtension", "advancement.create.overstressed.desc": "Testez d'abord les limites de la force mécanique", @@ -237,7 +275,7 @@ "itemGroup.create.base": "Create", "itemGroup.create.palettes": "Create Palettes", - "death.attack.create.crush": "%1$s nanana a été traitée par une roue de concassage", + "death.attack.create.crush": "%1$s a été concassé.e", "death.attack.create.fan_fire": "%1$s a été brûlé à mort par l'air chaud", "death.attack.create.fan_lava": "%1$s a été brûlé à mort par un ventilateur de lave", "death.attack.create.mechanical_drill": "%1$s a été empalé par une perceuse mécanique", @@ -365,10 +403,10 @@ "create.contraptions.movement_mode": "Mode de mouvement", "create.contraptions.movement_mode.move_place": "Toujours placer à l'arrêt", "create.contraptions.movement_mode.move_place_returned": "Placer uniquement en position de départ", - "create.contraptions.movement_mode.move_never_place": "Ne placer que lorsque l'ancre est détruite", + "create.contraptions.movement_mode.move_never_place": "Ne placer que Quand l'ancre est détruite", "create.contraptions.movement_mode.rotate_place": "Toujours placer à l'arrêt", "create.contraptions.movement_mode.rotate_place_returned": "Placer uniquement près de l'angle initial", - "create.contraptions.movement_mode.rotate_never_place": "Ne placer que lorsque l'ancre est détruite", + "create.contraptions.movement_mode.rotate_never_place": "Ne placer que Quand l'ancre est détruite", "create.logistics.filter": "Filtre", "create.logistics.recipe_filter": "Filtre de recettes", @@ -607,7 +645,7 @@ "create.command.killTPSCommand.status.usage.1": "[Create]: use /killtps start to artificially slow down the server tick", "create.command.killTPSCommand.argument.tickTime": "tickTime", - "create.subtitle.schematicannon_launch_block": "Tire de schémacanon", + "create.subtitle.schematicannon_launch_block": "Tir de schémacanon", "create.subtitle.schematicannon_finish": "Fin de schémacanon", "create.subtitle.slime_added": "Bruit de slime", "create.subtitle.mechanical_press_activation": "Activation de la presse mechanique", @@ -626,12 +664,12 @@ "item.create.example_item.tooltip.behaviour1": "Donc cet objet fait ceci. (les comportements sont affichés avec shift)", "item.create.example_item.tooltip.condition2": "Et quand cela", "item.create.example_item.tooltip.behaviour2": "Vous pouvez ajouter autant de comportements que vous le souhaitez", - "item.create.example_item.tooltip.control1": "Lorsque Ctrl enfoncé", + "item.create.example_item.tooltip.control1": "Quand Ctrl enfoncé", "item.create.example_item.tooltip.action1": "Ces commandes sont affichées.", "item.create.wand_of_symmetry.tooltip": "BÂTON DE SYMÉTRIE", "item.create.wand_of_symmetry.tooltip.summary": "Reflète parfaitement le placement des blocs sur les plans configurés.", - "item.create.wand_of_symmetry.tooltip.condition1": "Lorsque positionné dans la barre active", + "item.create.wand_of_symmetry.tooltip.condition1": "Quand positionné dans la barre active", "item.create.wand_of_symmetry.tooltip.behaviour1": "Reste actif", "item.create.wand_of_symmetry.tooltip.control1": "Clic droit au sol", "item.create.wand_of_symmetry.tooltip.action1": "_Créé_ ou _déplace_ le mirroir", @@ -658,25 +696,25 @@ "item.create.handheld_worldshaper.tooltip.control3": "Clic droit en étant accroupi", "item.create.handheld_worldshaper.tooltip.action3": "Ouvre l'_interface_ _de_ _configuration_", - "item.create.tree_fertilizer.tooltip": "ENGRAIS POUR ARBRE", - "item.create.tree_fertilizer.tooltip.summary": "Une puissante combinaison de minéraux adaptée pour accélérer la croissance des types d'arbres communs.", - "item.create.tree_fertilizer.tooltip.condition1": "Lorsqu'utilisé sur une pousse d'arbre", - "item.create.tree_fertilizer.tooltip.behaviour1": "Fait pousser des arbres _indépendamment_ de leurs _conditions_ _d'emplacement_", + "item.create.tree_fertilizer.tooltip": "ENGRAIS POUR ARBRES", + "item.create.tree_fertilizer.tooltip.summary": "Une puissante combinaison de minéraux adaptée pour accélérer la croissance des types d'rotors communs.", + "item.create.tree_fertilizer.tooltip.condition1": "Lorsqu'utilisé sur une pousse d'rotor", + "item.create.tree_fertilizer.tooltip.behaviour1": "Fait pousser des rotors _indépendamment_ de leurs _conditions_ _d'emplacement_", "item.create.deforester.tooltip": "DÉFORESTEUR", - "item.create.deforester.tooltip.summary": "Une _hache_ _rayonnante_ capable d'abattre des arbres en une fraction de seconde.", + "item.create.deforester.tooltip.summary": "Une _hache_ _rayonnante_ capable d'abattre des rotors en une fraction de seconde.", "item.create.filter.tooltip": "FILTRE", "item.create.filter.tooltip.summary": "_Contrôle_ les _sorties_ et _entrées_ de dispositifs logistiques avec plus de _précision_, en les comparant à un _ensemble_ _d'objets_ ou à plusieurs _filtres_ _imbriqués_.", - "item.create.filter.tooltip.condition1": "Lorsque dans l'emplacement de filtre", + "item.create.filter.tooltip.condition1": "Quand dans l'emplacement de filtre", "item.create.filter.tooltip.behaviour1": "_Contrôle_ le flux d'object selon sa _configuration_.", "item.create.filter.tooltip.condition2": "Clic droit", "item.create.filter.tooltip.behaviour2": "Ouvre l'_interface_ _de_ _configuration_.", "item.create.attribute_filter.tooltip": "FILTRE D'ATTRIBUTS", "item.create.attribute_filter.tooltip.summary": "_Contrôle_ les _sorties_ et les _entrées_ de dispositifs logistiques avec plus de _précision_, en les comparant à un _ensemble_ _d'objets_ ou à plusieurs _filtres_ _imbriqués_.", - "item.create.attribute_filter.tooltip.condition1": "Lorsque dans l'emplacement de filtre", + "item.create.attribute_filter.tooltip.condition1": "Quand dans l'emplacement de filtre", "item.create.attribute_filter.tooltip.behaviour1": "_Contrôle_ le flux d'object selon sa _configuration_.", "item.create.attribute_filter.tooltip.condition2": "Clic droit", "item.create.attribute_filter.tooltip.behaviour2": "Ouvre l'_interface_ _de_ _configuration_.", @@ -686,7 +724,7 @@ "item.create.schematic.tooltip": "SCHÉMA", "item.create.schematic.tooltip.summary": "Contient une structure à positionner et à placer dans le monde. Positionnez l'hologramme comme vous le souhaitez et utilisez un _schémacanon_ pour le construire.", - "item.create.schematic.tooltip.condition1": "Lorsque tenu en main", + "item.create.schematic.tooltip.condition1": "Quand tenu en main", "item.create.schematic.tooltip.behaviour1": "Peut être positionné à l'aide des outils à l'écran.", "item.create.schematic.tooltip.control1": "Clic droit en étant accroupi", "item.create.schematic.tooltip.action1": "Ouvre une _interface_ pour rentrer les _coordonées_ correctes.", @@ -711,54 +749,54 @@ "block.create.schematic_table.tooltip": "TABLE À SCHÉMA", "block.create.schematic_table.tooltip.summary": "Écrit les schémas enregistrés dans un _schéma_ _vide_.", - "block.create.schematic_table.tooltip.condition1": "Lorsque donné un schéma vide", + "block.create.schematic_table.tooltip.condition1": "Quand donné un schéma vide", "block.create.schematic_table.tooltip.behaviour1": "Télécharge un fichier choisi à partir de votre dossier de schémas.", - "block.create.shaft.tooltip": "ARBRE MÉCANIQUE", - "block.create.shaft.tooltip.summary": "_Relais_ la _rotation_ en ligne droite.", + "block.create.shaft.tooltip": "ROTOR", + "block.create.shaft.tooltip.summary": "_Relaie_ la _rotation_ en ligne droite.", "block.create.cogwheel.tooltip": "ROUE DENTÉE", - "block.create.cogwheel.tooltip.summary": "_Relais_ la _rotation_ en ligne droite, et aux _roues_ _dentées_ adjacentes.", + "block.create.cogwheel.tooltip.summary": "_Relaie_ la _rotation_ en ligne droite, et aux _roues_ _dentées_ adjacentes.", "block.create.large_cogwheel.tooltip": "GRANDE ROUE DENTÉE", "block.create.large_cogwheel.tooltip.summary": "Une version plus grande de la _roue_ _dentée_, permettant des _changements_ dans la _vitesse_ _de_ _rotation_ lorsqu'il est connecté à son homologue plus petit.", - "block.create.encased_shaft.tooltip": "ARBRE MÉCANIQUE ENBOÎTÉ", - "block.create.encased_shaft.tooltip.summary": "_Relais_ la _rotation_ en ligne droite. Convient pour propager la rotation à travers les murs.", + "block.create.encased_shaft.tooltip": "ROTOR ENCASTRÉ", + "block.create.encased_shaft.tooltip.summary": "_Relaie_ la _rotation_ en ligne droite. Convient pour propager la rotation à travers les murs.", "block.create.gearbox.tooltip": "BOÎTE DE VITESSES", - "block.create.gearbox.tooltip.summary": "_Relais_ la _rotation_ dans _quatre_ _directions_. Inverse les connexions directes.", + "block.create.gearbox.tooltip.summary": "_Relaie_ la _rotation_ dans _quatre_ _directions_. Inverse les connexions directes.", - "block.create.gearshift.tooltip": "DÉCALEUR DE ROTATION", - "block.create.gearshift.tooltip.summary": "Une commande pour basculer le sens de rotation des arbres connectés.", + "block.create.gearshift.tooltip": "BOÎTE DE VITESSES", + "block.create.gearshift.tooltip.summary": "Une commande pour basculer le sens de rotation des rotors connectés.", "block.create.gearshift.tooltip.condition1": "Lorsqu'alimenté", "block.create.gearshift.tooltip.behaviour1": "_Inverse_ la rotation sortante.", "block.create.clutch.tooltip": "EMBRAYAGE", - "block.create.clutch.tooltip.summary": "Une commande pour engager / désengager la rotation des arbres connectés.", + "block.create.clutch.tooltip.summary": "Une commande pour engager / désengager la rotation des rotors connectés.", "block.create.clutch.tooltip.condition1": "Lorsqu'alimenté", "block.create.clutch.tooltip.behaviour1": "_Arrête_ de transmettre la rotation de l'autre côté.", "item.create.belt_connector.tooltip": "CONNECTEUR DE TAPIS ROULANTS", - "item.create.belt_connector.tooltip.summary": "Connecte deux _arbres_ ou plus à un _tapis_ _roulant_ _mécanique_. Les arbres connectés auront exactement la même vitesse et le même sens de rotation. La ceinture peut agir comme un _convoyeur_ pour _objets_ et _entités_.", - "item.create.belt_connector.tooltip.control1": "Clic droit sur arbre", - "item.create.belt_connector.tooltip.action1": "Sélectionne l'arbre comme une poulie de la courroie. Les deux arbres sélectionnés doivent être _alignés_ soit _verticalement_, _horizontalement_, ou _diagonalement_ en direction de la courroie.", + "item.create.belt_connector.tooltip.summary": "Connecte deux _rotors_ ou plus à un _tapis_ _roulant_ _mécanique_. Les rotors connectés auront exactement la même vitesse et le même sens de rotation. La ceinture peut agir comme un _convoyeur_ pour _objets_ et _entités_.", + "item.create.belt_connector.tooltip.control1": "Clic droit sur rotor", + "item.create.belt_connector.tooltip.action1": "Sélectionne le rotor comme une poulie de la courroie. Les deux rotors sélectionnés doivent être _alignés_ soit _verticalement_, _horizontalement_, ou _diagonalement_ en direction de la courroie.", "item.create.belt_connector.tooltip.control2": "Clic droit en étant accroupi", "item.create.belt_connector.tooltip.action2": "_Réinitialise_ la première position sélectionnée pour le tapis roulant.", "item.create.goggles.tooltip": "LUNETTES", "item.create.goggles.tooltip.summary": "Une paire de lunettes pour augmenter votre vision avec des _informations_ _kinétiques_ utiles.", - "item.create.goggles.tooltip.condition1": "Lorsque portées", + "item.create.goggles.tooltip.condition1": "Quand portées", "item.create.goggles.tooltip.behaviour1": "Affiche des _indicateurs_ _colorés_ correspondants au _niveau_ _de_ _vitesse_ d'un composant cinétique placé ainsi que _l'impact_ du _stress_ et la _capacité_ des composants individuels.", - "item.create.goggles.tooltip.condition2": "Lorsque vision portée sur une jauge", + "item.create.goggles.tooltip.condition2": "Quand vision portée sur une jauge", "item.create.goggles.tooltip.behaviour2": "Affiche des informations détaillées sur la _vitesse_ ou le _stress_ du réseau auquel la jauge est connectée.", "item.create.wrench.tooltip": "CLÉ", "item.create.wrench.tooltip.summary": "Un outil utile pour travailler sur les engins cinétiques. Peut être utilisé pour _tourner_, _démonter_ et _configurer_ les composants.", - "item.create.wrench.tooltip.control1": "Clic droit a kinetic block", - "item.create.wrench.tooltip.action1": "_Tourne_ les _composents_ proche ou loin de la face avec lequel vous avez interagi.", + "item.create.wrench.tooltip.control1": "Clic droit sur un bloc de Create", + "item.create.wrench.tooltip.action1": "_Tourne_ le _composant_ le long de l'axe dépendant de la face avec lequel vous avez interagi.", "item.create.wrench.tooltip.control2": "Clic droit en étant accroupi", "item.create.wrench.tooltip.action2": "_Démonte_ les _composants_ _cinétiques_ et les replace dans _votre_ _inventaire_.", @@ -768,17 +806,17 @@ "block.create.water_wheel.tooltip": "ROUE À EAU", "block.create.water_wheel.tooltip.summary": "Fournit une _force_ _de_ _rotation_ provenant de _courants_ _d'eau_ adjacents.", - "block.create.encased_fan.tooltip": "VENTILATEUR ENFERMÉ", + "block.create.encased_fan.tooltip": "VENTILATEUR ENCHÂSSÉ", "block.create.encased_fan.tooltip.summary": "Convertit _force_ _de_ _rotation_ en _courants_ _d'air_ et inversement. A une variété d'utilisations.", "block.create.encased_fan.tooltip.condition1": "Lorsqu'alimenté par de la redstone", "block.create.encased_fan.tooltip.behaviour1": "Fournit _force_ _de_ _rotation_ à partir de toute _source_ _de_ _chaleur_ immédiatement en dessous de lui. Le ventilateur doit être tourné vers le bas.", - "block.create.encased_fan.tooltip.condition2": "Lorsque tourné", + "block.create.encased_fan.tooltip.condition2": "Quand tourné", "block.create.encased_fan.tooltip.behaviour2": "_Pousse_ ou _tire_ les entités, selon la vitesse de rotation entrante.", - "block.create.encased_fan.tooltip.condition3": "Lorsque souffle à travers des blocs spéciaux", + "block.create.encased_fan.tooltip.condition3": "Quand souffle à travers des blocs spéciaux", "block.create.encased_fan.tooltip.behaviour3": "Des particules de _liquides_ et de _feu_ sont émises dans le flux d'air. Cela peut être utilisé pour _traiter_ des _objets_.", "block.create.nozzle.tooltip": "BUSE", - "block.create.nozzle.tooltip.summary": "Attachez-le à l'avant d'un _ventilateur_ _enfermé_ pour répartir son effet sur les entités dans _toutes_ les _directions_.", + "block.create.nozzle.tooltip.summary": "Attachez-le à l'avant d'un _ventilateur_ enchâssé_ pour répartir son effet sur les entités dans _toutes_ les _directions_.", "block.create.hand_crank.tooltip": "MANIVELLE", "block.create.hand_crank.tooltip.summary": "Une simple _source_ de _force_ _de_ _rotation_ qui nécessite l'interaction des joueurs.", @@ -787,16 +825,16 @@ "block.create.cuckoo_clock.tooltip": "COUCOU", "block.create.cuckoo_clock.tooltip.summary": "Un bel artisanat pour _décorer_ un espace et _garder_ la _notion_ _du_ _temps_.", - "block.create.cuckoo_clock.tooltip.condition1": "Lorsque tourné", + "block.create.cuckoo_clock.tooltip.condition1": "Quand tourné", "block.create.cuckoo_clock.tooltip.behaviour1": "Affiche le _temps_ _présent_ et joue une mélodie deux fois par jour. _S'active_ une fois le _midi_ et une fois au crépuscule, dès que les _joueurs_ _peuvent_ _dormir_.", "block.create.turntable.tooltip": "PLAQUE TOURNANTE", - "block.create.turntable.tooltip.summary": "Transforme la _force_ _de_ _rotation_ en une nausée.", + "block.create.turntable.tooltip.summary": "Transforme la _force_ _de_ _rotation_ en énergie cinétique.", "block.create.crushing_wheel.tooltip": "ROUE DE CONCASSAGE", "block.create.crushing_wheel.tooltip.summary": "Grandes roues rotatives qui _cassent_ n'importe quoi.", - "block.create.crushing_wheel.tooltip.condition1": "Lorsque fixé à une autre roue de concassage", + "block.create.crushing_wheel.tooltip.condition1": "Quand fixé à une autre roue de concassage", "block.create.crushing_wheel.tooltip.behaviour1": "Forme une machine de concassage pour traiter une variété de choses. Les dents des roues doivent se connecter et se déplacer avec la _même_ _vitesse_ dans des _directions_ _opposées_.", "block.create.mechanical_press.tooltip": "PRESSE MÉCANIQUE", @@ -814,11 +852,11 @@ "block.create.mechanical_mixer.tooltip": "MIXEUR MÉCANIQUE", "block.create.mechanical_mixer.tooltip.summary": "Un fouet cinétique pour appliquer toutes les recettes d'artisanat informes aux objets en dessous. Nécessite une _force_ _de_ _rotation_ constant et un _bassin_ placé en dessous (avec un espace entre les deux).", "block.create.mechanical_mixer.tooltip.condition1": "Lorsqu'au-dessus d'un bassin", - "block.create.mechanical_mixer.tooltip.behaviour1": "Commence à mélanger les objets dans le bassin lorsque tous les ingrédients nécessaires sont présents.", + "block.create.mechanical_mixer.tooltip.behaviour1": "Commence à mélanger les objets dans le bassin Quand tous les ingrédients nécessaires sont présents.", "block.create.mechanical_crafter.tooltip": "ÉTABLI MÉCANIQUE", "block.create.mechanical_crafter.tooltip.summary": "Un assembleur cinétique pour _automatiser_ n'importe quelle recette _en_ _forme_. Placez-en _plusieurs_ _dans_ _une_ _grille_ correspondant à votre recette, et _arrangez_ _leurs_ _tapis_ _roulant_ pour créer un _flux_ qui sort de la grille sur l'un des établis.", - "block.create.mechanical_crafter.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_crafter.tooltip.condition1": "Quand tourné", "block.create.mechanical_crafter.tooltip.behaviour1": "_Démarre_ _le_ _processus_ _d'artisanat_ dès que _tous_ les _établis_ dans la grille ont _reçu_ _un_ _objet_.", "block.create.mechanical_crafter.tooltip.control1": "Lorsqu'utilisation de la clé à l'avant", "block.create.mechanical_crafter.tooltip.action1": "_Fait_ _défiler_ _la_ _direction_ dans laquelle un établi individuel _déplace_ _ses_ _objets_. Pour former une grille de travail, disposer les _tapis_ _roulants_ _dans_ _un_ _flux_ qui déplace tous les articles vers un établi final. Le dernier artisan doit _pointer_ _autrepart_ de la grille.", @@ -838,7 +876,7 @@ "block.create.portable_storage_interface.tooltip": "INTERFACE DE STOCKAGE PORTABLE", "block.create.portable_storage_interface.tooltip.summary": "Un point d'échange portable pour _déplacer_ des _objets_ vers et depuis une _structure_ déplacée par un piston, un roulement, un chariot ou une poulie.", "block.create.portable_storage_interface.tooltip.condition1": "Lorsqu'en mouvement", - "block.create.portable_storage_interface.tooltip.behaviour1": "Interagit avec les _transposeurs_ stationnaires de sorte que les transposeurs faisant _face_ _autrepart_ de l'interface tirent les objets, et les transposeurs ciblant l'interface y _insereront_ les _objets_ de l'inventaire joint. L'engin se bloquera brièvement lorsque les objets seront échangés.", + "block.create.portable_storage_interface.tooltip.behaviour1": "Interagit avec les _transposeurs_ stationnaires de sorte que les transposeurs faisant _face_ _autrepart_ de l'interface tirent les objets, et les transposeurs ciblant l'interface y _insereront_ les _objets_ de l'inventaire joint. L'engin se bloquera brièvement Quand les objets seront échangés.", "block.create.rotation_speed_controller.tooltip": "CONTRÔLEUR DE VITESSE DE ROTATION", @@ -848,17 +886,17 @@ "block.create.mechanical_piston.tooltip": "PISTON MÉCANIQUE", "block.create.mechanical_piston.tooltip.summary": "Une version plus avancée du _piston_. Il utilise une _force_ _de_ rotation_ pour déplacer précisément les structures attachées. Les _pôles_ _d'extension_ _de_ _piston_ à l'arrière définissent la _portée_ de cet appareil. Sans extensions, le piston ne bougera pas. Utilisez un _châssis_ ou un _bloc_ _de_ slime_ pour déplacer plus d'une seule ligne de blocs.", - "block.create.mechanical_piston.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_piston.tooltip.condition1": "Quand tourné", "block.create.mechanical_piston.tooltip.behaviour1": "Commence à déplacer la structure attachée. La vitesse et la direction sont corrélées à la vitesse de rotation entrante.", - "block.create.piston_extension_pole.tooltip": "PÔLE DE PISTON", + "block.create.piston_extension_pole.tooltip": "BARRE DE PISTON", "block.create.piston_extension_pole.tooltip.summary": "Étend la portée des _pistons_ _mécaniques.", "block.create.piston_extension_pole.tooltip.condition1": "Lorsqu'attaché à un piston mécanique", "block.create.piston_extension_pole.tooltip.behaviour1": "Étend la portée du _piston_ d'un bloc", "block.create.mechanical_bearing.tooltip": "ROULEMENT MÉCANIQUE", "block.create.mechanical_bearing.tooltip.summary": "Utilisé pour faire tourner de _plus_ _grande_ _structures_ ou pour exploiter une _force_ _de_ rotation_ contre le vent.", - "block.create.mechanical_bearing.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_bearing.tooltip.condition1": "Quand tourné", "block.create.mechanical_bearing.tooltip.behaviour1": "Démarre les blocs attachés en rotation. Utilisez un _châssis_ ou _bloc_ _de_ _slime_ pour déplacer plus d'un seul bloc.", @@ -866,48 +904,50 @@ "block.create.clockwork_bearing.tooltip": "ROULEMENT MÉCANIQUE HORLOGER", "block.create.clockwork_bearing.tooltip.summary": "Une version avancée du _roulement_ _mécanique_ pour faire tourner jusqu'à deux _aiguilles_ _d'horloge_ en fonction du _temps_ _en-jeu_ actuel.", - "block.create.clockwork_bearing.tooltip.condition1": "Lorsque tourné", + "block.create.clockwork_bearing.tooltip.condition1": "Quand tourné", "block.create.clockwork_bearing.tooltip.behaviour1": "Commence la rotation de la structure attachée vers l'_heure_ _actuelle_. Si une seconde structure est présente, elle servira _d'aiguille_ _des_ _minutes_.", - "block.create.sequenced_gearshift.tooltip": "DÉCALEUR DE ROTATION SÉQUENCÉ", + "block.create.sequenced_gearshift.tooltip": "BOÎITE À VITESSES SÉQUENCÉE", "block.create.sequenced_gearshift.tooltip.summary": "Un _composant_ _utilitaire_ _programmable_, qui peut changer son _débit_ _de_ _rotation_ suivant jusqu'à _5_ _instructions_ _consécutives_. Utilisez-le pour alimenter des roulements mécaniques, des pistons ou des poulies avec plus de contrôle sur le timing et la vitesse. Peut devenir moins précis à des vitesses plus élevées.", "block.create.sequenced_gearshift.tooltip.condition1": "Lorsqu'alimenté par de la redstone", "block.create.sequenced_gearshift.tooltip.behaviour1": "_Commence_ _à_ _exécuter_ les instructions programmées en fonction de la vitesse d'entrée.", "block.create.sequenced_gearshift.tooltip.condition2": "Clic droit", "block.create.sequenced_gearshift.tooltip.behaviour2": "Ouvre _l'interface_ _de_ _configuration_", - "block.create.cart_assembler.tooltip": "ASSEMBLEUR DE CHARIOT", - "block.create.cart_assembler.tooltip.summary": "Monte une structure connectée sur un _chariot_ _passant_.", + "block.create.cart_assembler.tooltip": "ASSEMBLEUR DE WAGON", + "block.create.cart_assembler.tooltip.summary": "Monte une structure connectée sur un _wagon_ _passant_.", "block.create.cart_assembler.tooltip.condition1": "Lorsqu'alimenté par de la redstone", - "block.create.cart_assembler.tooltip.behaviour1": "_Démonte_ les structures montées un _chariot_ _passant_ et les remet dans le monde.", + "block.create.cart_assembler.tooltip.behaviour1": "_Démonte_ les structures montées un _wagon passant_ et les remet dans le monde.", - "block.create.rope_pulley.tooltip": "POULIE DE CORDE", + "block.create.rope_pulley.tooltip": "POULIE", "block.create.rope_pulley.tooltip.summary": "Déplace les _blocs_ et _structures_ attachés _verticalement_. Utilisez un _châssis_ ou _bloc_ _de_ _slime_ pour déplacer plus d'un seul bloc.", - "block.create.rope_pulley.tooltip.condition1": "Lorsque tourné", + "block.create.rope_pulley.tooltip.condition1": "Quand tourné", "block.create.rope_pulley.tooltip.behaviour1": "Commence à déplacer la structure attachée. La vitesse et la direction sont corrélées à la vitesse de rotation entrante.", - "block.create.linear_chassis.tooltip": "CHÂSSIS DE TRADUCTION", + "block.create.linear_chassis.tooltip": "CHÂSSIS LINÉAIRE", "block.create.linear_chassis.tooltip.summary": "Un bloc de base configurable reliant les structures pour le mouvement.", - "block.create.linear_chassis.tooltip.condition1": "Lorsque déplacé", + "block.create.linear_chassis.tooltip.condition1": "Quand déplacé", "block.create.linear_chassis.tooltip.behaviour1": "_Déplace_ tous les _châssis_ _attachés_ avec la même orientation, et une colonne de blocs dans sa portée. Les blocs ne seront tirés que si la face du châssis est _collante_ (Voir [Ctrl]).", "block.create.linear_chassis.tooltip.condition2": "Lorsqu'utilisé avec une clé", "block.create.linear_chassis.tooltip.behaviour2": "Configurez la _portée_ pour ce bloc de châssis. Maintenez CTRL pour modifier également la plage de tous les blocs de châssis connectés.", "block.create.linear_chassis.tooltip.control1": "Clic droit avec une boule de slime", - "block.create.linear_chassis.tooltip.action1": "Rends la face _collante_. Lorsque déplace, le châssis va _tirer_ les blocs attachés, quelle que soit la direction du mouvement.", + "block.create.linear_chassis.tooltip.action1": "Rend la face _collante_. Quand déplacé, le châssis va _tirer_ les blocs attachés, quelle que soit la direction du mouvement.", + "block.create.secondary_linear_chassis.tooltip": "CHÂSSIS LINÉAIRE SECONDAIRE", + "block.create.secondary_linear_chassis.tooltip.summary": "Un deuxième type de _châssis linéaire_ qui ne se connecte pas au premier.", "block.create.radial_chassis.tooltip": "CHÂSSIS DE ROTATION", "block.create.radial_chassis.tooltip.summary": "Un bloc de base configurable reliant les structures pour le mouvement.", - "block.create.radial_chassis.tooltip.condition1": "Lorsque déplacé", + "block.create.radial_chassis.tooltip.condition1": "Quand déplacé", "block.create.radial_chassis.tooltip.behaviour1": "_Déplace_ tous les _châssis_ _attachés_ en colonne, et un cylindre de blocs autour de lui. Les blocs qui l'entourent ne sont déplacés que lorsqu'ils sont à portée et attachés à un côté collant (voir [Ctrl]).", "block.create.radial_chassis.tooltip.condition2": "Lorsqu'utilisé avec une clé", "block.create.radial_chassis.tooltip.behaviour2": "Configure la _portée_ pour ce bloc de châssis. Maintenez CTRL pour modifier également la portée de tous les blocs de châssis connectés.", "block.create.radial_chassis.tooltip.control1": "Clic droit avec une boule de slime", - "block.create.radial_chassis.tooltip.action1": "Rend la face _collante_. Lorsque le châssis se déplace, tous les blocs désignés attachés au côté collant sont déplacés avec lui.", + "block.create.radial_chassis.tooltip.action1": "Rend la face _collante_. Quand le châssis se déplace, tous les blocs désignés attachés au côté collant sont déplacés avec lui.", "block.create.mechanical_drill.tooltip": "PERCEUSE MÉCANIQUE", "block.create.mechanical_drill.tooltip.summary": "Un dispositif mécanique adapté pour _casser_ les _blocs_. Il est déplaceable avec _pistons_ _mécaniques_ ou _roulements_.", - "block.create.mechanical_drill.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_drill.tooltip.condition1": "Quand tourné", "block.create.mechanical_drill.tooltip.behaviour1": "Agit comme un casseur de bloc _stationnaire_. Inflige aussi des _dégats_ aux _entités_ se situant dans sa zone effective.", "block.create.mechanical_drill.tooltip.condition2": "Lorsqu'en mouvement", "block.create.mechanical_drill.tooltip.behaviour2": "Casse les blocs avec lesquels la perceuse entre en collision.", @@ -917,38 +957,44 @@ "block.create.mechanical_harvester.tooltip.condition1": "Lorsqu'en mouvement", "block.create.mechanical_harvester.tooltip.behaviour1": "_Récolte_ toutes les _cultures_ _matures_ que la lame entre en touche et les remet à leur état de croissance initial.", + "block.create.mechanical_plough.tooltip": "CHARRUE MÉCANIQUE", + "block.create.mechanical_plough.tooltip.summary": "Une charrue mécanique a divers usages. Elle peut être déplacée à l'aide de _pistons mécaniques_, de _roulements_ ou d'autres dispositifs de commande.", + "block.create.mechanical_plough.tooltip.condition1": "Lorsqu’en mouvement", + "block.create.mechanical_plough.tooltip.behaviour1": "_Casse les blocs_ avec lesquels _on ne peut pas entrer en collision_, tels que les torches, les sentiers ou les couches de neige. _Applique_ son _mouvement_ aux _entités_ sans les blesser. _Bêche les blocs de terre_ comme si une houe était utilisée sur ceux-ci.", "block.create.mechanical_saw.tooltip": "SCIE MÉCANIQUE", - "block.create.mechanical_saw.tooltip.summary": "Convient pour _couper_ des _arbres_ efficacement et pour _tailler_ des _blocs_ dans leurs homologues menuisés. Il est déplaceable à l'aide de _pistons_ _mécaniques_ ou _roulements_.", - "block.create.mechanical_saw.tooltip.condition1": "Lorsque tourné vers le haut", - "block.create.mechanical_saw.tooltip.behaviour1": "Applique les _recettes_ de _sciage_ et de _taillerie_ aux éléments jetés ou insérés dedans. Lorsque plusieurs sorties sont possibles, il les parcourt à moins qu'un _filtre_ ne soit affecté.", + "block.create.mechanical_saw.tooltip.summary": "Convient pour _couper_ des _rotors_ efficacement et pour _tailler_ des _blocs_ dans leurs homologues menuisés. Il est déplaceable à l'aide de _pistons_ _mécaniques_ ou _roulements_.", + "block.create.mechanical_saw.tooltip.condition1": "Quand tourné vers le haut", + "block.create.mechanical_saw.tooltip.behaviour1": "Applique les _recettes_ de _sciage_ et de _taillerie_ aux éléments jetés ou insérés dedans. Quand plusieurs sorties sont possibles, il les parcourt à moins qu'un _filtre_ ne soit affecté.", "block.create.mechanical_saw.tooltip.condition2": "Lorsqu'à l'horizontal", - "block.create.mechanical_saw.tooltip.behaviour2": "_Casse_ les _troncs_ devant elle. Si le tronc a supportait un arbre, _l'arbre_ _tombera_ loin de la scie.", + "block.create.mechanical_saw.tooltip.behaviour2": "_Casse_ les _troncs_ devant elle. Si le tronc a supportait un rotor, _le rotor_ _tombera_ loin de la scie.", "block.create.mechanical_saw.tooltip.condition3": "Lorsqu'en mouvement", - "block.create.mechanical_saw.tooltip.behaviour3": "_Coupe_ tous les _arbres_ avec lesquels la scie entre en collision.", + "block.create.mechanical_saw.tooltip.behaviour3": "_Coupe_ tous les _rotors_ avec lesquels la scie entre en collision.", "block.create.stockpile_switch.tooltip": "DÉTÉCTEUR DE STOCKAGE", "block.create.stockpile_switch.tooltip.summary": "Bascule un signal Redstone basé sur _l'espace_ _de_ _stockage_ dans le conteneur attaché.", "block.create.stockpile_switch.tooltip.condition1": "Lorsqu'en dessous de la limite de stockage minimum", "block.create.stockpile_switch.tooltip.behaviour1": "Arrête de fournir de _l'énergie_", + "block.create.content_observer.tooltip": "OBSERVATEUR DE CONTENU", + "block.create.content_observer.tooltip.summary": "_Détecte les objets_ à l'intérieur des _conteneurs_ et des _transporteurs_ correspondant à un _filtre_ configuré. Tant que l'_inventaire_, le _tapis roulant_ ou la _glissière_ observé _contient_ un objet correspondant, ce composant émet un _signal de redstone_. Quand un _entonnoir_ observé _transfère_ un objet correspondant, ce composant émet une _impulsion de redstone_.", - "block.create.redstone_link.tooltip": "LIAISON REDSTONE", - "block.create.redstone_link.tooltip.summary": "Points de terminaison pour les connexions de _redstone_ _sans-fil_. Peut être attribué des _fréquences_ en utilisant n'importe quel objet. La portée du signal est limitée, quoique raisonnablement loin.", - "block.create.redstone_link.tooltip.condition1": "Lorsqu'alimenté", - "block.create.redstone_link.tooltip.behaviour1": "La réception de liens de la même _fréquence_ produira un signal redstone.", + "block.create.redstone_link.tooltip": "LIEN DE REDSTONE", + "block.create.redstone_link.tooltip.summary": "Terminaux pour les connexions de _redstone_ _sans-fil_. Peut être attribué des _fréquences_ en utilisant n'importe quel objet. La portée du signal est limitée, nonobstant raisonnablement loin.", + "block.create.redstone_link.tooltip.condition1": "Quand alimenté", + "block.create.redstone_link.tooltip.behaviour1": "Les liens de la même _fréquence_ configurés en réception produira un signal redstone.", "block.create.redstone_link.tooltip.control1": "Clic droit avec un objet", "block.create.redstone_link.tooltip.action1": "Définit la _fréquence_ sur cet élément. Un total de _deux_ _différents_ _objets_ peuvent être utilisés en combinaison pour définir une fréquence.", "block.create.redstone_link.tooltip.control2": "Clic droit en étant accroupi", - "block.create.redstone_link.tooltip.action2": "TBascule entre le mode _receveur_ et _transmetteur_.", + "block.create.redstone_link.tooltip.action2": "Bascule entre le mode _récepteur_ et _transmetteur_.", - "block.create.redstone_contact.tooltip": "redstone_contact REDSTONE", - "block.create.redstone_contact.tooltip.summary": "N'émet de l'énergie que par paires. Il est mobile avec _pistons_ _mécaniques_ ou _roulements_.", - "block.create.redstone_contact.tooltip.condition1": "Lorsque tourné vers un autre redstone_contact", - "block.create.redstone_contact.tooltip.behaviour1": "Fournit un _signal_ _redstone_.", - "block.create.redstone_contact.tooltip.condition2": "Lorsqu'en mouvement", - "block.create.redstone_contact.tooltip.behaviour2": "Déclenche tous les redstone_contacts fixes qu'il passe.", + "block.create.redstone_contact.tooltip": "CONTACT DE REDSTONE", + "block.create.redstone_contact.tooltip.summary": "N'émet de l'énergie que par paires. Il est mobile avec des _pistons_ _mécaniques_ ou _roulements_.", + "block.create.redstone_contact.tooltip.condition1": "Quand tourné vers un autre contact de redstone", + "block.create.redstone_contact.tooltip.behaviour1": "Fournit un _signal_ de _redstone_.", + "block.create.redstone_contact.tooltip.condition2": "Quand en mouvement", + "block.create.redstone_contact.tooltip.behaviour2": "Déclenche tous les contacts de redstone fixes qu'il passe.", "block.create.adjustable_crate.tooltip": "CAISSE AJUSTABLE", "block.create.adjustable_crate.tooltip.summary": "Ce _conteneur_ _de_ _stockage_ permet un contrôle manuel de sa capacité. Il peut contenir jusqu'à _16_ _piles_ de n'importe quel objet. Prend en charge les _comparateurs_ _de_ _redstone_.", @@ -957,16 +1003,20 @@ "block.create.creative_crate.tooltip": "CAISSE CRÉATIVE", "block.create.creative_crate.tooltip.summary": "Fournit une réserve infinie de blocs aux _Schémacanons_ adjacents.", + "block.create.creative_crate.tooltip.condition1": "Quand un objet se trouve dans l'emplacement de filtrage", + "block.create.creative_crate.tooltip.behaviour1": "Tout ce qui _extrait_ de ce conteneur aura une _alimentation illimitée_ de l'objet spécifié. Les objets _insérés_ dans cette caisse seront _éliminés_.", "block.create.deployer.tooltip": "DÉPLOYEUR", "block.create.deployer.tooltip.summary": "_Frappe_, _utilise_ et _active_. Cette machine essaiera _d'imiter_ un _joueur_ autant que possible. Peut _prendre_ et _déposer_ des _objets_ dans _l'inventaire_ adjacent. Peut être affecté à une pile d'éléments en tant que _filtre_.", - "block.create.deployer.tooltip.condition1": "Lorsque tourné", + "block.create.deployer.tooltip.condition1": "Quand tourné", "block.create.deployer.tooltip.behaviour1": "Étend son bras et _active_ dans l'espace de bloc _2m_ _devant_ de lui-même.", "block.create.deployer.tooltip.condition2": "Clic droit avec une clé", "block.create.deployer.tooltip.behaviour2": "Bascule le mode frappe. Dans le _mode_ _frappe_, le déployeur tentera d'utiliser son élément pour _casser_ les _blocs_ ou infliger des _dégats_ aux _entités_.", + "block.create.deployer.tooltip.condition3": "Quand un filtre est attribué", + "block.create.deployer.tooltip.behaviour3": "Le déploiement n'est activé que si l'élément tenu _correspond_ au _filtre._ Les éléments ne correspondant pas ne peuvent pas être insérés ; les éléments tenus correspondant au filtre ne peuvent pas être extraits.", - "block.create.brass_casing.tooltip": "BOÎTIER EN LAITON", - "block.create.brass_casing.tooltip.summary": "Boîtier de machine robuste avec une variété d'utilisations. Sans danger pour la décoration.", + "block.create.brass_casing.tooltip": "REVÊTEMENT EN LAITON", + "block.create.brass_casing.tooltip.summary": "Revêtement de machine robuste avec une variété d'utilisations. Sans danger pour la décoration.", "block.create.pulse_repeater.tooltip": "RÉPÉTEUR D'IMPULSIONS", "block.create.pulse_repeater.tooltip.summary": "Un circuit simple pour couper les signaux de redstone passant à une longueur de _1_ _tick_.", @@ -989,20 +1039,36 @@ "block.create.speedometer.tooltip": "COMPTEUR DE VITESSE", "block.create.speedometer.tooltip.summary": "Mesure et affiche la _ vitesse de rotation _ des composants cinétiques attachés. Prend en charge les _comparateurs_ _de_ _redstone_.", - "block.create.speedometer.tooltip.condition1": "Lorsque tourné", + "block.create.speedometer.tooltip.condition1": "Quand tourné", "block.create.speedometer.tooltip.behaviour1": "Indique une couleur correspondant au niveau de vitesse. _Vert_ indique une rotation lente, _Bleu_ modérée et _violet_ rapide. Certains composants mécaniques nécessitent une vitesse suffisante pour fonctionner correctement.", "block.create.stressometer.tooltip": "STRESSOMÈTRE", "block.create.stressometer.tooltip.summary": "Mesure et affiche la _stress__ globale du réseau cinétique attaché. Prend en charge les _comparateurs_ _de_ _redstone_.", - "block.create.stressometer.tooltip.condition1": "Lorsque tourné", + "block.create.stressometer.tooltip.condition1": "Quand tourné", "block.create.stressometer.tooltip.behaviour1": "Indique une couleur correspondant au niveau de contrainte. Les _réseaux_ _surchargés_ cesseront de bouger. Le stress peut être soulagé en ajoutant plus de _sources_ _rotationnelles_ au réseau.", + "item.create.sand_paper.tooltip": "PAPIER DE VERRE", + "item.create.sand_paper.tooltip.summary": "Un papier rugueux qui peut être utilisé pour _polir des matériaux_. Peut être appliqué automatiquement à l'aide du déployeur.", + "item.create.sand_paper.tooltip.condition1": "Quand utilisé", + "item.create.sand_paper.tooltip.behaviour1": "Polit les objets qui se tenus dans la _main secondaire_ ou par terre quand on les _regarde_.", + + "item.create.super_glue.tooltip": "COLLE EXTRA-FORTE", + "item.create.super_glue.tooltip.summary": "Collez un bloc à un autre, et ils seront à jamais inséparables.", + "item.create.super_glue.tooltip.condition1": "Quand utilisé", + "item.create.super_glue.tooltip.behaviour1": "Rend la face _cliquée_ d'un bloc _collante_. Les blocs attachés aux faces collantes seront entraînés par des _pistons mécaniques_, _des roulements_ et d'autres contrôleurs.", + "item.create.super_glue.tooltip.condition2": "Quand tenu en main secondaire", + "item.create.super_glue.tooltip.behaviour2": "Attache automatiquement les blocs placés de la main principale à la _face_ contre laquelle ils ont été _placés_.", + + "item.create.builders_tea.tooltip": "THÉ DU CONSTRUCTEUR", + "item.create.builders_tea.tooltip.summary": "La boisson parfaite pour commencer la journée - _motivante_ et _rasasiante_.", + "item.create.refined_radiance.tooltip": "ÉCLAT RAFFINÉ", "item.create.refined_radiance.tooltip.summary": "Un matériau chromatique forgé à partir de _lumière_ _absorbée_.", "item.create.shadow_steel.tooltip": "ACIER SOMBRE", "item.create.shadow_steel.tooltip.summary": "Un matériau chromatique forgé _dans_ _le_ _néant_.", + "item.create.minecart_coupling.tooltip": "LIEN POUR WAGONS", "item.create.crafter_slot_cover.tooltip": "COUVERCLE D'EMPLACEMENT", "item.create.crafter_slot_cover.tooltip.summary": "Utilisé pour marquer un _établi_ _mécanique_ comme un emplacement vide dans une recette. Les établis ne doivent pas nécessairement former une grille carrée complète. C'est utile quand il y a des recettes où les _ingredients_ _sont_ _en_ _diagonale_ les uns aux autres.", @@ -1012,7 +1078,7 @@ "create.tooltip.randomWipDescription0": "Veuillez garder cet objet hors de portée des enfants.", "create.tooltip.randomWipDescription1": "Un bébé panda meurt chaque fois que vous utilisez cet objet. Chaque. Fois.", "create.tooltip.randomWipDescription2": "À utiliser à vos risques et périls.", - "create.tooltip.randomWipDescription3": "Ce n'est pas l'objet que vous recherchez, *agites les doigts* veuillez vous disperser.", + "create.tooltip.randomWipDescription3": "Ce n'est pas l'objet que vous recherchez, *agite les doigts* circulez.", "create.tooltip.randomWipDescription4": "Cet objet s'autodétruit en 10 secondes. 10, 9, 8...", "create.tooltip.randomWipDescription5": "Croyez-moi, c'est inutile.", "create.tooltip.randomWipDescription6": "En utilisant cet article, vous êtes responsables et acceptez ses conditions.", @@ -1021,4 +1087,4 @@ "_": "Thank you for translating Create!" -} \ No newline at end of file +} From 88f80c6240a8ac2b9675291ab1a4b7cb5eaea947 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 6 Feb 2021 17:48:03 +0100 Subject: [PATCH 25/31] Refresh unfinished/fr_fr template file --- src/generated/resources/.cache/cache | 4 +- .../assets/create/lang/unfinished/fr_fr.json | 338 +++++++++--------- 2 files changed, 171 insertions(+), 171 deletions(-) diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 0cd1576c7..7546069c8 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -404,7 +404,7 @@ e3f618c5b622d21880de858678d1802cbf65e615 assets/create/lang/en_ud.json acc852d80378b426d7ee6cb59c169e06b6d63b25 assets/create/lang/en_us.json 30ce93c56557cea2f384a47b549fb893700523a5 assets/create/lang/unfinished/de_de.json 77b8310f3cbed36fa0d2ee29e65ac6aee0c2adc2 assets/create/lang/unfinished/es_mx.json -b8e44c8c33b3c36b850f579e317103eb57f85f07 assets/create/lang/unfinished/fr_fr.json +8db9f9147dcef8c8182c548a524f96f578c116ec assets/create/lang/unfinished/fr_fr.json 89f7029d73733938ee9f900fc36d52ab7fc97563 assets/create/lang/unfinished/it_it.json b1935e7f8d79d1112e1685adb42daedb976ac6d7 assets/create/lang/unfinished/ja_jp.json 23aaf879d07a24775aeba3b98c355c992b24f28b assets/create/lang/unfinished/ko_kr.json @@ -3539,7 +3539,7 @@ d3fdb8ece6cb072a93ddb64a0baad5ac952117a4 data/create/recipes/weathered_limestone eedf31af7134d03656c5fa57229982f9c5bed07c data/create/tags/blocks/brittle.json 13b55d6e905a02403d2e95e9ba2357f99c5f2241 data/create/tags/blocks/fan_heaters.json 3bc64e3a1e7980237435b1770a9ba2102d57fcd4 data/create/tags/blocks/fan_transparent.json -745a82505a68a6482407d87374e356781406ab46 data/create/tags/blocks/safe_nbt.json +c81ea194e808985847159b201140d4aa4cbcca65 data/create/tags/blocks/safe_nbt.json c9ac7e3e5ec18554e7184168d65e9b8e44ef5610 data/create/tags/blocks/sails.json 6cdeeac1689f7b5bfd9bc40b462143d8eaf3ad0b data/create/tags/blocks/seats.json 50936b211d94167a35ec78c89954082a336b6269 data/create/tags/blocks/valve_handles.json diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index d62c0b757..f9524d01b 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 730", + "_": "Missing Localizations: 666", "_": "->------------------------] Game Elements [------------------------<-", @@ -10,83 +10,83 @@ "block.create.adjustable_pulse_repeater": "Répéteur d'impulsions réglable", "block.create.adjustable_repeater": "Répéteur réglable", "block.create.analog_lever": "Levier analogique", - "block.create.andesite_belt_funnel": "UNLOCALIZED: Andesite Belt Funnel", + "block.create.andesite_belt_funnel": "Entonnoir en andésite pour tapis roulant", "block.create.andesite_bricks": "Briques d'andésite", "block.create.andesite_bricks_slab": "Dalle en briques d'andésite", "block.create.andesite_bricks_stairs": "Escalier en briques d'andésite", "block.create.andesite_bricks_wall": "Mur en briques d'andésite", - "block.create.andesite_casing": "Boîtier en andésite", + "block.create.andesite_casing": "Revêtement en andésite", "block.create.andesite_cobblestone": "Pierres d'andésite", "block.create.andesite_cobblestone_slab": "Dalles en pierres d'andésite", "block.create.andesite_cobblestone_stairs": "Escaliers en pierres d'andésite", "block.create.andesite_cobblestone_wall": "Mur en pierres d'andésite", - "block.create.andesite_encased_shaft": "Arbre mécanique dans un revêtement en andésite", + "block.create.andesite_encased_shaft": "Rotor dans un revêtement en andésite", "block.create.andesite_funnel": "Entonnoir en andésite", "block.create.andesite_pillar": "Pilier en andésite", "block.create.andesite_tunnel": "Tunnel en andésite", "block.create.basin": "Bassin", "block.create.belt": "Tapis roulant", "block.create.birch_window": "Fenêtre en bouleau", - "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", - "block.create.black_sail": "UNLOCALIZED: Black Sail", - "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.black_valve_handle": "UNLOCALIZED: Black Valve Handle", - "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", - "block.create.blue_sail": "UNLOCALIZED: Blue Sail", - "block.create.blue_seat": "UNLOCALIZED: Blue Seat", - "block.create.blue_valve_handle": "UNLOCALIZED: Blue Valve Handle", - "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", - "block.create.brass_block": "UNLOCALIZED: Brass Block", - "block.create.brass_casing": "Boîtier en laiton", - "block.create.brass_encased_shaft": "UNLOCALIZED: Brass Encased Shaft", - "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", - "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", - "block.create.brown_sail": "UNLOCALIZED: Brown Sail", - "block.create.brown_seat": "UNLOCALIZED: Brown Seat", - "block.create.brown_valve_handle": "UNLOCALIZED: Brown Valve Handle", + "block.create.birch_window_pane": "Vitre en bouleau", + "block.create.black_sail": "Voile noire", + "block.create.black_seat": "Siège noir", + "block.create.black_valve_handle": "Vanne noire", + "block.create.blaze_burner": "Brûleur à blaze", + "block.create.blue_sail": "Voile bleue", + "block.create.blue_seat": "Siège bleu", + "block.create.blue_valve_handle": "Vanne bleue", + "block.create.brass_belt_funnel": "Entonnoir en laiton pour tapis roulant", + "block.create.brass_block": "Bloc de laiton", + "block.create.brass_casing": "Revêtement en laiton", + "block.create.brass_encased_shaft": "Rotor dans un revêtement en laiton", + "block.create.brass_funnel": "Entonnoir en laiton", + "block.create.brass_tunnel": "Tunnel en laiton", + "block.create.brown_sail": "Voile brune", + "block.create.brown_seat": "Siège brun", + "block.create.brown_valve_handle": "Vanne brune", "block.create.cart_assembler": "Assembleur de wagon", - "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", - "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", - "block.create.chiseled_gabbro": "UNLOCALIZED: Chiseled Gabbro", - "block.create.chiseled_limestone": "UNLOCALIZED: Chiseled Limestone", - "block.create.chiseled_scoria": "UNLOCALIZED: Chiseled Scoria", - "block.create.chiseled_weathered_limestone": "UNLOCALIZED: Chiseled Weathered Limestone", - "block.create.chocolate": "UNLOCALIZED: Chocolate", - "block.create.chute": "UNLOCALIZED: Chute", + "block.create.chiseled_dark_scoria": "Scoria sombre taillé", + "block.create.chiseled_dolomite": "Dolomite taillée", + "block.create.chiseled_gabbro": "Gabbro taillé", + "block.create.chiseled_limestone": "Calcaire taillé", + "block.create.chiseled_scoria": "Scoria taillé", + "block.create.chiseled_weathered_limestone": "Calcaire altéré taillé", + "block.create.chocolate": "Chocolat", + "block.create.chute": "Glissière", "block.create.clockwork_bearing": "Roulement mécanique horloger", "block.create.clutch": "Embrayage", "block.create.cogwheel": "Roue dentée", - "block.create.content_observer": "UNLOCALIZED: Content Observer", - "block.create.controller_rail": "UNLOCALIZED: Controller Rail", + "block.create.content_observer": "Observateur de contenu", + "block.create.controller_rail": "Rails controlleurs", "block.create.copper_block": "Bloc de cuivre", - "block.create.copper_casing": "Boîtier en cuivre", + "block.create.copper_casing": "Revêtement en cuivre", "block.create.copper_ore": "Minerai de cuivre", "block.create.copper_shingles": "Bardeaux de cuivre", - "block.create.copper_tiles": "UNLOCALIZED: Copper Tiles", - "block.create.copper_valve_handle": "UNLOCALIZED: Copper Valve Handle", + "block.create.copper_tiles": "Tuiles en cuivre", + "block.create.copper_valve_handle": "Vanne en cuivre", "block.create.creative_crate": "Créateur de schémacanon", - "block.create.creative_fluid_tank": "UNLOCALIZED: Creative Fluid Tank", + "block.create.creative_fluid_tank": "Réservoir créatif", "block.create.creative_motor": "Moteur", "block.create.crushing_wheel": "Roue de concassage", - "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", + "block.create.crushing_wheel_controller": "Contrôleur de roue de concassage", "block.create.cuckoo_clock": "Horloge à coucou", - "block.create.cyan_sail": "UNLOCALIZED: Cyan Sail", - "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", - "block.create.cyan_valve_handle": "UNLOCALIZED: Cyan Valve Handle", - "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", - "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", + "block.create.cyan_sail": "Voile cyan", + "block.create.cyan_seat": "Siège cyan", + "block.create.cyan_valve_handle": "Vanne cyan", + "block.create.dark_oak_window": "fenêtre en chêne sombre", + "block.create.dark_oak_window_pane": "Vitre en chêne sombre", "block.create.dark_scoria": "Scorie sombre", "block.create.dark_scoria_bricks": "Briques de scorie sombre", "block.create.dark_scoria_bricks_slab": "Dalles de briques de scorie sombre", "block.create.dark_scoria_bricks_stairs": "Escaliers de briques de scorie sombre", "block.create.dark_scoria_bricks_wall": "Muret de briques de scorie sombre", - "block.create.dark_scoria_cobblestone": "UNLOCALIZED: Dark Scoria Cobblestone", + "block.create.dark_scoria_cobblestone": "Pierres de scorie sombre", "block.create.dark_scoria_cobblestone_slab": "UNLOCALIZED: Dark Scoria Cobblestone Slab", "block.create.dark_scoria_cobblestone_stairs": "UNLOCALIZED: Dark Scoria Cobblestone Stairs", "block.create.dark_scoria_cobblestone_wall": "UNLOCALIZED: Dark Scoria Cobblestone Wall", "block.create.dark_scoria_pillar": "UNLOCALIZED: Dark Scoria Pillar", "block.create.deployer": "Déployeur", - "block.create.depot": "UNLOCALIZED: Depot", + "block.create.depot": "Dépot", "block.create.diorite_bricks": "Briques de diorite", "block.create.diorite_bricks_slab": "UNLOCALIZED: Diorite Bricks Slab", "block.create.diorite_bricks_stairs": "UNLOCALIZED: Diorite Bricks Stairs", @@ -96,18 +96,18 @@ "block.create.diorite_cobblestone_stairs": "UNLOCALIZED: Diorite Cobblestone Stairs", "block.create.diorite_cobblestone_wall": "UNLOCALIZED: Diorite Cobblestone Wall", "block.create.diorite_pillar": "UNLOCALIZED: Diorite Pillar", - "block.create.dolomite": "Dolomie", - "block.create.dolomite_bricks": "Briques de dolomie", - "block.create.dolomite_bricks_slab": "Dalle de briques de dolomie", - "block.create.dolomite_bricks_stairs": "Escaliers de briques de dolomie", - "block.create.dolomite_bricks_wall": "Muret de briques de dolomie", + "block.create.dolomite": "Dolomite", + "block.create.dolomite_bricks": "Briques de dolomite", + "block.create.dolomite_bricks_slab": "Dalle de briques de dolomite", + "block.create.dolomite_bricks_stairs": "Escaliers de briques de dolomite", + "block.create.dolomite_bricks_wall": "Muret de briques de dolomite", "block.create.dolomite_cobblestone": "UNLOCALIZED: Dolomite Cobblestone", "block.create.dolomite_cobblestone_slab": "UNLOCALIZED: Dolomite Cobblestone Slab", "block.create.dolomite_cobblestone_stairs": "UNLOCALIZED: Dolomite Cobblestone Stairs", "block.create.dolomite_cobblestone_wall": "UNLOCALIZED: Dolomite Cobblestone Wall", - "block.create.dolomite_pillar": "Pillier de dolomie", - "block.create.encased_chain_drive": "UNLOCALIZED: Encased Chain Drive", - "block.create.encased_fan": "Ventilateur enfermé", + "block.create.dolomite_pillar": "Pillier de dolomite", + "block.create.encased_chain_drive": "Chaine de transmission", + "block.create.encased_fan": "Ventilateur enchâssé", "block.create.encased_fluid_pipe": "UNLOCALIZED: Encased Fluid Pipe", "block.create.fancy_andesite_bricks": "UNLOCALIZED: Fancy Andesite Bricks", "block.create.fancy_andesite_bricks_slab": "UNLOCALIZED: Fancy Andesite Bricks Slab", @@ -308,12 +308,12 @@ "block.create.pink_sail": "UNLOCALIZED: Pink Sail", "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.pink_valve_handle": "UNLOCALIZED: Pink Valve Handle", - "block.create.piston_extension_pole": "Pôle d'extension de piston", + "block.create.piston_extension_pole": "Barre d'extension de piston", "block.create.polished_dark_scoria": "Scorie sombre polie", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", "block.create.polished_dark_scoria_stairs": "UNLOCALIZED: Polished Dark Scoria Stairs", "block.create.polished_dark_scoria_wall": "UNLOCALIZED: Polished Dark Scoria Wall", - "block.create.polished_dolomite": "Dolomie polie", + "block.create.polished_dolomite": "Dolomite polie", "block.create.polished_dolomite_slab": "UNLOCALIZED: Polished Dolomite Slab", "block.create.polished_dolomite_stairs": "UNLOCALIZED: Polished Dolomite Stairs", "block.create.polished_dolomite_wall": "UNLOCALIZED: Polished Dolomite Wall", @@ -329,8 +329,8 @@ "block.create.polished_scoria_slab": "Dalle de scorie polie", "block.create.polished_scoria_stairs": "UNLOCALIZED: Polished Scoria Stairs", "block.create.polished_scoria_wall": "UNLOCALIZED: Polished Scoria Wall", - "block.create.polished_weathered_limestone": "Calcaire patinées polies", - "block.create.polished_weathered_limestone_slab": "Dalle de calcaire patinées", + "block.create.polished_weathered_limestone": "Calcaire altéré polies", + "block.create.polished_weathered_limestone_slab": "Dalle de calcaire altéré", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", @@ -346,7 +346,7 @@ "block.create.red_sail": "UNLOCALIZED: Red Sail", "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.red_valve_handle": "UNLOCALIZED: Red Valve Handle", - "block.create.redstone_contact": "redstone_contact Redstone", + "block.create.redstone_contact": "Contact de redstone", "block.create.redstone_link": "Liaison Redstone", "block.create.refined_radiance_casing": "UNLOCALIZED: Radiant Casing", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -369,7 +369,7 @@ "block.create.secondary_linear_chassis": "UNLOCALIZED: Secondary Linear Chassis", "block.create.sequenced_gearshift": "Décaleur de rotation séquencé", "block.create.shadow_steel_casing": "UNLOCALIZED: Shadow Casing", - "block.create.shaft": "Arbre mécanique", + "block.create.shaft": "Rotor", "block.create.smart_chute": "UNLOCALIZED: Smart Chute", "block.create.smart_fluid_pipe": "UNLOCALIZED: Smart Fluid Pipe", "block.create.speedometer": "Compteur de vitesse", @@ -385,16 +385,16 @@ "block.create.vertical_framed_glass": "Fenêtre en verre verticale", "block.create.vertical_framed_glass_pane": "Vitre encadrée verticale", "block.create.water_wheel": "Roue à eau", - "block.create.weathered_limestone": "Calcaire patinées", - "block.create.weathered_limestone_bricks": "Briques de calcaire patinées", - "block.create.weathered_limestone_bricks_slab": "Dalle de briques de calcaire patinées", - "block.create.weathered_limestone_bricks_stairs": "Escaliers de briques de calcaire patinées", - "block.create.weathered_limestone_bricks_wall": "Muret de briques de calcaire patinées", + "block.create.weathered_limestone": "Calcaire altéré", + "block.create.weathered_limestone_bricks": "Briques de Calcaire altéré", + "block.create.weathered_limestone_bricks_slab": "Dalle de briques de Calcaire altéré", + "block.create.weathered_limestone_bricks_stairs": "Escaliers de briques de Calcaire altéré", + "block.create.weathered_limestone_bricks_wall": "Muret de briques de Calcaire altéré", "block.create.weathered_limestone_cobblestone": "UNLOCALIZED: Weathered Limestone Cobblestone", "block.create.weathered_limestone_cobblestone_slab": "UNLOCALIZED: Weathered Limestone Cobblestone Slab", "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", - "block.create.weathered_limestone_pillar": "Pillier de calcaire patinées", + "block.create.weathered_limestone_pillar": "Pillier de Calcaire altéré", "block.create.white_sail": "UNLOCALIZED: White Sail", "block.create.white_seat": "UNLOCALIZED: White Seat", "block.create.white_valve_handle": "UNLOCALIZED: White Valve Handle", @@ -478,7 +478,7 @@ "item.create.schematic_and_quill": "Schéma et plume", "item.create.shadow_steel": "Acier sombre", "item.create.super_glue": "Colle extra-forte", - "item.create.tree_fertilizer": "Engrais pour arbre", + "item.create.tree_fertilizer": "Engrais pour arbres", "item.create.vertical_gearbox": "Boîte de transfert verticale", "item.create.wand_of_symmetry": "Bâton de symétrie", "item.create.wheat_flour": "Farine", @@ -496,7 +496,7 @@ "advancement.create.andesite_alloy.desc": "Certains matériaux de Create ont des noms bizzares; l'alliage d'andésite est l'un d'entre eux.", "advancement.create.its_alive": "Ça bouge!", "advancement.create.its_alive.desc": "Regardez vos bremiers composants tourner.", - "advancement.create.shifting_gears": "Arbre de transmission", + "advancement.create.shifting_gears": "rotor de transmission", "advancement.create.shifting_gears.desc": "Connectez une roue dentée à une grande roue dentée afin de changer la vitesse de votre engin", "advancement.create.overstressed": "Surtension", "advancement.create.overstressed.desc": "Testez d'abord les limites de la force mécanique", @@ -657,7 +657,7 @@ "itemGroup.create.base": "Create", "itemGroup.create.palettes": "Create Palettes", - "death.attack.create.crush": "%1$s nanana a été traitée par une roue de concassage", + "death.attack.create.crush": "%1$s a été concassé.e", "death.attack.create.fan_fire": "%1$s a été brûlé à mort par l'air chaud", "death.attack.create.fan_lava": "%1$s a été brûlé à mort par un ventilateur de lave", "death.attack.create.mechanical_drill": "%1$s a été empalé par une perceuse mécanique", @@ -796,10 +796,10 @@ "create.contraptions.movement_mode": "Mode de mouvement", "create.contraptions.movement_mode.move_place": "Toujours placer à l'arrêt", "create.contraptions.movement_mode.move_place_returned": "Placer uniquement en position de départ", - "create.contraptions.movement_mode.move_never_place": "Ne placer que lorsque l'ancre est détruite", + "create.contraptions.movement_mode.move_never_place": "Ne placer que Quand l'ancre est détruite", "create.contraptions.movement_mode.rotate_place": "Toujours placer à l'arrêt", "create.contraptions.movement_mode.rotate_place_returned": "Placer uniquement près de l'angle initial", - "create.contraptions.movement_mode.rotate_never_place": "Ne placer que lorsque l'ancre est détruite", + "create.contraptions.movement_mode.rotate_never_place": "Ne placer que Quand l'ancre est détruite", "create.contraptions.cart_movement_mode": "UNLOCALIZED: Cart Movement Mode", "create.contraptions.cart_movement_mode.rotate": "UNLOCALIZED: Always face toward motion", "create.contraptions.cart_movement_mode.rotate_paused": "UNLOCALIZED: Pause actors while rotating", @@ -1118,7 +1118,7 @@ "create.command.killTPSCommand.status.usage.1": "[Create]: use /killtps start to artificially slow down the server tick", "create.command.killTPSCommand.argument.tickTime": "tickTime", - "create.subtitle.schematicannon_launch_block": "Tire de schémacanon", + "create.subtitle.schematicannon_launch_block": "Tir de schémacanon", "create.subtitle.schematicannon_finish": "Fin de schémacanon", "create.subtitle.slime_added": "Bruit de slime", "create.subtitle.mechanical_press_activation": "Activation de la presse mechanique", @@ -1138,7 +1138,7 @@ "item.create.example_item.tooltip.behaviour1": "Donc cet objet fait ceci. (les comportements sont affichés avec shift)", "item.create.example_item.tooltip.condition2": "Et quand cela", "item.create.example_item.tooltip.behaviour2": "Vous pouvez ajouter autant de comportements que vous le souhaitez", - "item.create.example_item.tooltip.control1": "Lorsque Ctrl enfoncé", + "item.create.example_item.tooltip.control1": "Quand Ctrl enfoncé", "item.create.example_item.tooltip.action1": "Ces commandes sont affichées.", "block.create.andesite_encased_shaft.tooltip": "UNLOCALIZED: ANDESITE ENCASED SHAFT", @@ -1298,7 +1298,7 @@ "item.create.wand_of_symmetry.tooltip": "BÂTON DE SYMÉTRIE", "item.create.wand_of_symmetry.tooltip.summary": "Reflète parfaitement le placement des blocs sur les plans configurés.", - "item.create.wand_of_symmetry.tooltip.condition1": "Lorsque positionné dans la barre active", + "item.create.wand_of_symmetry.tooltip.condition1": "Quand positionné dans la barre active", "item.create.wand_of_symmetry.tooltip.behaviour1": "Reste actif", "item.create.wand_of_symmetry.tooltip.control1": "Clic droit au sol", "item.create.wand_of_symmetry.tooltip.action1": "_Créé_ ou _déplace_ le mirroir", @@ -1325,13 +1325,13 @@ "item.create.handheld_worldshaper.tooltip.control3": "Clic droit en étant accroupi", "item.create.handheld_worldshaper.tooltip.action3": "Ouvre l'_interface_ _de_ _configuration_", - "item.create.tree_fertilizer.tooltip": "ENGRAIS POUR ARBRE", - "item.create.tree_fertilizer.tooltip.summary": "Une puissante combinaison de minéraux adaptée pour accélérer la croissance des types d'arbres communs.", - "item.create.tree_fertilizer.tooltip.condition1": "Lorsqu'utilisé sur une pousse d'arbre", - "item.create.tree_fertilizer.tooltip.behaviour1": "Fait pousser des arbres _indépendamment_ de leurs _conditions_ _d'emplacement_", + "item.create.tree_fertilizer.tooltip": "ENGRAIS POUR ARBRES", + "item.create.tree_fertilizer.tooltip.summary": "Une puissante combinaison de minéraux adaptée pour accélérer la croissance des types d'rotors communs.", + "item.create.tree_fertilizer.tooltip.condition1": "Lorsqu'utilisé sur une pousse d'rotor", + "item.create.tree_fertilizer.tooltip.behaviour1": "Fait pousser des rotors _indépendamment_ de leurs _conditions_ _d'emplacement_", "item.create.deforester.tooltip": "DÉFORESTEUR", - "item.create.deforester.tooltip.summary": "Une _hache_ _rayonnante_ capable d'abattre des arbres en une fraction de seconde.", + "item.create.deforester.tooltip.summary": "Une _hache_ _rayonnante_ capable d'abattre des rotors en une fraction de seconde.", "item.create.extendo_grip.tooltip": "UNLOCALIZED: EXTENDO GRIP", "item.create.extendo_grip.tooltip.summary": "UNLOCALIZED: Boioioing! Greatly _increases reach distance_ of the wielder.", @@ -1340,14 +1340,14 @@ "item.create.filter.tooltip": "FILTRE", "item.create.filter.tooltip.summary": "_Contrôle_ les _sorties_ et _entrées_ de dispositifs logistiques avec plus de _précision_, en les comparant à un _ensemble_ _d'objets_ ou à plusieurs _filtres_ _imbriqués_.", - "item.create.filter.tooltip.condition1": "Lorsque dans l'emplacement de filtre", + "item.create.filter.tooltip.condition1": "Quand dans l'emplacement de filtre", "item.create.filter.tooltip.behaviour1": "_Contrôle_ le flux d'object selon sa _configuration_.", "item.create.filter.tooltip.condition2": "Clic droit", "item.create.filter.tooltip.behaviour2": "Ouvre l'_interface_ _de_ _configuration_.", "item.create.attribute_filter.tooltip": "FILTRE D'ATTRIBUTS", "item.create.attribute_filter.tooltip.summary": "_Contrôle_ les _sorties_ et les _entrées_ de dispositifs logistiques avec plus de _précision_, en les comparant à un _ensemble_ _d'objets_ ou à plusieurs _filtres_ _imbriqués_.", - "item.create.attribute_filter.tooltip.condition1": "Lorsque dans l'emplacement de filtre", + "item.create.attribute_filter.tooltip.condition1": "Quand dans l'emplacement de filtre", "item.create.attribute_filter.tooltip.behaviour1": "_Contrôle_ le flux d'object selon sa _configuration_.", "item.create.attribute_filter.tooltip.condition2": "Clic droit", "item.create.attribute_filter.tooltip.behaviour2": "Ouvre l'_interface_ _de_ _configuration_.", @@ -1357,7 +1357,7 @@ "item.create.schematic.tooltip": "SCHÉMA", "item.create.schematic.tooltip.summary": "Contient une structure à positionner et à placer dans le monde. Positionnez l'hologramme comme vous le souhaitez et utilisez un _schémacanon_ pour le construire.", - "item.create.schematic.tooltip.condition1": "Lorsque tenu en main", + "item.create.schematic.tooltip.condition1": "Quand tenu en main", "item.create.schematic.tooltip.behaviour1": "Peut être positionné à l'aide des outils à l'écran.", "item.create.schematic.tooltip.control1": "Clic droit en étant accroupi", "item.create.schematic.tooltip.action1": "Ouvre une _interface_ pour rentrer les _coordonées_ correctes.", @@ -1382,31 +1382,31 @@ "block.create.schematic_table.tooltip": "TABLE À SCHÉMA", "block.create.schematic_table.tooltip.summary": "Écrit les schémas enregistrés dans un _schéma_ _vide_.", - "block.create.schematic_table.tooltip.condition1": "Lorsque donné un schéma vide", + "block.create.schematic_table.tooltip.condition1": "Quand donné un schéma vide", "block.create.schematic_table.tooltip.behaviour1": "Télécharge un fichier choisi à partir de votre dossier de schémas.", - "block.create.shaft.tooltip": "ARBRE MÉCANIQUE", - "block.create.shaft.tooltip.summary": "_Relais_ la _rotation_ en ligne droite.", + "block.create.shaft.tooltip": "ROTOR", + "block.create.shaft.tooltip.summary": "_Relaie_ la _rotation_ en ligne droite.", "block.create.cogwheel.tooltip": "ROUE DENTÉE", - "block.create.cogwheel.tooltip.summary": "_Relais_ la _rotation_ en ligne droite, et aux _roues_ _dentées_ adjacentes.", + "block.create.cogwheel.tooltip.summary": "_Relaie_ la _rotation_ en ligne droite, et aux _roues_ _dentées_ adjacentes.", "block.create.large_cogwheel.tooltip": "GRANDE ROUE DENTÉE", "block.create.large_cogwheel.tooltip.summary": "Une version plus grande de la _roue_ _dentée_, permettant des _changements_ dans la _vitesse_ _de_ _rotation_ lorsqu'il est connecté à son homologue plus petit.", - "block.create.encased_shaft.tooltip": "ARBRE MÉCANIQUE ENBOÎTÉ", - "block.create.encased_shaft.tooltip.summary": "_Relais_ la _rotation_ en ligne droite. Convient pour propager la rotation à travers les murs.", + "block.create.encased_shaft.tooltip": "ROTOR ENCASTRÉ", + "block.create.encased_shaft.tooltip.summary": "_Relaie_ la _rotation_ en ligne droite. Convient pour propager la rotation à travers les murs.", "block.create.gearbox.tooltip": "BOÎTE DE VITESSES", - "block.create.gearbox.tooltip.summary": "_Relais_ la _rotation_ dans _quatre_ _directions_. Inverse les connexions directes.", + "block.create.gearbox.tooltip.summary": "_Relaie_ la _rotation_ dans _quatre_ _directions_. Inverse les connexions directes.", - "block.create.gearshift.tooltip": "DÉCALEUR DE ROTATION", - "block.create.gearshift.tooltip.summary": "Une commande pour basculer le sens de rotation des arbres connectés.", + "block.create.gearshift.tooltip": "BOÎTE DE VITESSES", + "block.create.gearshift.tooltip.summary": "Une commande pour basculer le sens de rotation des rotors connectés.", "block.create.gearshift.tooltip.condition1": "Lorsqu'alimenté", "block.create.gearshift.tooltip.behaviour1": "_Inverse_ la rotation sortante.", "block.create.clutch.tooltip": "EMBRAYAGE", - "block.create.clutch.tooltip.summary": "Une commande pour engager / désengager la rotation des arbres connectés.", + "block.create.clutch.tooltip.summary": "Une commande pour engager / désengager la rotation des rotors connectés.", "block.create.clutch.tooltip.condition1": "Lorsqu'alimenté", "block.create.clutch.tooltip.behaviour1": "_Arrête_ de transmettre la rotation de l'autre côté.", @@ -1421,23 +1421,23 @@ "block.create.adjustable_chain_gearshift.tooltip.behaviour1": "UNLOCALIZED: _Without_ a signal, adjacent chain drives will relay the _same speed._ With a _full strength_ signal, adjacent chain drives will relay exactly _twice its speed._ Anything inbetween will give results between 1-2x its speed.", "item.create.belt_connector.tooltip": "CONNECTEUR DE TAPIS ROULANTS", - "item.create.belt_connector.tooltip.summary": "Connecte deux _arbres_ ou plus à un _tapis_ _roulant_ _mécanique_. Les arbres connectés auront exactement la même vitesse et le même sens de rotation. La ceinture peut agir comme un _convoyeur_ pour _objets_ et _entités_.", - "item.create.belt_connector.tooltip.control1": "Clic droit sur arbre", - "item.create.belt_connector.tooltip.action1": "Sélectionne l'arbre comme une poulie de la courroie. Les deux arbres sélectionnés doivent être _alignés_ soit _verticalement_, _horizontalement_, ou _diagonalement_ en direction de la courroie.", + "item.create.belt_connector.tooltip.summary": "Connecte deux _rotors_ ou plus à un _tapis_ _roulant_ _mécanique_. Les rotors connectés auront exactement la même vitesse et le même sens de rotation. La ceinture peut agir comme un _convoyeur_ pour _objets_ et _entités_.", + "item.create.belt_connector.tooltip.control1": "Clic droit sur rotor", + "item.create.belt_connector.tooltip.action1": "Sélectionne le rotor comme une poulie de la courroie. Les deux rotors sélectionnés doivent être _alignés_ soit _verticalement_, _horizontalement_, ou _diagonalement_ en direction de la courroie.", "item.create.belt_connector.tooltip.control2": "Clic droit en étant accroupi", "item.create.belt_connector.tooltip.action2": "_Réinitialise_ la première position sélectionnée pour le tapis roulant.", "item.create.goggles.tooltip": "LUNETTES", "item.create.goggles.tooltip.summary": "Une paire de lunettes pour augmenter votre vision avec des _informations_ _kinétiques_ utiles.", - "item.create.goggles.tooltip.condition1": "Lorsque portées", + "item.create.goggles.tooltip.condition1": "Quand portées", "item.create.goggles.tooltip.behaviour1": "Affiche des _indicateurs_ _colorés_ correspondants au _niveau_ _de_ _vitesse_ d'un composant cinétique placé ainsi que _l'impact_ du _stress_ et la _capacité_ des composants individuels.", - "item.create.goggles.tooltip.condition2": "Lorsque vision portée sur une jauge", + "item.create.goggles.tooltip.condition2": "Quand vision portée sur une jauge", "item.create.goggles.tooltip.behaviour2": "Affiche des informations détaillées sur la _vitesse_ ou le _stress_ du réseau auquel la jauge est connectée.", "item.create.wrench.tooltip": "CLÉ", "item.create.wrench.tooltip.summary": "Un outil utile pour travailler sur les engins cinétiques. Peut être utilisé pour _tourner_, _démonter_ et _configurer_ les composants.", - "item.create.wrench.tooltip.control1": "Clic droit a kinetic block", - "item.create.wrench.tooltip.action1": "_Tourne_ les _composents_ proche ou loin de la face avec lequel vous avez interagi.", + "item.create.wrench.tooltip.control1": "Clic droit sur un bloc de Create", + "item.create.wrench.tooltip.action1": "_Tourne_ le _composant_ le long de l'axe dépendant de la face avec lequel vous avez interagi.", "item.create.wrench.tooltip.control2": "Clic droit en étant accroupi", "item.create.wrench.tooltip.action2": "_Démonte_ les _composants_ _cinétiques_ et les replace dans _votre_ _inventaire_.", @@ -1447,17 +1447,17 @@ "block.create.water_wheel.tooltip": "ROUE À EAU", "block.create.water_wheel.tooltip.summary": "Fournit une _force_ _de_ _rotation_ provenant de _courants_ _d'eau_ adjacents.", - "block.create.encased_fan.tooltip": "VENTILATEUR ENFERMÉ", + "block.create.encased_fan.tooltip": "VENTILATEUR ENCHÂSSÉ", "block.create.encased_fan.tooltip.summary": "Convertit _force_ _de_ _rotation_ en _courants_ _d'air_ et inversement. A une variété d'utilisations.", "block.create.encased_fan.tooltip.condition1": "Lorsqu'alimenté par de la redstone", "block.create.encased_fan.tooltip.behaviour1": "Fournit _force_ _de_ _rotation_ à partir de toute _source_ _de_ _chaleur_ immédiatement en dessous de lui. Le ventilateur doit être tourné vers le bas.", - "block.create.encased_fan.tooltip.condition2": "Lorsque tourné", + "block.create.encased_fan.tooltip.condition2": "Quand tourné", "block.create.encased_fan.tooltip.behaviour2": "_Pousse_ ou _tire_ les entités, selon la vitesse de rotation entrante.", - "block.create.encased_fan.tooltip.condition3": "Lorsque souffle à travers des blocs spéciaux", + "block.create.encased_fan.tooltip.condition3": "Quand souffle à travers des blocs spéciaux", "block.create.encased_fan.tooltip.behaviour3": "Des particules de _liquides_ et de _feu_ sont émises dans le flux d'air. Cela peut être utilisé pour _traiter_ des _objets_.", "block.create.nozzle.tooltip": "BUSE", - "block.create.nozzle.tooltip.summary": "Attachez-le à l'avant d'un _ventilateur_ _enfermé_ pour répartir son effet sur les entités dans _toutes_ les _directions_.", + "block.create.nozzle.tooltip.summary": "Attachez-le à l'avant d'un _ventilateur_ enchâssé_ pour répartir son effet sur les entités dans _toutes_ les _directions_.", "block.create.hand_crank.tooltip": "MANIVELLE", "block.create.hand_crank.tooltip.summary": "Une simple _source_ de _force_ _de_ _rotation_ qui nécessite l'interaction des joueurs.", @@ -1466,11 +1466,11 @@ "block.create.cuckoo_clock.tooltip": "COUCOU", "block.create.cuckoo_clock.tooltip.summary": "Un bel artisanat pour _décorer_ un espace et _garder_ la _notion_ _du_ _temps_.", - "block.create.cuckoo_clock.tooltip.condition1": "Lorsque tourné", + "block.create.cuckoo_clock.tooltip.condition1": "Quand tourné", "block.create.cuckoo_clock.tooltip.behaviour1": "Affiche le _temps_ _présent_ et joue une mélodie deux fois par jour. _S'active_ une fois le _midi_ et une fois au crépuscule, dès que les _joueurs_ _peuvent_ _dormir_.", "block.create.turntable.tooltip": "PLAQUE TOURNANTE", - "block.create.turntable.tooltip.summary": "Transforme la _force_ _de_ _rotation_ en une nausée.", + "block.create.turntable.tooltip.summary": "Transforme la _force_ _de_ _rotation_ en énergie cinétique.", "block.create.millstone.tooltip": "UNLOCALIZED: MILLSTONE", "block.create.millstone.tooltip.summary": "UNLOCALIZED: A kinetic component suitable for _grinding_ inserted _materials_. Can be powered by an adjacent cogwheel or by connecting to the shaft at the bottom. Results have to be extracted from the component.", @@ -1481,7 +1481,7 @@ "block.create.crushing_wheel.tooltip": "ROUE DE CONCASSAGE", "block.create.crushing_wheel.tooltip.summary": "Grandes roues rotatives qui _cassent_ n'importe quoi.", - "block.create.crushing_wheel.tooltip.condition1": "Lorsque fixé à une autre roue de concassage", + "block.create.crushing_wheel.tooltip.condition1": "Quand fixé à une autre roue de concassage", "block.create.crushing_wheel.tooltip.behaviour1": "Forme une machine de concassage pour traiter une variété de choses. Les dents des roues doivent se connecter et se déplacer avec la _même_ _vitesse_ dans des _directions_ _opposées_.", "block.create.mechanical_press.tooltip": "PRESSE MÉCANIQUE", @@ -1511,11 +1511,11 @@ "block.create.mechanical_mixer.tooltip": "MIXEUR MÉCANIQUE", "block.create.mechanical_mixer.tooltip.summary": "Un fouet cinétique pour appliquer toutes les recettes d'artisanat informes aux objets en dessous. Nécessite une _force_ _de_ _rotation_ constant et un _bassin_ placé en dessous (avec un espace entre les deux).", "block.create.mechanical_mixer.tooltip.condition1": "Lorsqu'au-dessus d'un bassin", - "block.create.mechanical_mixer.tooltip.behaviour1": "Commence à mélanger les objets dans le bassin lorsque tous les ingrédients nécessaires sont présents.", + "block.create.mechanical_mixer.tooltip.behaviour1": "Commence à mélanger les objets dans le bassin Quand tous les ingrédients nécessaires sont présents.", "block.create.mechanical_crafter.tooltip": "ÉTABLI MÉCANIQUE", "block.create.mechanical_crafter.tooltip.summary": "Un assembleur cinétique pour _automatiser_ n'importe quelle recette _en_ _forme_. Placez-en _plusieurs_ _dans_ _une_ _grille_ correspondant à votre recette, et _arrangez_ _leurs_ _tapis_ _roulant_ pour créer un _flux_ qui sort de la grille sur l'un des établis.", - "block.create.mechanical_crafter.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_crafter.tooltip.condition1": "Quand tourné", "block.create.mechanical_crafter.tooltip.behaviour1": "_Démarre_ _le_ _processus_ _d'artisanat_ dès que _tous_ les _établis_ dans la grille ont _reçu_ _un_ _objet_.", "block.create.mechanical_crafter.tooltip.condition2": "UNLOCALIZED: On Redstone Pulse", "block.create.mechanical_crafter.tooltip.behaviour2": "UNLOCALIZED: _Forces_ the start of the _crafting process_ with all currently given _items_ in the grid.", @@ -1537,7 +1537,7 @@ "block.create.portable_storage_interface.tooltip": "INTERFACE DE STOCKAGE PORTABLE", "block.create.portable_storage_interface.tooltip.summary": "Un point d'échange portable pour _déplacer_ des _objets_ vers et depuis une _structure_ déplacée par un piston, un roulement, un chariot ou une poulie.", "block.create.portable_storage_interface.tooltip.condition1": "Lorsqu'en mouvement", - "block.create.portable_storage_interface.tooltip.behaviour1": "Interagit avec les _transposeurs_ stationnaires de sorte que les transposeurs faisant _face_ _autrepart_ de l'interface tirent les objets, et les transposeurs ciblant l'interface y _insereront_ les _objets_ de l'inventaire joint. L'engin se bloquera brièvement lorsque les objets seront échangés.", + "block.create.portable_storage_interface.tooltip.behaviour1": "Interagit avec les _transposeurs_ stationnaires de sorte que les transposeurs faisant _face_ _autrepart_ de l'interface tirent les objets, et les transposeurs ciblant l'interface y _insereront_ les _objets_ de l'inventaire joint. L'engin se bloquera brièvement Quand les objets seront échangés.", "block.create.portable_storage_interface.tooltip.condition2": "UNLOCALIZED: When Powered by Redstone", "block.create.portable_storage_interface.tooltip.behaviour2": "UNLOCALIZED: _Disengages_ any active connection immediately.", @@ -1555,17 +1555,17 @@ "block.create.mechanical_piston.tooltip": "PISTON MÉCANIQUE", "block.create.mechanical_piston.tooltip.summary": "Une version plus avancée du _piston_. Il utilise une _force_ _de_ rotation_ pour déplacer précisément les structures attachées. Les _pôles_ _d'extension_ _de_ _piston_ à l'arrière définissent la _portée_ de cet appareil. Sans extensions, le piston ne bougera pas. Utilisez un _châssis_ ou un _bloc_ _de_ slime_ pour déplacer plus d'une seule ligne de blocs.", - "block.create.mechanical_piston.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_piston.tooltip.condition1": "Quand tourné", "block.create.mechanical_piston.tooltip.behaviour1": "Commence à déplacer la structure attachée. La vitesse et la direction sont corrélées à la vitesse de rotation entrante.", - "block.create.piston_extension_pole.tooltip": "PÔLE DE PISTON", + "block.create.piston_extension_pole.tooltip": "BARRE DE PISTON", "block.create.piston_extension_pole.tooltip.summary": "Étend la portée des _pistons_ _mécaniques.", "block.create.piston_extension_pole.tooltip.condition1": "Lorsqu'attaché à un piston mécanique", "block.create.piston_extension_pole.tooltip.behaviour1": "Étend la portée du _piston_ d'un bloc", "block.create.mechanical_bearing.tooltip": "ROULEMENT MÉCANIQUE", "block.create.mechanical_bearing.tooltip.summary": "Utilisé pour faire tourner de _plus_ _grande_ _structures_ ou pour exploiter une _force_ _de_ rotation_ contre le vent.", - "block.create.mechanical_bearing.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_bearing.tooltip.condition1": "Quand tourné", "block.create.mechanical_bearing.tooltip.behaviour1": "Démarre les blocs attachés en rotation. Utilisez un _châssis_ ou _bloc_ _de_ _slime_ pour déplacer plus d'un seul bloc.", "block.create.windmill_bearing.tooltip": "UNLOCALIZED: WINDMILL BEARING", @@ -1583,20 +1583,20 @@ "block.create.clockwork_bearing.tooltip": "ROULEMENT MÉCANIQUE HORLOGER", "block.create.clockwork_bearing.tooltip.summary": "Une version avancée du _roulement_ _mécanique_ pour faire tourner jusqu'à deux _aiguilles_ _d'horloge_ en fonction du _temps_ _en-jeu_ actuel.", - "block.create.clockwork_bearing.tooltip.condition1": "Lorsque tourné", + "block.create.clockwork_bearing.tooltip.condition1": "Quand tourné", "block.create.clockwork_bearing.tooltip.behaviour1": "Commence la rotation de la structure attachée vers l'_heure_ _actuelle_. Si une seconde structure est présente, elle servira _d'aiguille_ _des_ _minutes_.", - "block.create.sequenced_gearshift.tooltip": "DÉCALEUR DE ROTATION SÉQUENCÉ", + "block.create.sequenced_gearshift.tooltip": "BOÎITE À VITESSES SÉQUENCÉE", "block.create.sequenced_gearshift.tooltip.summary": "Un _composant_ _utilitaire_ _programmable_, qui peut changer son _débit_ _de_ _rotation_ suivant jusqu'à _5_ _instructions_ _consécutives_. Utilisez-le pour alimenter des roulements mécaniques, des pistons ou des poulies avec plus de contrôle sur le timing et la vitesse. Peut devenir moins précis à des vitesses plus élevées.", "block.create.sequenced_gearshift.tooltip.condition1": "Lorsqu'alimenté par de la redstone", "block.create.sequenced_gearshift.tooltip.behaviour1": "_Commence_ _à_ _exécuter_ les instructions programmées en fonction de la vitesse d'entrée.", "block.create.sequenced_gearshift.tooltip.condition2": "Clic droit", "block.create.sequenced_gearshift.tooltip.behaviour2": "Ouvre _l'interface_ _de_ _configuration_", - "block.create.cart_assembler.tooltip": "ASSEMBLEUR DE CHARIOT", - "block.create.cart_assembler.tooltip.summary": "Monte une structure connectée sur un _chariot_ _passant_.", + "block.create.cart_assembler.tooltip": "ASSEMBLEUR DE WAGON", + "block.create.cart_assembler.tooltip.summary": "Monte une structure connectée sur un _wagon_ _passant_.", "block.create.cart_assembler.tooltip.condition1": "Lorsqu'alimenté par de la redstone", - "block.create.cart_assembler.tooltip.behaviour1": "_Démonte_ les structures montées un _chariot_ _passant_ et les remet dans le monde.", + "block.create.cart_assembler.tooltip.behaviour1": "_Démonte_ les structures montées un _wagon passant_ et les remet dans le monde.", "block.create.cart_assembler.tooltip.condition2": "UNLOCALIZED: Carriage Contraptions", "block.create.cart_assembler.tooltip.behaviour2": "UNLOCALIZED: Two cart assembers _connected by_ a _structure_ will, once both contain a minecart, connect those carts with a _contraption mounted between_ the _two_ of them. The structure will behave similarly to a _Minecart Coupling_.", "block.create.cart_assembler.tooltip.control1": "UNLOCALIZED: When placed above Rail", @@ -1608,35 +1608,35 @@ "block.create.cart_assembler.tooltip.control4": "UNLOCALIZED: When placed above Activator Rail", "block.create.cart_assembler.tooltip.action4": "UNLOCALIZED: _Disassembles_ carts when powered.", - "block.create.rope_pulley.tooltip": "POULIE DE CORDE", + "block.create.rope_pulley.tooltip": "POULIE", "block.create.rope_pulley.tooltip.summary": "Déplace les _blocs_ et _structures_ attachés _verticalement_. Utilisez un _châssis_ ou _bloc_ _de_ _slime_ pour déplacer plus d'un seul bloc.", - "block.create.rope_pulley.tooltip.condition1": "Lorsque tourné", + "block.create.rope_pulley.tooltip.condition1": "Quand tourné", "block.create.rope_pulley.tooltip.behaviour1": "Commence à déplacer la structure attachée. La vitesse et la direction sont corrélées à la vitesse de rotation entrante.", - "block.create.linear_chassis.tooltip": "CHÂSSIS DE TRADUCTION", + "block.create.linear_chassis.tooltip": "CHÂSSIS LINÉAIRE", "block.create.linear_chassis.tooltip.summary": "Un bloc de base configurable reliant les structures pour le mouvement.", - "block.create.linear_chassis.tooltip.condition1": "Lorsque déplacé", + "block.create.linear_chassis.tooltip.condition1": "Quand déplacé", "block.create.linear_chassis.tooltip.behaviour1": "_Déplace_ tous les _châssis_ _attachés_ avec la même orientation, et une colonne de blocs dans sa portée. Les blocs ne seront tirés que si la face du châssis est _collante_ (Voir [Ctrl]).", "block.create.linear_chassis.tooltip.condition2": "Lorsqu'utilisé avec une clé", "block.create.linear_chassis.tooltip.behaviour2": "Configurez la _portée_ pour ce bloc de châssis. Maintenez CTRL pour modifier également la plage de tous les blocs de châssis connectés.", "block.create.linear_chassis.tooltip.control1": "Clic droit avec une boule de slime", - "block.create.linear_chassis.tooltip.action1": "Rends la face _collante_. Lorsque déplace, le châssis va _tirer_ les blocs attachés, quelle que soit la direction du mouvement.", + "block.create.linear_chassis.tooltip.action1": "Rend la face _collante_. Quand déplacé, le châssis va _tirer_ les blocs attachés, quelle que soit la direction du mouvement.", - "block.create.secondary_linear_chassis.tooltip": "UNLOCALIZED: SECONDARY LINEAR CHASSIS", - "block.create.secondary_linear_chassis.tooltip.summary": "UNLOCALIZED: A second type of _Linear Chassis_ that does not connect to the other.", + "block.create.secondary_linear_chassis.tooltip": "CHÂSSIS LINÉAIRE SECONDAIRE", + "block.create.secondary_linear_chassis.tooltip.summary": "Un deuxième type de _châssis linéaire_ qui ne se connecte pas au premier.", "block.create.radial_chassis.tooltip": "CHÂSSIS DE ROTATION", "block.create.radial_chassis.tooltip.summary": "Un bloc de base configurable reliant les structures pour le mouvement.", - "block.create.radial_chassis.tooltip.condition1": "Lorsque déplacé", + "block.create.radial_chassis.tooltip.condition1": "Quand déplacé", "block.create.radial_chassis.tooltip.behaviour1": "_Déplace_ tous les _châssis_ _attachés_ en colonne, et un cylindre de blocs autour de lui. Les blocs qui l'entourent ne sont déplacés que lorsqu'ils sont à portée et attachés à un côté collant (voir [Ctrl]).", "block.create.radial_chassis.tooltip.condition2": "Lorsqu'utilisé avec une clé", "block.create.radial_chassis.tooltip.behaviour2": "Configure la _portée_ pour ce bloc de châssis. Maintenez CTRL pour modifier également la portée de tous les blocs de châssis connectés.", "block.create.radial_chassis.tooltip.control1": "Clic droit avec une boule de slime", - "block.create.radial_chassis.tooltip.action1": "Rend la face _collante_. Lorsque le châssis se déplace, tous les blocs désignés attachés au côté collant sont déplacés avec lui.", + "block.create.radial_chassis.tooltip.action1": "Rend la face _collante_. Quand le châssis se déplace, tous les blocs désignés attachés au côté collant sont déplacés avec lui.", "block.create.mechanical_drill.tooltip": "PERCEUSE MÉCANIQUE", "block.create.mechanical_drill.tooltip.summary": "Un dispositif mécanique adapté pour _casser_ les _blocs_. Il est déplaceable avec _pistons_ _mécaniques_ ou _roulements_.", - "block.create.mechanical_drill.tooltip.condition1": "Lorsque tourné", + "block.create.mechanical_drill.tooltip.condition1": "Quand tourné", "block.create.mechanical_drill.tooltip.behaviour1": "Agit comme un casseur de bloc _stationnaire_. Inflige aussi des _dégats_ aux _entités_ se situant dans sa zone effective.", "block.create.mechanical_drill.tooltip.condition2": "Lorsqu'en mouvement", "block.create.mechanical_drill.tooltip.behaviour2": "Casse les blocs avec lesquels la perceuse entre en collision.", @@ -1646,36 +1646,36 @@ "block.create.mechanical_harvester.tooltip.condition1": "Lorsqu'en mouvement", "block.create.mechanical_harvester.tooltip.behaviour1": "_Récolte_ toutes les _cultures_ _matures_ que la lame entre en touche et les remet à leur état de croissance initial.", - "block.create.mechanical_plough.tooltip": "UNLOCALIZED: MECHANICAL PLOUGH", - "block.create.mechanical_plough.tooltip.summary": "UNLOCALIZED: A mechanical plough has a variety of uses. It is movable with _Mechanical Pistons_, _Bearings_ or other controllers.", - "block.create.mechanical_plough.tooltip.condition1": "UNLOCALIZED: While Moving", - "block.create.mechanical_plough.tooltip.behaviour1": "UNLOCALIZED: _Breaks blocks_ which _cannot be collided_ with, such as torches, tracks or snow layers. _Applies_ its _motion_ to _entities_ without hurting them. _Tills soil blocks_ as though a Hoe would be used on them.", + "block.create.mechanical_plough.tooltip": "CHARRUE MÉCANIQUE", + "block.create.mechanical_plough.tooltip.summary": "Une charrue mécanique a divers usages. Elle peut être déplacée à l'aide de _pistons mécaniques_, de _roulements_ ou d'autres dispositifs de commande.", + "block.create.mechanical_plough.tooltip.condition1": "Lorsqu’en mouvement", + "block.create.mechanical_plough.tooltip.behaviour1": "_Casse les blocs_ avec lesquels _on ne peut pas entrer en collision_, tels que les torches, les sentiers ou les couches de neige. _Applique_ son _mouvement_ aux _entités_ sans les blesser. _Bêche les blocs de terre_ comme si une houe était utilisée sur ceux-ci.", "block.create.mechanical_saw.tooltip": "SCIE MÉCANIQUE", - "block.create.mechanical_saw.tooltip.summary": "Convient pour _couper_ des _arbres_ efficacement et pour _tailler_ des _blocs_ dans leurs homologues menuisés. Il est déplaceable à l'aide de _pistons_ _mécaniques_ ou _roulements_.", - "block.create.mechanical_saw.tooltip.condition1": "Lorsque tourné vers le haut", - "block.create.mechanical_saw.tooltip.behaviour1": "Applique les _recettes_ de _sciage_ et de _taillerie_ aux éléments jetés ou insérés dedans. Lorsque plusieurs sorties sont possibles, il les parcourt à moins qu'un _filtre_ ne soit affecté.", + "block.create.mechanical_saw.tooltip.summary": "Convient pour _couper_ des _rotors_ efficacement et pour _tailler_ des _blocs_ dans leurs homologues menuisés. Il est déplaceable à l'aide de _pistons_ _mécaniques_ ou _roulements_.", + "block.create.mechanical_saw.tooltip.condition1": "Quand tourné vers le haut", + "block.create.mechanical_saw.tooltip.behaviour1": "Applique les _recettes_ de _sciage_ et de _taillerie_ aux éléments jetés ou insérés dedans. Quand plusieurs sorties sont possibles, il les parcourt à moins qu'un _filtre_ ne soit affecté.", "block.create.mechanical_saw.tooltip.condition2": "Lorsqu'à l'horizontal", - "block.create.mechanical_saw.tooltip.behaviour2": "_Casse_ les _troncs_ devant elle. Si le tronc a supportait un arbre, _l'arbre_ _tombera_ loin de la scie.", + "block.create.mechanical_saw.tooltip.behaviour2": "_Casse_ les _troncs_ devant elle. Si le tronc a supportait un rotor, _le rotor_ _tombera_ loin de la scie.", "block.create.mechanical_saw.tooltip.condition3": "Lorsqu'en mouvement", - "block.create.mechanical_saw.tooltip.behaviour3": "_Coupe_ tous les _arbres_ avec lesquels la scie entre en collision.", + "block.create.mechanical_saw.tooltip.behaviour3": "_Coupe_ tous les _rotors_ avec lesquels la scie entre en collision.", "block.create.stockpile_switch.tooltip": "DÉTÉCTEUR DE STOCKAGE", "block.create.stockpile_switch.tooltip.summary": "Bascule un signal Redstone basé sur _l'espace_ _de_ _stockage_ dans le conteneur attaché.", "block.create.stockpile_switch.tooltip.condition1": "Lorsqu'en dessous de la limite de stockage minimum", "block.create.stockpile_switch.tooltip.behaviour1": "Arrête de fournir de _l'énergie_", - "block.create.content_observer.tooltip": "UNLOCALIZED: CONTENT OBSERVER", - "block.create.content_observer.tooltip.summary": "UNLOCALIZED: _Detects Items_ inside _containers_ and _conveyors_ matching a configured _filter_. While the observed _inventory_, _belt_ or _chute contains_ a matching item, this component will emit a _Redstone Signal_. When an observed _funnel transfers_ a matching item, this component will emit a _Redstone Pulse_.", + "block.create.content_observer.tooltip": "OBSERVATEUR DE CONTENU", + "block.create.content_observer.tooltip.summary": "_Détecte les objets_ à l'intérieur des _conteneurs_ et des _transporteurs_ correspondant à un _filtre_ configuré. Tant que l'_inventaire_, le _tapis roulant_ ou la _glissière_ observé _contient_ un objet correspondant, ce composant émet un _signal de redstone_. Quand un _entonnoir_ observé _transfère_ un objet correspondant, ce composant émet une _impulsion de redstone_.", - "block.create.redstone_link.tooltip": "LIAISON REDSTONE", - "block.create.redstone_link.tooltip.summary": "Points de terminaison pour les connexions de _redstone_ _sans-fil_. Peut être attribué des _fréquences_ en utilisant n'importe quel objet. La portée du signal est limitée, quoique raisonnablement loin.", - "block.create.redstone_link.tooltip.condition1": "Lorsqu'alimenté", - "block.create.redstone_link.tooltip.behaviour1": "La réception de liens de la même _fréquence_ produira un signal redstone.", + "block.create.redstone_link.tooltip": "LIEN DE REDSTONE", + "block.create.redstone_link.tooltip.summary": "Terminaux pour les connexions de _redstone_ _sans-fil_. Peut être attribué des _fréquences_ en utilisant n'importe quel objet. La portée du signal est limitée, nonobstant raisonnablement loin.", + "block.create.redstone_link.tooltip.condition1": "Quand alimenté", + "block.create.redstone_link.tooltip.behaviour1": "Les liens de la même _fréquence_ configurés en réception produira un signal redstone.", "block.create.redstone_link.tooltip.control1": "Clic droit avec un objet", "block.create.redstone_link.tooltip.action1": "Définit la _fréquence_ sur cet élément. Un total de _deux_ _différents_ _objets_ peuvent être utilisés en combinaison pour définir une fréquence.", "block.create.redstone_link.tooltip.control2": "Clic droit en étant accroupi", - "block.create.redstone_link.tooltip.action2": "TBascule entre le mode _receveur_ et _transmetteur_.", + "block.create.redstone_link.tooltip.action2": "Bascule entre le mode _récepteur_ et _transmetteur_.", "block.create.nixie_tube.tooltip": "UNLOCALIZED: NIXIE TUBE", "block.create.nixie_tube.tooltip.summary": "UNLOCALIZED: A fancy redstone-powered _Number_ and _Text Display_.", @@ -1684,12 +1684,12 @@ "block.create.nixie_tube.tooltip.condition2": "UNLOCALIZED: With Name Tag", "block.create.nixie_tube.tooltip.behaviour2": "UNLOCALIZED: Display _contents_ of your _name tag_ with several nixie tubes _arranged_ in a _line_.", - "block.create.redstone_contact.tooltip": "redstone_contact REDSTONE", - "block.create.redstone_contact.tooltip.summary": "N'émet de l'énergie que par paires. Il est mobile avec _pistons_ _mécaniques_ ou _roulements_.", - "block.create.redstone_contact.tooltip.condition1": "Lorsque tourné vers un autre redstone_contact", - "block.create.redstone_contact.tooltip.behaviour1": "Fournit un _signal_ _redstone_.", - "block.create.redstone_contact.tooltip.condition2": "Lorsqu'en mouvement", - "block.create.redstone_contact.tooltip.behaviour2": "Déclenche tous les redstone_contacts fixes qu'il passe.", + "block.create.redstone_contact.tooltip": "CONTACT DE REDSTONE", + "block.create.redstone_contact.tooltip.summary": "N'émet de l'énergie que par paires. Il est mobile avec des _pistons_ _mécaniques_ ou _roulements_.", + "block.create.redstone_contact.tooltip.condition1": "Quand tourné vers un autre contact de redstone", + "block.create.redstone_contact.tooltip.behaviour1": "Fournit un _signal_ de _redstone_.", + "block.create.redstone_contact.tooltip.condition2": "Quand en mouvement", + "block.create.redstone_contact.tooltip.behaviour2": "Déclenche tous les contacts de redstone fixes qu'il passe.", "block.create.adjustable_crate.tooltip": "CAISSE AJUSTABLE", "block.create.adjustable_crate.tooltip.summary": "Ce _conteneur_ _de_ _stockage_ permet un contrôle manuel de sa capacité. Il peut contenir jusqu'à _16_ _piles_ de n'importe quel objet. Prend en charge les _comparateurs_ _de_ _redstone_.", @@ -1698,20 +1698,20 @@ "block.create.creative_crate.tooltip": "CAISSE CRÉATIVE", "block.create.creative_crate.tooltip.summary": "Fournit une réserve infinie de blocs aux _Schémacanons_ adjacents.", - "block.create.creative_crate.tooltip.condition1": "UNLOCALIZED: When Item in Filter Slot", - "block.create.creative_crate.tooltip.behaviour1": "UNLOCALIZED: Anything _extracting_ from this container will provide an _endless supply_ of the item specified. Items _inserted_ into this crate will be _voided._", + "block.create.creative_crate.tooltip.condition1": "Quand un objet se trouve dans l'emplacement de filtrage", + "block.create.creative_crate.tooltip.behaviour1": "Tout ce qui _extrait_ de ce conteneur aura une _alimentation illimitée_ de l'objet spécifié. Les objets _insérés_ dans cette caisse seront _éliminés_.", "block.create.deployer.tooltip": "DÉPLOYEUR", "block.create.deployer.tooltip.summary": "_Frappe_, _utilise_ et _active_. Cette machine essaiera _d'imiter_ un _joueur_ autant que possible. Peut _prendre_ et _déposer_ des _objets_ dans _l'inventaire_ adjacent. Peut être affecté à une pile d'éléments en tant que _filtre_.", - "block.create.deployer.tooltip.condition1": "Lorsque tourné", + "block.create.deployer.tooltip.condition1": "Quand tourné", "block.create.deployer.tooltip.behaviour1": "Étend son bras et _active_ dans l'espace de bloc _2m_ _devant_ de lui-même.", "block.create.deployer.tooltip.condition2": "Clic droit avec une clé", "block.create.deployer.tooltip.behaviour2": "Bascule le mode frappe. Dans le _mode_ _frappe_, le déployeur tentera d'utiliser son élément pour _casser_ les _blocs_ ou infliger des _dégats_ aux _entités_.", - "block.create.deployer.tooltip.condition3": "UNLOCALIZED: When Filter assigned", - "block.create.deployer.tooltip.behaviour3": "UNLOCALIZED: Deployer will not activate unless held item _matches_ the _filter._ Items not matching cannot be inserted; Held items matching the filter cannot be extracted.", + "block.create.deployer.tooltip.condition3": "Quand un filtre est attribué", + "block.create.deployer.tooltip.behaviour3": "Le déploiement n'est activé que si l'élément tenu _correspond_ au _filtre._ Les éléments ne correspondant pas ne peuvent pas être insérés ; les éléments tenus correspondant au filtre ne peuvent pas être extraits.", - "block.create.brass_casing.tooltip": "BOÎTIER EN LAITON", - "block.create.brass_casing.tooltip.summary": "Boîtier de machine robuste avec une variété d'utilisations. Sans danger pour la décoration.", + "block.create.brass_casing.tooltip": "REVÊTEMENT EN LAITON", + "block.create.brass_casing.tooltip.summary": "Revêtement de machine robuste avec une variété d'utilisations. Sans danger pour la décoration.", "block.create.pulse_repeater.tooltip": "RÉPÉTEUR D'IMPULSIONS", "block.create.pulse_repeater.tooltip.summary": "Un circuit simple pour couper les signaux de redstone passant à une longueur de _1_ _tick_.", @@ -1738,28 +1738,28 @@ "block.create.speedometer.tooltip": "COMPTEUR DE VITESSE", "block.create.speedometer.tooltip.summary": "Mesure et affiche la _ vitesse de rotation _ des composants cinétiques attachés. Prend en charge les _comparateurs_ _de_ _redstone_.", - "block.create.speedometer.tooltip.condition1": "Lorsque tourné", + "block.create.speedometer.tooltip.condition1": "Quand tourné", "block.create.speedometer.tooltip.behaviour1": "Indique une couleur correspondant au niveau de vitesse. _Vert_ indique une rotation lente, _Bleu_ modérée et _violet_ rapide. Certains composants mécaniques nécessitent une vitesse suffisante pour fonctionner correctement.", "block.create.stressometer.tooltip": "STRESSOMÈTRE", "block.create.stressometer.tooltip.summary": "Mesure et affiche la _stress__ globale du réseau cinétique attaché. Prend en charge les _comparateurs_ _de_ _redstone_.", - "block.create.stressometer.tooltip.condition1": "Lorsque tourné", + "block.create.stressometer.tooltip.condition1": "Quand tourné", "block.create.stressometer.tooltip.behaviour1": "Indique une couleur correspondant au niveau de contrainte. Les _réseaux_ _surchargés_ cesseront de bouger. Le stress peut être soulagé en ajoutant plus de _sources_ _rotationnelles_ au réseau.", - "item.create.sand_paper.tooltip": "UNLOCALIZED: SAND PAPER", - "item.create.sand_paper.tooltip.summary": "UNLOCALIZED: A rough paper that can be used to _polish materials_. Can be automatically applied using the Deployer.", - "item.create.sand_paper.tooltip.condition1": "UNLOCALIZED: When Used", - "item.create.sand_paper.tooltip.behaviour1": "UNLOCALIZED: Applies polish to items held in the _offhand_ or lying on the _floor_ when _looking at them_", + "item.create.sand_paper.tooltip": "PAPIER DE VERRE", + "item.create.sand_paper.tooltip.summary": "Un papier rugueux qui peut être utilisé pour _polir des matériaux_. Peut être appliqué automatiquement à l'aide du déployeur.", + "item.create.sand_paper.tooltip.condition1": "Quand utilisé", + "item.create.sand_paper.tooltip.behaviour1": "Polit les objets qui se tenus dans la _main secondaire_ ou par terre quand on les _regarde_.", - "item.create.super_glue.tooltip": "UNLOCALIZED: SUPER GLUE", - "item.create.super_glue.tooltip.summary": "UNLOCALIZED: Glue a block to another, and they will forever be inseparable.", - "item.create.super_glue.tooltip.condition1": "UNLOCALIZED: When Used", - "item.create.super_glue.tooltip.behaviour1": "UNLOCALIZED: Makes the _clicked face_ of a block _sticky_. Blocks attached to sticky faces will be _dragged along_ when moved by _mechanical pistons_, _bearings_ and other controllers.", - "item.create.super_glue.tooltip.condition2": "UNLOCALIZED: When Held in Offhand", - "item.create.super_glue.tooltip.behaviour2": "UNLOCALIZED: _Automatically attaches_ blocks placed from the main hand to the _side_ they were _placed against._", + "item.create.super_glue.tooltip": "COLLE EXTRA-FORTE", + "item.create.super_glue.tooltip.summary": "Collez un bloc à un autre, et ils seront à jamais inséparables.", + "item.create.super_glue.tooltip.condition1": "Quand utilisé", + "item.create.super_glue.tooltip.behaviour1": "Rend la face _cliquée_ d'un bloc _collante_. Les blocs attachés aux faces collantes seront entraînés par des _pistons mécaniques_, _des roulements_ et d'autres contrôleurs.", + "item.create.super_glue.tooltip.condition2": "Quand tenu en main secondaire", + "item.create.super_glue.tooltip.behaviour2": "Attache automatiquement les blocs placés de la main principale à la _face_ contre laquelle ils ont été _placés_.", - "item.create.builders_tea.tooltip": "UNLOCALIZED: BUILDERS TEA", - "item.create.builders_tea.tooltip.summary": "UNLOCALIZED: The perfect drink to get the day started- _Motivating_ and _Saturating._", + "item.create.builders_tea.tooltip": "THÉ DU CONSTRUCTEUR", + "item.create.builders_tea.tooltip.summary": "La boisson parfaite pour commencer la journée - _motivante_ et _rasasiante_.", "item.create.refined_radiance.tooltip": "ÉCLAT RAFFINÉ", "item.create.refined_radiance.tooltip.summary": "Un matériau chromatique forgé à partir de _lumière_ _absorbée_.", @@ -1767,7 +1767,7 @@ "item.create.shadow_steel.tooltip": "ACIER SOMBRE", "item.create.shadow_steel.tooltip.summary": "Un matériau chromatique forgé _dans_ _le_ _néant_.", - "item.create.minecart_coupling.tooltip": "UNLOCALIZED: MINECART COUPLING", + "item.create.minecart_coupling.tooltip": "LIEN POUR WAGONS", "item.create.minecart_coupling.tooltip.summary": "UNLOCALIZED: _Chains_ all your _Minecarts_ or _Carriage Contraptions_ together to form a majestic Train.", "item.create.minecart_coupling.tooltip.condition1": "UNLOCALIZED: When Used on Minecart", "item.create.minecart_coupling.tooltip.behaviour1": "UNLOCALIZED: _Couples_ two Minecarts together, attempting to keep them at a _constant distance_ while moving.", @@ -1780,7 +1780,7 @@ "create.tooltip.randomWipDescription0": "Veuillez garder cet objet hors de portée des enfants.", "create.tooltip.randomWipDescription1": "Un bébé panda meurt chaque fois que vous utilisez cet objet. Chaque. Fois.", "create.tooltip.randomWipDescription2": "À utiliser à vos risques et périls.", - "create.tooltip.randomWipDescription3": "Ce n'est pas l'objet que vous recherchez, *agites les doigts* veuillez vous disperser.", + "create.tooltip.randomWipDescription3": "Ce n'est pas l'objet que vous recherchez, *agite les doigts* circulez.", "create.tooltip.randomWipDescription4": "Cet objet s'autodétruit en 10 secondes. 10, 9, 8...", "create.tooltip.randomWipDescription5": "Croyez-moi, c'est inutile.", "create.tooltip.randomWipDescription6": "En utilisant cet article, vous êtes responsables et acceptez ses conditions.", From 2315625c4b244ab1c7a4fad6b202693af500496b Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 6 Feb 2021 18:11:35 +0100 Subject: [PATCH 26/31] Quickfix - Fixed gantry shafts able to cause loops in kinetic connectivity when switching to powered state --- .../contraptions/relays/advanced/GantryShaftBlock.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java index 15cd24040..6fa9bd927 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java @@ -187,13 +187,9 @@ public class GantryShaftBlock extends DirectionalKineticBlock { toUpdate.add(pos); for (BlockPos blockPos : toUpdate) { BlockState blockState = worldIn.getBlockState(blockPos); - - if (!shouldPower) { - TileEntity te = worldIn.getTileEntity(blockPos); - if (te instanceof KineticTileEntity) - ((KineticTileEntity) te).detachKinetics(); - } - + TileEntity te = worldIn.getTileEntity(blockPos); + if (te instanceof KineticTileEntity) + ((KineticTileEntity) te).detachKinetics(); if (blockState.getBlock() instanceof GantryShaftBlock) worldIn.setBlockState(blockPos, blockState.with(POWERED, shouldPower), 2); } From 6981848f8a3c0572879906b4e165ea88cbdecab6 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 6 Feb 2021 22:41:20 +0100 Subject: [PATCH 27/31] Clean-up - Fixed smart chutes not filtering properly - Fixed chutes not treating smart chutes like chutes - Removed code leftovers - Removed datagen cache from gitignore --- .gitignore | 1 - .../block/chute/ChuteTileEntity.java | 41 +++---------------- .../block/chute/SmartChuteTileEntity.java | 2 +- .../filtering/SchematicInstances.java | 5 --- 4 files changed, 6 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index f5e691153..0123b6707 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,3 @@ local.properties # PDT-specific .buildpath -src/generated/resources/.cache/cache diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java index 943f8345e..fac939e92 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java @@ -379,29 +379,6 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor .isHorizontal()) return false; -// BlockState stateBelow = world.getBlockState(pos.down()); -// if (stateBelow.getBlock() instanceof FunnelBlock) { -// if (stateBelow.has(BrassFunnelBlock.POWERED) && stateBelow.get(BrassFunnelBlock.POWERED)) -// return false; -// if (stateBelow.get(BrassFunnelBlock.FACING) != Direction.UP) -// return false; -// ItemStack remainder = FunnelBlock.tryInsert(world, pos.down(), item, simulate); -// if (!simulate) -// setItem(remainder); -// return remainder.isEmpty(); -// } -// -// DirectBeltInputBehaviour directInput = -// TileEntityBehaviour.get(world, pos.down(), DirectBeltInputBehaviour.TYPE); -// if (directInput != null) { -// if (!directInput.canInsertFromSide(Direction.UP)) -// return false; -// ItemStack remainder = directInput.handleInsertion(item, Direction.UP, simulate); -// if (!simulate) -// setItem(remainder); -// return remainder.isEmpty(); -// } - if (Block.hasSolidSideOnTop(world, pos.down())) return false; @@ -420,17 +397,6 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor private boolean handleUpwardOutput(boolean simulate) { BlockState stateAbove = world.getBlockState(pos.up()); -// if (stateAbove.getBlock() instanceof FunnelBlock) { -// boolean powered = stateAbove.has(BrassFunnelBlock.POWERED) && stateAbove.get(BrassFunnelBlock.POWERED); -// if (!powered && stateAbove.get(BrassFunnelBlock.FACING) == Direction.DOWN) { -// ItemStack remainder = FunnelBlock.tryInsert(world, pos.up(), item, simulate); -// if (remainder.isEmpty()) { -// if (!simulate) -// setItem(remainder); -// return true; -// } -// } -// } if (world == null) return false; @@ -501,9 +467,12 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor if (world == null) return LazyOptional.empty(); TileEntity te = world.getTileEntity(pos); - if (te == null - || (te instanceof ChuteTileEntity) && (side != Direction.DOWN || !(te instanceof SmartChuteTileEntity))) + if (te == null) return LazyOptional.empty(); + if (te instanceof ChuteTileEntity) { + if (side != Direction.DOWN || !(te instanceof SmartChuteTileEntity) || getItemMotion() > 0) + return LazyOptional.empty(); + } return te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side.getOpposite()); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteTileEntity.java index d2ba5c271..07cbb4fcb 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteTileEntity.java @@ -21,7 +21,7 @@ public class SmartChuteTileEntity extends ChuteTileEntity { @Override protected boolean canAcceptItem(ItemStack stack) { - return super.canAcceptItem(stack) && canCollectItemsFromBelow(); + return super.canAcceptItem(stack) && canCollectItemsFromBelow() && filtering.test(stack); } @Override diff --git a/src/main/java/com/simibubi/create/content/schematics/filtering/SchematicInstances.java b/src/main/java/com/simibubi/create/content/schematics/filtering/SchematicInstances.java index f8b612b61..1a34d744f 100644 --- a/src/main/java/com/simibubi/create/content/schematics/filtering/SchematicInstances.java +++ b/src/main/java/com/simibubi/create/content/schematics/filtering/SchematicInstances.java @@ -9,7 +9,6 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.simibubi.create.content.schematics.SchematicWorld; import com.simibubi.create.content.schematics.item.SchematicItem; -import com.simibubi.create.foundation.utility.Debug; import com.simibubi.create.foundation.utility.WorldAttached; import net.minecraft.item.ItemStack; @@ -63,10 +62,6 @@ public class SchematicInstances { PlacementSettings settings = SchematicItem.getSettings(schematic); activeTemplate.addBlocksToWorld(world, anchor, settings); - Debug.debugChat("Loading Schematic Instance of " + schematic.getTag() - .getString("File") + ". Total active instances: " + (loadedSchematics.get(wrapped).size() + 1)); - - return world; } From cb2c56d772e23fd1405d2d89b11e7a041b2cbc6a Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 7 Feb 2021 18:09:08 +0100 Subject: [PATCH 28/31] Gantry shaft placement assist --- .../structureMovement/bearing/SailBlock.java | 11 ---- .../relays/advanced/GantryShaftBlock.java | 54 +++++++++++++++++++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java index fbc1517c7..8e12c734a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java @@ -72,17 +72,6 @@ public class SailBlock extends ProperDirectionalBlock { return ActionResultType.PASS; offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock().getDefaultState(), player, heldItem); - - /*BlockState blockState = ((BlockItem) heldItem.getItem()).getBlock() - .getDefaultState() - .with(FACING, state.get(FACING)); - BlockPos offsetPos = new BlockPos(offset.getPos()); - if (!world.isRemote && world.getBlockState(offsetPos).getMaterial().isReplaceable()) { - world.setBlockState(offsetPos, blockState); - if (!player.isCreative()) - heldItem.shrink(1); - }*/ - return ActionResultType.SUCCESS; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java index 6fa9bd927..cca015c0a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.relays.advanced; import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; @@ -10,11 +11,18 @@ import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.placement.IPlacementHelper; +import com.simibubi.create.foundation.utility.placement.PlacementHelpers; +import com.simibubi.create.foundation.utility.placement.PlacementOffset; +import com.simibubi.create.foundation.utility.placement.util.PoleHelper; import net.minecraft.block.Block; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.state.BooleanProperty; import net.minecraft.state.EnumProperty; @@ -25,8 +33,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Hand; import net.minecraft.util.IStringSerializable; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; @@ -39,6 +49,8 @@ public class GantryShaftBlock extends DirectionalKineticBlock { public static final IProperty PART = EnumProperty.create("part", Part.class); public static final BooleanProperty POWERED = BlockStateProperties.POWERED; + private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); + public enum Part implements IStringSerializable { START, MIDDLE, END, SINGLE; @@ -53,6 +65,25 @@ public class GantryShaftBlock extends DirectionalKineticBlock { super.fillStateContainer(builder.add(PART, POWERED)); } + @Override + public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, + BlockRayTraceResult ray) { + ItemStack heldItem = player.getHeldItem(hand); + + IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); + if (!placementHelper.matchesItem(heldItem)) + return ActionResultType.PASS; + + PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray); + + if (!offset.isReplaceable(world)) + return ActionResultType.PASS; + + offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock() + .getDefaultState(), player, heldItem); + return ActionResultType.SUCCESS; + } + @Override public VoxelShape getShape(BlockState state, IBlockReader p_220053_2_, BlockPos p_220053_3_, ISelectionContext p_220053_4_) { @@ -237,4 +268,27 @@ public class GantryShaftBlock extends DirectionalKineticBlock { && oldState.get(POWERED) == newState.get(POWERED); } + public static class PlacementHelper extends PoleHelper { + + public PlacementHelper() { + super(AllBlocks.GANTRY_SHAFT::has, s -> s.get(FACING) + .getAxis(), FACING); + } + + @Override + public Predicate getItemPredicate() { + return AllBlocks.GANTRY_SHAFT::isIn; + } + + @Override + public PlacementOffset getOffset(World world, BlockState state, BlockPos pos, BlockRayTraceResult ray) { + PlacementOffset offset = super.getOffset(world, state, pos, ray); + if (!offset.isSuccessful()) + return offset; + return PlacementOffset.success(offset.getPos(), offset.getTransform() + .andThen(s -> s.with(POWERED, state.get(POWERED)))); + } + + } + } From f3fd32edd30b9a816d5d4998e87f307373747728 Mon Sep 17 00:00:00 2001 From: Zelophed Date: Thu, 11 Feb 2021 00:28:47 +0100 Subject: [PATCH 29/31] Assisted Placement, Part III - blocks placed by helpers make sounds again - helpers now trigger the proper event and can be cancelled --- .../structureMovement/bearing/SailBlock.java | 13 +---- .../glue/SuperGlueHandler.java | 18 +++--- .../piston/PistonExtensionPoleBlock.java | 25 ++------- .../relays/advanced/GantryShaftBlock.java | 21 ++----- .../relays/advanced/SpeedControllerBlock.java | 21 ++----- .../relays/elementary/CogwheelBlockItem.java | 50 +++++------------ .../relays/elementary/ShaftBlock.java | 23 +------- .../utility/placement/IPlacementHelper.java | 24 ++------ .../utility/placement/PlacementOffset.java | 55 +++++++++++++++---- 9 files changed, 94 insertions(+), 156 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java index 8e12c734a..9c2255629 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/SailBlock.java @@ -64,16 +64,9 @@ public class SailBlock extends ProperDirectionalBlock { public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) { ItemStack heldItem = player.getHeldItem(hand); - if (AllBlocks.SAIL.isIn(heldItem) || AllBlocks.SAIL_FRAME.isIn(heldItem)) { - IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); - PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray); - - if (!offset.isReplaceable(world)) - return ActionResultType.PASS; - - offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock().getDefaultState(), player, heldItem); - return ActionResultType.SUCCESS; - } + IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); + if (placementHelper.matchesItem(heldItem)) + return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); if (heldItem.getItem() instanceof ShearsItem) { if (!world.isRemote) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueHandler.java index 34190f8b8..c9862ba88 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueHandler.java @@ -1,13 +1,9 @@ package com.simibubi.create.content.contraptions.components.structureMovement.glue; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.simibubi.create.AllItems; import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.worldWrappers.RayTraceWorld; - import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -15,12 +11,8 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.RayTraceContext; +import net.minecraft.util.math.*; import net.minecraft.util.math.RayTraceResult.Type; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent; @@ -28,6 +20,10 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.network.PacketDistributor; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + @EventBusSubscriber public class SuperGlueHandler { @@ -65,6 +61,8 @@ public class SuperGlueHandler { return; if (AllItems.WRENCH.isIn(placer.getHeldItemMainhand())) return; + if (event.getPlacedAgainst() == IPlacementHelper.ID) + return; double distance = placer.getAttribute(PlayerEntity.REACH_DISTANCE) .getValue(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java index 27460381f..b0cb526f2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java @@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; -import com.simibubi.create.foundation.utility.placement.PlacementOffset; import com.simibubi.create.foundation.utility.placement.util.PoleHelper; import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.Block; @@ -17,6 +16,7 @@ import net.minecraft.block.material.PushReaction; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.Fluids; import net.minecraft.fluid.IFluidState; +import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.state.StateContainer.Builder; @@ -114,26 +114,9 @@ public class PistonExtensionPoleBlock extends ProperDirectionalBlock implements public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) { ItemStack heldItem = player.getHeldItem(hand); - if (AllBlocks.PISTON_EXTENSION_POLE.isIn(heldItem) && !player.isSneaking()) { - IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); - PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray); - - if (!offset.isReplaceable(world)) - return ActionResultType.PASS; - - offset.placeInWorld(world, AllBlocks.PISTON_EXTENSION_POLE.getDefaultState(), player, heldItem); - - /*BlockPos newPos = new BlockPos(offset.getPos()); - - if (world.isRemote) - return ActionResultType.SUCCESS; - - world.setBlockState(newPos, offset.getTransform().apply(AllBlocks.PISTON_EXTENSION_POLE.getDefaultState())); - if (!player.isCreative()) - heldItem.shrink(1);*/ - - return ActionResultType.SUCCESS; - } + IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); + if (placementHelper.matchesItem(heldItem) && !player.isSneaking()) + return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); return ActionResultType.PASS; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java index cca015c0a..05078e359 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java @@ -1,9 +1,5 @@ package com.simibubi.create.content.contraptions.relays.advanced; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Predicate; - import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; @@ -15,7 +11,6 @@ import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; import com.simibubi.create.foundation.utility.placement.PlacementOffset; import com.simibubi.create.foundation.utility.placement.util.PoleHelper; - import net.minecraft.block.Block; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; @@ -44,6 +39,10 @@ import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + public class GantryShaftBlock extends DirectionalKineticBlock { public static final IProperty PART = EnumProperty.create("part", Part.class); @@ -66,22 +65,14 @@ public class GantryShaftBlock extends DirectionalKineticBlock { } @Override - public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, - BlockRayTraceResult ray) { + public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) { ItemStack heldItem = player.getHeldItem(hand); IPlacementHelper placementHelper = PlacementHelpers.get(placementHelperId); if (!placementHelper.matchesItem(heldItem)) return ActionResultType.PASS; - PlacementOffset offset = placementHelper.getOffset(world, state, pos, ray); - - if (!offset.isReplaceable(world)) - return ActionResultType.PASS; - - offset.placeInWorld(world, ((BlockItem) heldItem.getItem()).getBlock() - .getDefaultState(), player, heldItem); - return ActionResultType.SUCCESS; + return placementHelper.getOffset(world, state, pos, ray).placeInWorld(world, ((BlockItem) heldItem.getItem()), player, hand, ray); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java index 5d9071e98..8d15808c4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlock.java @@ -1,7 +1,5 @@ package com.simibubi.create.content.contraptions.relays.advanced; -import java.util.function.Predicate; - import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; @@ -13,11 +11,11 @@ import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; import com.simibubi.create.foundation.utility.placement.PlacementOffset; - import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -32,6 +30,8 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; +import java.util.function.Predicate; + public class SpeedControllerBlock extends HorizontalAxisKineticBlock implements ITE { private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); @@ -67,19 +67,10 @@ public class SpeedControllerBlock extends HorizontalAxisKineticBlock implements public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) { - IPlacementHelper helper = PlacementHelpers.get(placementHelperId); ItemStack heldItem = player.getHeldItem(hand); - if (helper.matchesItem(heldItem)) { - PlacementOffset offset = helper.getOffset(world, state, pos, ray); - - if (!offset.isReplaceable(world)) - return ActionResultType.PASS; - - offset.placeInWorld(world, AllBlocks.LARGE_COGWHEEL.getDefaultState(), player, heldItem); - - return ActionResultType.SUCCESS; - - } + IPlacementHelper helper = PlacementHelpers.get(placementHelperId); + if (helper.matchesItem(heldItem)) + return helper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); return ActionResultType.PASS; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogwheelBlockItem.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogwheelBlockItem.java index 15ea07c4c..31a886453 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogwheelBlockItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogwheelBlockItem.java @@ -1,10 +1,5 @@ package com.simibubi.create.content.contraptions.relays.elementary; -import static com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock.AXIS; - -import java.util.List; -import java.util.function.Predicate; - import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; @@ -16,13 +11,13 @@ import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; import com.simibubi.create.foundation.utility.placement.PlacementOffset; - import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; @@ -31,6 +26,11 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.world.World; +import java.util.List; +import java.util.function.Predicate; + +import static com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock.AXIS; + public class CogwheelBlockItem extends BlockItem { boolean large; @@ -47,49 +47,27 @@ public class CogwheelBlockItem extends BlockItem { } @Override - public ActionResultType tryPlace(BlockItemUseContext context) { + public ActionResultType onItemUseFirst(ItemStack stack, ItemUseContext context) { World world = context.getWorld(); - BlockPos pos = context.getPos() - .offset(context.getFace() - .getOpposite()); + BlockPos pos = context.getPos(); BlockState state = world.getBlockState(pos); IPlacementHelper helper = PlacementHelpers.get(placementHelperId); PlayerEntity player = context.getPlayer(); - - if (helper.matchesState(state)) { - PlacementOffset offset = helper.getOffset(world, state, pos, - new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true)); - - if (!offset.isReplaceable(world)) - return super.tryPlace(context); - - offset.placeInWorld(world, this, player, context.getItem()); - triggerShiftingGearsAdvancement(world, new BlockPos(offset.getPos()), offset.getTransform() - .apply(getBlock().getDefaultState()), player); - - return ActionResultType.SUCCESS; + BlockRayTraceResult ray = new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true); + if (helper.matchesState(state) && player != null && !player.isSneaking()) { + return helper.getOffset(world, state, pos, ray).placeInWorld(world, this, player, context.getHand(), ray); } if (integratedCogHelperId != -1) { helper = PlacementHelpers.get(integratedCogHelperId); - if (helper.matchesState(state)) { - PlacementOffset offset = helper.getOffset(world, state, pos, - new BlockRayTraceResult(context.getHitVec(), context.getFace(), pos, true)); - - if (!offset.isReplaceable(world)) - return super.tryPlace(context); - - offset.placeInWorld(world, this, player, context.getItem()); - triggerShiftingGearsAdvancement(world, new BlockPos(offset.getPos()), offset.getTransform() - .apply(getBlock().getDefaultState()), player); - - return ActionResultType.SUCCESS; + if (helper.matchesState(state) && player != null && !player.isSneaking()) { + return helper.getOffset(world, state, pos, ray).placeInWorld(world, this, player, context.getHand(), ray); } } - return super.tryPlace(context); + return super.onItemUseFirst(stack, context); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java index f1094dcc0..d68c293f0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java @@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.utility.placement.IPlacementHelper; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; -import com.simibubi.create.foundation.utility.placement.PlacementOffset; import com.simibubi.create.foundation.utility.placement.util.PoleHelper; import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.BlockState; @@ -77,26 +76,8 @@ public class ShaftBlock extends AbstractShaftBlock { } IPlacementHelper helper = PlacementHelpers.get(placementHelperId); - if (helper.getItemPredicate().test(heldItem)) { - PlacementOffset offset = helper.getOffset(world, state, pos, ray); - - if (!offset.isReplaceable(world)) - return ActionResultType.PASS; - - offset.placeInWorld(world, (BlockItem) heldItem.getItem(), player, heldItem); - - /*BlockPos newPos = new BlockPos(offset.getPos()); - - if (world.isRemote) - return ActionResultType.SUCCESS; - - Block block = ((BlockItem) heldItem.getItem()).getBlock(); - world.setBlockState(newPos, offset.getTransform().apply(block.getDefaultState())); - if (!player.isCreative()) - heldItem.shrink(1);*/ - - return ActionResultType.SUCCESS; - } + if (helper.matchesItem(heldItem)) + return helper.getOffset(world, state, pos, ray).placeInWorld(world, (BlockItem) heldItem.getItem(), player, hand, ray); return ActionResultType.PASS; } diff --git a/src/main/java/com/simibubi/create/foundation/utility/placement/IPlacementHelper.java b/src/main/java/com/simibubi/create/foundation/utility/placement/IPlacementHelper.java index 2cb70be61..082776a7c 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/placement/IPlacementHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/placement/IPlacementHelper.java @@ -6,6 +6,7 @@ import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.VecHelper; import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -22,6 +23,11 @@ import java.util.stream.Collectors; @MethodsReturnNonnullByDefault public interface IPlacementHelper { + /** + * used as an identifier in SuperGlueHandler to skip blocks placed by helpers + */ + BlockState ID = new BlockState(Blocks.AIR, null); + /** * @return a predicate that gets tested with the items held in the players hands, * should return true if this placement helper is active with the given item @@ -61,24 +67,6 @@ public interface IPlacementHelper { CreateClient.outliner.showLine("placementArrowB" + center + target, start.add(offset), endB.add(offset)).lineWidth(1/16f); } - /*@OnlyIn(Dist.CLIENT) - static void renderArrow(Vec3d center, Direction towards, BlockRayTraceResult ray) { - Direction hitFace = ray.getFace(); - - if (hitFace.getAxis() == towards.getAxis()) - return; - - //get the two perpendicular directions to form the arrow - Direction[] directions = Arrays.stream(Direction.Axis.values()).filter(axis -> axis != hitFace.getAxis() && axis != towards.getAxis()).map(Iterate::directionsInAxis).findFirst().orElse(new Direction[]{}); - Vec3d startOffset = new Vec3d(towards.getDirectionVec()); - Vec3d start = center.add(startOffset); - for (Direction dir : directions) { - Vec3d arrowOffset = new Vec3d(dir.getDirectionVec()).scale(.25); - Vec3d target = center.add(startOffset.scale(0.75)).add(arrowOffset); - CreateClient.outliner.showLine("placementArrow" + towards + dir, start, target).lineWidth(1/16f); - } - }*/ - static List orderedByDistanceOnlyAxis(BlockPos pos, Vec3d hit, Direction.Axis axis) { return orderedByDistance(pos, hit, dir -> dir.getAxis() == axis); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/placement/PlacementOffset.java b/src/main/java/com/simibubi/create/foundation/utility/placement/PlacementOffset.java index 8da2b5ce2..e9d50d6d5 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/placement/PlacementOffset.java +++ b/src/main/java/com/simibubi/create/foundation/utility/placement/PlacementOffset.java @@ -1,15 +1,26 @@ package com.simibubi.create.foundation.utility.placement; +import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.BlockState; +import net.minecraft.block.SoundType; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.fluid.Fluids; import net.minecraft.fluid.IFluidState; import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.stats.Stats; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.Vec3i; import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.world.BlockEvent; import java.util.function.Function; @@ -55,25 +66,49 @@ public class PlacementOffset { return world.getBlockState(new BlockPos(pos)).getMaterial().isReplaceable(); } - - public void placeInWorld(World world, BlockItem blockItem, PlayerEntity player, ItemStack item) { - placeInWorld(world, blockItem.getBlock().getDefaultState(), player, item); - } - public void placeInWorld(World world, BlockState defaultState, PlayerEntity player, ItemStack item) { - if (world.isRemote) - return; + public ActionResultType placeInWorld(World world, BlockItem blockItem, PlayerEntity player, Hand hand, BlockRayTraceResult ray) { + + ItemUseContext context = new ItemUseContext(player, hand, ray); BlockPos newPos = new BlockPos(pos); - BlockState state = stateTransform.apply(defaultState); + + if (!world.isBlockModifiable(player, newPos)) + return ActionResultType.PASS; + + if (!isReplaceable(world)) + return ActionResultType.PASS; + + BlockState state = stateTransform.apply(blockItem.getBlock().getDefaultState()); if (state.has(BlockStateProperties.WATERLOGGED)) { IFluidState fluidState = world.getFluidState(newPos); state = state.with(BlockStateProperties.WATERLOGGED, fluidState.getFluid() == Fluids.WATER); } + BlockSnapshot snapshot = BlockSnapshot.getBlockSnapshot(world, newPos); world.setBlockState(newPos, state); + BlockEvent.EntityPlaceEvent event = new BlockEvent.EntityPlaceEvent(snapshot, IPlacementHelper.ID, player); + if (MinecraftForge.EVENT_BUS.post(event)) { + snapshot.restore(true, false); + return ActionResultType.FAIL; + } + + BlockState newState = world.getBlockState(newPos); + SoundType soundtype = newState.getSoundType(world, newPos, player); + world.playSound(player, newPos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F); + + player.addStat(Stats.ITEM_USED.get(blockItem)); + + if (world.isRemote) + return ActionResultType.SUCCESS; + + if (player instanceof ServerPlayerEntity) + CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, newPos, context.getItem()); + if (!player.isCreative()) - item.shrink(1); + context.getItem().shrink(1); + + return ActionResultType.SUCCESS; } } From b4c881a6c8eff198f558bec55aa98570e97161eb Mon Sep 17 00:00:00 2001 From: Zelophed Date: Thu, 11 Feb 2021 17:47:55 +0100 Subject: [PATCH 30/31] Player Feedback, Part II --- src/generated/resources/.cache/cache | 24 ++++---- .../resources/assets/create/lang/en_us.json | 6 ++ .../assets/create/lang/unfinished/de_de.json | 8 ++- .../assets/create/lang/unfinished/fr_fr.json | 8 ++- .../assets/create/lang/unfinished/it_it.json | 8 ++- .../assets/create/lang/unfinished/ja_jp.json | 8 ++- .../assets/create/lang/unfinished/ko_kr.json | 8 ++- .../assets/create/lang/unfinished/nl_nl.json | 8 ++- .../assets/create/lang/unfinished/pt_br.json | 8 ++- .../assets/create/lang/unfinished/ru_ru.json | 8 ++- .../assets/create/lang/unfinished/zh_cn.json | 8 ++- .../structureMovement/AssemblyException.java | 41 +++++++++++-- .../structureMovement/Contraption.java | 61 ++++++------------- .../IDisplayAssemblyExceptions.java | 28 +++++++++ .../bearing/ClockworkBearingTileEntity.java | 33 +++++----- .../bearing/ClockworkContraption.java | 16 +++-- .../bearing/MechanicalBearingTileEntity.java | 37 ++++++----- .../mounted/CartAssemblerBlock.java | 11 +++- .../mounted/CartAssemblerTileEntity.java | 41 +++++++++---- .../piston/LinearActuatorTileEntity.java | 35 +++++------ .../piston/PistonContraption.java | 12 ++-- .../pulley/PulleyTileEntity.java | 5 +- .../goggles/GoggleOverlayRenderer.java | 9 +++ .../goggles/IHaveGoggleInformation.java | 6 +- .../assets/create/lang/default/messages.json | 7 +++ 25 files changed, 282 insertions(+), 162 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/IDisplayAssemblyExceptions.java diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 0dfe925ea..2d9d6f52b 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -140,7 +140,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 assets/create/blockstates/fancy_scoria_ fc9ac0a7e7191b93516719455a17177fa6524ecc assets/create/blockstates/fancy_weathered_limestone_bricks_slab.json b2a7c321b1795f20e7433f81a55ce4683de081b8 assets/create/blockstates/fancy_weathered_limestone_bricks_stairs.json 6372fe02ba0065acb0758121c45a15a1a8fdc5de assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json -4c3e0500f9382d2e426e823fe876f57f4d7ee3b4 assets/create/blockstates/fluid_pipe.json +6106fc0a0f9d83da89c3e8af98e7c45232602c23 assets/create/blockstates/fluid_pipe.json f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json 5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets/create/blockstates/flywheel.json @@ -335,7 +335,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json -bdd56f32ce0a148b6e466a55ab2777f69fc08cfc assets/create/blockstates/radial_chassis.json +143d66a7262ccd29f36784d6b064d4a13ba374b6 assets/create/blockstates/radial_chassis.json 45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json 722fc77bbf387af8a4016e42cbf9501d2b968881 assets/create/blockstates/red_valve_handle.json @@ -399,16 +399,16 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json df67c2c11fa22487d3a0fdc9b008056e593d14e3 assets/create/lang/en_ud.json -3ad443f44eb33fe8c3ac092d1532dcbd27e49c84 assets/create/lang/en_us.json -612a63d73f7f4b8e79dce3f53ddbe3345f0e74d8 assets/create/lang/unfinished/de_de.json -2e37dc718a8dea2af85daba7266c877ce80ff35b assets/create/lang/unfinished/fr_fr.json -f843761728c403276b7a47282f4fdd039b5b6854 assets/create/lang/unfinished/it_it.json -8b90c66fd5974c993e83bfa5733ca03187211d28 assets/create/lang/unfinished/ja_jp.json -59db0a3cff42707ecb828b975ef1fcba2a21a521 assets/create/lang/unfinished/ko_kr.json -b1900a6cce7216a4baa844affa169cfb32ff645c assets/create/lang/unfinished/nl_nl.json -d3f09a37b1f4ec5d53effc2b87efbccf2df2b7c7 assets/create/lang/unfinished/pt_br.json -16c92dab525ba20e85b65ee084f7b760432dcb73 assets/create/lang/unfinished/ru_ru.json -c8b5c2a3a65468950aa713a56bf1c930eef81305 assets/create/lang/unfinished/zh_cn.json +9fa2b840f81a9d61e25af4718a4948ee762ef0a8 assets/create/lang/en_us.json +ebe9ae0de05c542426e1fc9eeb865cad08f7c6a0 assets/create/lang/unfinished/de_de.json +f2525e7139a8e5aaac2fed2a562ad13a295f0e4e assets/create/lang/unfinished/fr_fr.json +30db009b45db33814b43f15d09775de2f9cad091 assets/create/lang/unfinished/it_it.json +25c2d05bfcdd0e64e889ca6ff36377d933f35e87 assets/create/lang/unfinished/ja_jp.json +7a4f40c3a6851714a450173f0c2f1e5689d96025 assets/create/lang/unfinished/ko_kr.json +c2b4070659ce9a0a44cbaa37beef3b0217d15c00 assets/create/lang/unfinished/nl_nl.json +9cfe6a2af979661bbdcc78edc28ab07b9a8f2f43 assets/create/lang/unfinished/pt_br.json +590368f1507e77d67c416299188b2e147e0a9616 assets/create/lang/unfinished/ru_ru.json +719105e25c79198ad76bd1782499545ce0f8a3ce assets/create/lang/unfinished/zh_cn.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index a7b48ea0c..8fa382ee8 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -819,6 +819,12 @@ "create.gui.goggles.kinetic_stats": "Kinetic Stats:", "create.gui.goggles.at_current_speed": "at current speed", "create.gui.goggles.pole_length": "Pole Length:", + "create.gui.assembly.exception": "This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "The Piston is missing some extension Poles", "create.gui.gauge.info_header": "Gauge Information:", "create.gui.speedometer.title": "Rotation Speed", "create.gui.stressometer.title": "Network Stress", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index ab2ac6851..3379876de 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1211", + "_": "Missing Localizations: 1217", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "UNLOCALIZED: Kinetic Stats:", "create.gui.goggles.at_current_speed": "UNLOCALIZED: at current speed", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "UNLOCALIZED: Gauge Information:", "create.gui.speedometer.title": "UNLOCALIZED: Rotation Speed", "create.gui.stressometer.title": "UNLOCALIZED: Network Stress", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 24cd8a5b7..c14ef3c22 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 862", + "_": "Missing Localizations: 868", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "Statistiques cinétiques:", "create.gui.goggles.at_current_speed": "À la vitesse actuelle", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "Informations sur la jauge:", "create.gui.speedometer.title": "Vitesse de rotation", "create.gui.stressometer.title": "Stress du réseau", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index 7de389b9f..134283a58 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 846", + "_": "Missing Localizations: 852", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "Statistiche Cinetiche:", "create.gui.goggles.at_current_speed": "Alla velocità Attuale", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "Informazioni sul Calibro:", "create.gui.speedometer.title": "Velocità di Rotazione", "create.gui.stressometer.title": "Stress della Rete", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 9b31a9385..9318e59cd 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 845", + "_": "Missing Localizations: 851", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "動力の統計:", "create.gui.goggles.at_current_speed": "現在の速度", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "計器の情報:", "create.gui.speedometer.title": "回転速度", "create.gui.stressometer.title": "ネットワークの応力", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index bec923df7..e8dd41da1 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 52", + "_": "Missing Localizations: 58", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "가동 상태:", "create.gui.goggles.at_current_speed": "현재 에너지량", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "게이지 정보:", "create.gui.speedometer.title": "회전 속도", "create.gui.stressometer.title": "네트워크 부하", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index 0b8b4afb2..067508d5c 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1152", + "_": "Missing Localizations: 1158", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "UNLOCALIZED: Kinetic Stats:", "create.gui.goggles.at_current_speed": "UNLOCALIZED: at current speed", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "UNLOCALIZED: Gauge Information:", "create.gui.speedometer.title": "UNLOCALIZED: Rotation Speed", "create.gui.stressometer.title": "UNLOCALIZED: Network Stress", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index e0eb5b879..b7397663d 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1218", + "_": "Missing Localizations: 1224", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "UNLOCALIZED: Kinetic Stats:", "create.gui.goggles.at_current_speed": "UNLOCALIZED: at current speed", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "UNLOCALIZED: Gauge Information:", "create.gui.speedometer.title": "UNLOCALIZED: Rotation Speed", "create.gui.stressometer.title": "UNLOCALIZED: Network Stress", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index 2085aa34a..88dbb7788 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 2", + "_": "Missing Localizations: 8", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "Кинетическая статистика:", "create.gui.goggles.at_current_speed": "На текущей скорости", "create.gui.goggles.pole_length": "Длина поршня", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "Калибровочная информация:", "create.gui.speedometer.title": "Скорость вращения", "create.gui.stressometer.title": "Сетевой момент", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 783cb9fb2..a1e4b7a73 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 5", + "_": "Missing Localizations: 11", "_": "->------------------------] Game Elements [------------------------<-", @@ -820,6 +820,12 @@ "create.gui.goggles.kinetic_stats": "动力学状态:", "create.gui.goggles.at_current_speed": "当前速度应力值", "create.gui.goggles.pole_length": "UNLOCALIZED: Pole Length:", + "create.gui.assembly.exception": "UNLOCALIZED: This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "UNLOCALIZED: Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "UNLOCALIZED: The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "UNLOCALIZED: There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "UNLOCALIZED: There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "UNLOCALIZED: The Piston is missing some extension Poles", "create.gui.gauge.info_header": "仪表信息:", "create.gui.speedometer.title": "旋转速度", "create.gui.stressometer.title": "网络应力", diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java index 67e595602..4beac5ff9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java @@ -1,23 +1,52 @@ package com.simibubi.create.content.contraptions.components.structureMovement; +import com.simibubi.create.foundation.config.AllConfigs; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; -public class AssemblyException extends RuntimeException { - public final ITextComponent message; +public class AssemblyException extends Exception { + public final ITextComponent component; - public AssemblyException(ITextComponent message) { - this.message = message; + public AssemblyException(ITextComponent component) { + this.component = component; } public AssemblyException(String langKey, Object... objects) { - this(new TranslationTextComponent("gui.goggles.contraptions." + langKey, objects)); + this(new TranslationTextComponent("create.gui.assembly.exception." + langKey, objects)); } public static AssemblyException unmovableBlock(BlockPos pos, BlockState state) { - return new AssemblyException("unmovableBlock", pos.getX(), pos.getY(), pos.getZ(), + return new AssemblyException("unmovableBlock", + pos.getX(), + pos.getY(), + pos.getZ(), new TranslationTextComponent(state.getBlock().getTranslationKey())); } + + public static AssemblyException unloadedChunk(BlockPos pos) { + return new AssemblyException("chunkNotLoaded", + pos.getX(), + pos.getY(), + pos.getZ()); + } + + public static AssemblyException structureTooLarge() { + return new AssemblyException("structureTooLarge", + AllConfigs.SERVER.kinetics.maxBlocksMoved.get()); + } + + public static AssemblyException tooManyPistonPoles() { + return new AssemblyException("tooManyPistonPoles", + AllConfigs.SERVER.kinetics.maxPistonPoles.get()); + } + + public static AssemblyException noPistonPoles() { + return new AssemblyException("noPistonPoles"); + } + + public String getFormattedText() { + return component.getFormattedText(); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index e2344c503..eb52b707e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -1,28 +1,5 @@ package com.simibubi.create.content.contraptions.components.structureMovement; -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole; -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Queue; -import java.util.Set; -import java.util.UUID; -import java.util.function.BiConsumer; -import java.util.stream.Collectors; - -import javax.annotation.Nullable; - -import org.apache.commons.lang3.tuple.MutablePair; -import org.apache.commons.lang3.tuple.Pair; - import com.simibubi.create.AllBlocks; import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.content.contraptions.base.KineticTileEntity; @@ -52,15 +29,7 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; - -import net.minecraft.block.AbstractButtonBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.ChestBlock; -import net.minecraft.block.DoorBlock; -import net.minecraft.block.IWaterLoggable; -import net.minecraft.block.PressurePlateBlock; +import net.minecraft.block.*; import net.minecraft.block.material.PushReaction; import net.minecraft.entity.Entity; import net.minecraft.fluid.Fluids; @@ -92,6 +61,16 @@ import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import net.minecraftforge.fluids.capability.templates.FluidTank; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.wrapper.CombinedInvWrapper; +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.function.BiConsumer; +import java.util.stream.Collectors; + +import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole; +import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead; public abstract class Contraption { @@ -150,7 +129,7 @@ public abstract class Contraption { } protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection, - Queue frontier) { + Queue frontier) throws AssemblyException { return true; } @@ -161,7 +140,7 @@ public abstract class Contraption { return contraption; } - public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) { + public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) throws AssemblyException { initialPassengers.clear(); Queue frontier = new LinkedList<>(); Set visited = new HashSet<>(); @@ -180,7 +159,7 @@ public abstract class Contraption { if (!moveBlock(world, forcedDirection, frontier, visited)) return false; } - throw new AssemblyException("structureTooLarge"); + throw AssemblyException.structureTooLarge(); } public void onEntityCreated(AbstractContraptionEntity entity) { @@ -249,7 +228,7 @@ public abstract class Contraption { /** move the first block in frontier queue */ protected boolean moveBlock(World world, @Nullable Direction forcedDirection, Queue frontier, - Set visited) { + Set visited) throws AssemblyException { BlockPos pos = frontier.poll(); if (pos == null) return false; @@ -258,7 +237,7 @@ public abstract class Contraption { if (World.isOutsideBuildHeight(pos)) return true; if (!world.isBlockPresent(pos)) - throw new AssemblyException("chunkNotLoaded"); + throw AssemblyException.unloadedChunk(pos); if (isAnchoringBlockAt(pos)) return true; BlockState state = world.getBlockState(pos); @@ -348,7 +327,7 @@ public abstract class Contraption { if (blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get()) return true; else - throw new AssemblyException("structureTooLarge"); + throw AssemblyException.structureTooLarge(); } private void moveBearing(BlockPos pos, Queue frontier, Set visited, BlockState state) { @@ -402,7 +381,7 @@ public abstract class Contraption { } private boolean moveMechanicalPiston(World world, BlockPos pos, Queue frontier, Set visited, - BlockState state) { + BlockState state) throws AssemblyException { int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); Direction direction = state.get(MechanicalPistonBlock.FACING); if (state.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { @@ -424,7 +403,7 @@ public abstract class Contraption { break; } if (limit <= -1) - throw new AssemblyException("tooManyPistonPoles"); + throw AssemblyException.tooManyPistonPoles(); } BlockPos searchPos = pos; @@ -443,7 +422,7 @@ public abstract class Contraption { } if (limit <= -1) - throw new AssemblyException("tooManyPistonPoles"); + throw AssemblyException.tooManyPistonPoles(); return true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/IDisplayAssemblyExceptions.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/IDisplayAssemblyExceptions.java new file mode 100644 index 000000000..33abfc9fb --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/IDisplayAssemblyExceptions.java @@ -0,0 +1,28 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; +import com.simibubi.create.foundation.utility.Lang; +import net.minecraft.util.text.TextFormatting; + +import java.util.Arrays; +import java.util.List; + +public interface IDisplayAssemblyExceptions { + + default boolean addExceptionToTooltip(List tooltip) { + AssemblyException e = getLastAssemblyException(); + if (e == null) + return false; + + if (!tooltip.isEmpty()) + tooltip.add(""); + + tooltip.add(IHaveGoggleInformation.spacing + TextFormatting.GOLD + Lang.translate("gui.assembly.exception")); + String text = e.getFormattedText(); + Arrays.stream(text.split("\n")).forEach(l -> tooltip.add(IHaveGoggleInformation.spacing + TextFormatting.GRAY + l)); + + return true; + } + + AssemblyException getLastAssemblyException(); +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java index 35a036a50..12c65902f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java @@ -1,13 +1,10 @@ package com.simibubi.create.content.contraptions.components.structureMovement.bearing; -import java.util.List; - -import org.apache.commons.lang3.tuple.Pair; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkContraption.HandType; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.gui.AllIcons; @@ -17,7 +14,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOpt import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.ServerSpeedProvider; - import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; @@ -27,8 +23,11 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; +import org.apache.commons.lang3.tuple.Pair; -public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity { +import java.util.List; + +public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions { protected ControlledContraptionEntity hourHand; protected ControlledContraptionEntity minuteHand; @@ -39,7 +38,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe protected boolean running; protected boolean assembleNextTick; - protected ITextComponent lastException; + protected AssemblyException lastException; protected ScrollOptionBehaviour operationMode; @@ -108,6 +107,11 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe applyRotations(); } + @Override + public AssemblyException getLastAssemblyException() { + return lastException; + } + protected void applyRotations() { BlockState blockState = getBlockState(); Axis axis = Axis.X; @@ -207,7 +211,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe contraption = ClockworkContraption.assembleClockworkAt(world, pos, direction); lastException = null; } catch (AssemblyException e) { - lastException = e.message; + lastException = e; + sendData(); return; } if (contraption == null) @@ -294,7 +299,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe compound.putFloat("HourAngle", hourAngle); compound.putFloat("MinuteAngle", minuteAngle); if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); super.write(compound, clientPacket); } @@ -307,7 +312,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe hourAngle = compound.getFloat("HourAngle"); minuteAngle = compound.getFloat("MinuteAngle"); if (compound.contains("LastException")) - lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); else lastException = null; super.read(compound, clientPacket); @@ -408,12 +413,4 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe return pos; } - @Override - public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { - boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); - if (lastException != null) - tooltip.add(lastException.getFormattedText()); - return lastException != null || added; - } - } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java index be481d66e..ed71bf748 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java @@ -1,21 +1,19 @@ package com.simibubi.create.content.contraptions.components.structureMovement.bearing; -import java.util.HashSet; -import java.util.Queue; -import java.util.Set; - -import org.apache.commons.lang3.tuple.Pair; - import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.foundation.utility.NBTHelper; - import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.HashSet; +import java.util.Queue; +import java.util.Set; public class ClockworkContraption extends Contraption { @@ -88,13 +86,13 @@ public class ClockworkContraption extends Contraption { } @Override - public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) { + public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) throws AssemblyException { return super.searchMovedStructure(world, pos.offset(direction, offset + 1), null); } @Override protected boolean moveBlock(World world, Direction direction, Queue frontier, - Set visited) { + Set visited) throws AssemblyException { if (ignoreBlocks.contains(frontier.peek())) { frontier.poll(); return true; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java index 1bb979484..353e58c17 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java @@ -1,13 +1,10 @@ package com.simibubi.create.content.contraptions.components.structureMovement.bearing; -import static net.minecraft.state.properties.BlockStateProperties.FACING; - -import java.util.List; - import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -15,7 +12,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOpt import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.ServerSpeedProvider; - import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; @@ -25,7 +21,11 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; -public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity { +import java.util.List; + +import static net.minecraft.state.properties.BlockStateProperties.FACING; + +public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions { protected ScrollOptionBehaviour movementMode; protected ControlledContraptionEntity movedContraption; @@ -33,7 +33,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp protected boolean running; protected boolean assembleNextTick; protected float clientAngleDiff; - protected ITextComponent lastException; + protected AssemblyException lastException; public MechanicalBearingTileEntity(TileEntityType type) { super(type); @@ -66,7 +66,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp compound.putBoolean("Running", running); compound.putFloat("Angle", angle); if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); super.write(compound, clientPacket); } @@ -76,7 +76,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp running = compound.getBoolean("Running"); angle = compound.getFloat("Angle"); if (compound.contains("LastException")) - lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); else lastException = null; super.read(compound, clientPacket); @@ -113,6 +113,11 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp return speed; } + @Override + public AssemblyException getLastAssemblyException() { + return lastException; + } + protected boolean isWindmill() { return false; } @@ -130,11 +135,13 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp Direction direction = getBlockState().get(FACING); BearingContraption contraption = new BearingContraption(isWindmill(), direction); try { - lastException = null; if (!contraption.assemble(world, pos)) return; + + lastException = null; } catch (AssemblyException e) { - lastException = e.message; + lastException = e; + sendData(); return; } @@ -296,12 +303,4 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp TooltipHelper.addHint(tooltip, "hint.empty_bearing"); return true; } - - @Override - public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { - boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); - if (lastException != null) - tooltip.add(lastException.getFormattedText()); - return lastException != null || added; - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java index 5813f6afe..8a50eb7cf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlock.java @@ -237,11 +237,18 @@ public class CartAssemblerBlock extends AbstractRailBlock MountedContraption contraption = new MountedContraption(mode); try { - assembler.ifPresent(te -> te.lastException = null); if (!contraption.assemble(world, pos)) return; + + assembler.ifPresent(te -> { + te.lastException = null; + te.sendData(); + }); } catch (AssemblyException e) { - assembler.ifPresent(te -> te.lastException = e.message); + assembler.ifPresent(te -> { + te.lastException = e; + te.sendData(); + }); return; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java index 6e1c3be7a..4640e7fa9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java @@ -1,8 +1,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.mounted; -import java.util.List; - -import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; +import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions; import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -12,19 +11,21 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.INamedIco import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.VecHelper; - +import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.RailShape; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.ITextComponent; -public class CartAssemblerTileEntity extends SmartTileEntity implements IHaveGoggleInformation { +import java.util.List; + +public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplayAssemblyExceptions { private static final int assemblyCooldown = 8; protected ScrollOptionBehaviour movementMode; private int ticksSinceMinecartUpdate; - protected ITextComponent lastException; //TODO + protected AssemblyException lastException; public CartAssemblerTileEntity(TileEntityType type) { super(type); @@ -47,6 +48,27 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IHaveGog behaviours.add(movementMode); } + @Override + public void write(CompoundNBT compound, boolean clientPacket) { + if (lastException != null) + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); + super.write(compound, clientPacket); + } + + @Override + protected void read(CompoundNBT compound, boolean clientPacket) { + if (compound.contains("LastException")) + lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); + else + lastException = null; + super.read(compound, clientPacket); + } + + @Override + public AssemblyException getLastAssemblyException() { + return lastException; + } + protected ValueBoxTransform getMovementModeSlot() { return new CartAssemblerValueBoxTransform(); } @@ -106,11 +128,4 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IHaveGog public boolean isMinecartUpdateValid() { return ticksSinceMinecartUpdate >= assemblyCooldown; } - - @Override - public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { - if (lastException != null) - tooltip.add(lastException.getFormattedText()); - return lastException != null; - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java index e92f2d807..9b6454df9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java @@ -1,18 +1,12 @@ package com.simibubi.create.content.contraptions.components.structureMovement.piston; -import java.util.List; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; -import com.simibubi.create.content.contraptions.components.structureMovement.ControlledContraptionEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.IControlContraption; +import com.simibubi.create.content.contraptions.components.structureMovement.*; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.ServerSpeedProvider; - import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.BlockPos; @@ -20,7 +14,9 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.ITextComponent; -public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption { +import java.util.List; + +public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption, IDisplayAssemblyExceptions { public float offset; public boolean running; @@ -29,7 +25,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme protected boolean forceMove; protected ScrollOptionBehaviour movementMode; protected boolean waitingForSpeedChange; - protected ITextComponent lastException; + protected AssemblyException lastException; // Custom position sync protected float clientOffsetDiff; @@ -87,8 +83,9 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme assemble(); lastException = null; } catch (AssemblyException e) { - lastException = e.message; + lastException = e; } + sendData(); } return; } @@ -162,7 +159,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme compound.putBoolean("Waiting", waitingForSpeedChange); compound.putFloat("Offset", offset); if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); super.write(compound, clientPacket); if (clientPacket && forceMove) { @@ -180,7 +177,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme waitingForSpeedChange = compound.getBoolean("Waiting"); offset = compound.getFloat("Offset"); if (compound.contains("LastException")) - lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); else lastException = null; super.read(compound, clientPacket); @@ -197,6 +194,11 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme movedContraption = null; } + @Override + public AssemblyException getLastAssemblyException() { + return lastException; + } + public abstract void disassemble(); protected abstract void assemble() throws AssemblyException; @@ -302,13 +304,4 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme public BlockPos getBlockPosition() { return pos; } - - @Override - public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { - boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); - if (lastException != null) - tooltip.add(lastException.getFormattedText()); - return lastException != null || added; - } - } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java index 39a48d58e..c1cb38c3a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java @@ -68,7 +68,7 @@ public class PistonContraption extends TranslatingContraption { return true; } - private boolean collectExtensions(World world, BlockPos pos, Direction direction) { + private boolean collectExtensions(World world, BlockPos pos, Direction direction) throws AssemblyException { List poles = new ArrayList<>(); BlockPos actualStart = pos; BlockState nextBlock = world.getBlockState(actualStart.offset(direction)); @@ -91,7 +91,7 @@ public class PistonContraption extends TranslatingContraption { nextBlock = world.getBlockState(actualStart.offset(direction)); if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles()) - throw new AssemblyException("tooManyPistonPoles"); + throw AssemblyException.tooManyPistonPoles(); } } @@ -114,7 +114,7 @@ public class PistonContraption extends TranslatingContraption { nextBlock = world.getBlockState(end.offset(direction.getOpposite())); if (extensionsInFront + extensionsInBack > MechanicalPistonBlock.maxAllowedPistonPoles()) - throw new AssemblyException("tooManyPistonPoles"); + throw AssemblyException.tooManyPistonPoles(); } anchor = pos.offset(direction, initialExtensionProgress + 1); @@ -126,7 +126,7 @@ public class PistonContraption extends TranslatingContraption { 1, 1); if (extensionLength == 0) - throw new AssemblyException("noPistonPoles"); + throw AssemblyException.noPistonPoles(); bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0); @@ -146,7 +146,7 @@ public class PistonContraption extends TranslatingContraption { } @Override - protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, Queue frontier) { + protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, Queue frontier) throws AssemblyException { frontier.clear(); boolean sticky = isStickyPiston(world.getBlockState(pos.offset(orientation, -1))); boolean retracting = direction != orientation; @@ -159,7 +159,7 @@ public class PistonContraption extends TranslatingContraption { if (retracting && World.isOutsideBuildHeight(currentPos)) return true; if (!world.isBlockPresent(currentPos)) - throw new AssemblyException("chunkNotLoaded"); + throw AssemblyException.unloadedChunk(currentPos); BlockState state = world.getBlockState(currentPos); if (!BlockMovementTraits.movementNecessary(state, world, currentPos)) return true; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index b1894d543..5f0bf3469 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -9,7 +9,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pis import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; - import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.IWaterLoggable; @@ -192,7 +191,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { protected void read(CompoundNBT compound, boolean clientPacket) { initialOffset = compound.getInt("InitialOffset"); if (compound.contains("LastException")) - lastException = ITextComponent.Serializer.fromJson(compound.getString("LastException")); + lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); else lastException = null; super.read(compound, clientPacket); @@ -202,7 +201,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { public void write(CompoundNBT compound, boolean clientPacket) { compound.putInt("InitialOffset", initialOffset); if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException)); + compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); super.write(compound, clientPacket); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java index 07b9dff3a..c61452bb8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java @@ -4,6 +4,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; import com.simibubi.create.CreateClient; +import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock; import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock; import com.simibubi.create.foundation.config.AllConfigs; @@ -92,6 +93,14 @@ public class GoggleOverlayRenderer { tooltip.remove(tooltip.size() - 1); } + if (te instanceof IDisplayAssemblyExceptions) { + boolean exceptionAdded = ((IDisplayAssemblyExceptions) te).addExceptionToTooltip(tooltip); + if (exceptionAdded) { + hasHoveringInformation = true; + hoverAddedInformation = true; + } + } + // break early if goggle or hover returned false when present if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation)) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java b/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java index 728f1c631..9a664a92d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java +++ b/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java @@ -9,13 +9,13 @@ import java.util.List; public interface IHaveGoggleInformation { DecimalFormat decimalFormat = new DecimalFormat("#.##"); - public static String spacing = " "; + String spacing = " "; /** * this method will be called when looking at a TileEntity that implemented this interface * - * @return {{@code true}} if the tooltip creation was successful and should be displayed, - * or {{@code false}} if the overlay should not be displayed + * @return {@code true} if the tooltip creation was successful and should be displayed, + * or {@code false} if the overlay should not be displayed * */ default boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking){ return false; diff --git a/src/main/resources/assets/create/lang/default/messages.json b/src/main/resources/assets/create/lang/default/messages.json index 57fbc9b7e..94af8ae4d 100644 --- a/src/main/resources/assets/create/lang/default/messages.json +++ b/src/main/resources/assets/create/lang/default/messages.json @@ -172,6 +172,13 @@ "create.gui.goggles.at_current_speed": "at current speed", "create.gui.goggles.pole_length": "Pole Length:", + "create.gui.assembly.exception": "This Contraption was unable to assemble:", + "create.gui.assembly.exception.unmovableBlock": "Unmovable Block (%4$s) at [%1$s %2$s %3$s]", + "create.gui.assembly.exception.chunkNotLoaded": "The Block at [%1$s %2$s %3$s] was not in a loaded chunk", + "create.gui.assembly.exception.structureTooLarge": "There are too many Blocks included in the contraption.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.tooManyPistonPoles": "There are too many extension Poles attached to this Piston.\nThe configured maximum is: %1$s", + "create.gui.assembly.exception.noPistonPoles": "The Piston is missing some extension Poles", + "create.gui.gauge.info_header": "Gauge Information:", "create.gui.speedometer.title": "Rotation Speed", "create.gui.stressometer.title": "Network Stress", From 34de9a031997f48801392d40b7ebb8b6261e5d9c Mon Sep 17 00:00:00 2001 From: Zelophed Date: Fri, 12 Feb 2021 03:13:19 +0100 Subject: [PATCH 31/31] Player Feedback, Part III --- .../structureMovement/AssemblyException.java | 43 +++++++- .../bearing/ClockworkBearingTileEntity.java | 9 +- .../bearing/MechanicalBearingTileEntity.java | 9 +- .../gantry/GantryContraption.java | 4 +- .../gantry/GantryPinionTileEntity.java | 39 ++++++- .../mounted/CartAssemblerTileEntity.java | 9 +- .../piston/LinearActuatorTileEntity.java | 9 +- .../piston/PistonContraption.java | 2 +- .../pulley/PulleyTileEntity.java | 7 -- .../foundation/command/AllCommands.java | 43 +++++--- .../foundation/command/HighlightCommand.java | 103 ++++++++++++++++++ .../foundation/command/HighlightPacket.java | 55 ++++++++++ .../foundation/networking/AllPackets.java | 25 ++--- .../foundation/utility/outliner/Outliner.java | 23 ++-- 14 files changed, 298 insertions(+), 82 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/command/HighlightCommand.java create mode 100644 src/main/java/com/simibubi/create/foundation/command/HighlightPacket.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java index 4beac5ff9..0db500c6d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AssemblyException.java @@ -2,12 +2,39 @@ package com.simibubi.create.content.contraptions.components.structureMovement; import com.simibubi.create.foundation.config.AllConfigs; import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; public class AssemblyException extends Exception { public final ITextComponent component; + private BlockPos position = null; + + public static void write(CompoundNBT compound, AssemblyException exception) { + if (exception == null) + return; + + CompoundNBT nbt = new CompoundNBT(); + nbt.putString("Component", ITextComponent.Serializer.toJson(exception.component)); + if (exception.hasPosition()) + nbt.putLong("Position", exception.getPosition().toLong()); + + compound.put("LastException", nbt); + } + + public static AssemblyException read(CompoundNBT compound) { + if (!compound.contains("LastException")) + return null; + + CompoundNBT nbt = compound.getCompound("LastException"); + String string = nbt.getString("Component"); + AssemblyException exception = new AssemblyException(ITextComponent.Serializer.fromJson(string)); + if (nbt.contains("Position")) + exception.position = BlockPos.fromLong(nbt.getLong("Position")); + + return exception; + } public AssemblyException(ITextComponent component) { this.component = component; @@ -18,18 +45,22 @@ public class AssemblyException extends Exception { } public static AssemblyException unmovableBlock(BlockPos pos, BlockState state) { - return new AssemblyException("unmovableBlock", + AssemblyException e = new AssemblyException("unmovableBlock", pos.getX(), pos.getY(), pos.getZ(), new TranslationTextComponent(state.getBlock().getTranslationKey())); + e.position = pos; + return e; } public static AssemblyException unloadedChunk(BlockPos pos) { - return new AssemblyException("chunkNotLoaded", + AssemblyException e = new AssemblyException("chunkNotLoaded", pos.getX(), pos.getY(), pos.getZ()); + e.position = pos; + return e; } public static AssemblyException structureTooLarge() { @@ -49,4 +80,12 @@ public class AssemblyException extends Exception { public String getFormattedText() { return component.getFormattedText(); } + + public boolean hasPosition() { + return position != null; + } + + public BlockPos getPosition() { + return position; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java index 12c65902f..69b40f6fd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java @@ -22,7 +22,6 @@ import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.text.ITextComponent; import org.apache.commons.lang3.tuple.Pair; import java.util.List; @@ -298,8 +297,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe compound.putBoolean("Running", running); compound.putFloat("HourAngle", hourAngle); compound.putFloat("MinuteAngle", minuteAngle); - if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); + AssemblyException.write(compound, lastException); super.write(compound, clientPacket); } @@ -311,10 +309,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe running = compound.getBoolean("Running"); hourAngle = compound.getFloat("HourAngle"); minuteAngle = compound.getFloat("MinuteAngle"); - if (compound.contains("LastException")) - lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); - else - lastException = null; + lastException = AssemblyException.read(compound); super.read(compound, clientPacket); if (!clientPacket) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java index 353e58c17..65573cb35 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java @@ -19,7 +19,6 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.text.ITextComponent; import java.util.List; @@ -65,8 +64,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public void write(CompoundNBT compound, boolean clientPacket) { compound.putBoolean("Running", running); compound.putFloat("Angle", angle); - if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); + AssemblyException.write(compound, lastException); super.write(compound, clientPacket); } @@ -75,10 +73,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp float angleBefore = angle; running = compound.getBoolean("Running"); angle = compound.getFloat("Angle"); - if (compound.contains("LastException")) - lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); - else - lastException = null; + lastException = AssemblyException.read(compound); super.read(compound, clientPacket); if (!clientPacket) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java index 58ddcadcb..8bc426b3e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java @@ -1,9 +1,9 @@ package com.simibubi.create.content.contraptions.components.structureMovement.gantry; import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; - import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -21,7 +21,7 @@ public class GantryContraption extends TranslatingContraption { } @Override - public boolean assemble(World world, BlockPos pos) { + public boolean assemble(World world, BlockPos pos) throws AssemblyException { if (!searchMovedStructure(world, pos, null)) return false; startMoving(world); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionTileEntity.java index 3c2b6f437..000a944ba 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionTileEntity.java @@ -1,23 +1,26 @@ package com.simibubi.create.content.contraptions.components.structureMovement.gantry; -import static net.minecraft.state.properties.BlockStateProperties.FACING; - import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; +import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions; import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlock; import com.simibubi.create.content.contraptions.relays.advanced.GantryShaftTileEntity; - import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; -public class GantryPinionTileEntity extends KineticTileEntity { +import static net.minecraft.state.properties.BlockStateProperties.FACING; + +public class GantryPinionTileEntity extends KineticTileEntity implements IDisplayAssemblyExceptions { boolean assembleNextTick; + protected AssemblyException lastException; public GantryPinionTileEntity(TileEntityType typeIn) { super(typeIn); @@ -50,6 +53,11 @@ public class GantryPinionTileEntity extends KineticTileEntity { } } + @Override + public AssemblyException getLastAssemblyException() { + return lastException; + } + private void tryAssemble() { BlockState blockState = getBlockState(); if (!(blockState.getBlock() instanceof GantryPinionBlock)) @@ -71,8 +79,17 @@ public class GantryPinionTileEntity extends KineticTileEntity { if (pinionMovementSpeed < 0) movementDirection = movementDirection.getOpposite(); - if (!contraption.assemble(world, pos)) + try { + lastException = null; + if (!contraption.assemble(world, pos)) + return; + + sendData(); + } catch (AssemblyException e) { + lastException = e; + sendData(); return; + } if (ContraptionCollider.isCollidingWithWorld(world, contraption, pos.offset(movementDirection), movementDirection)) return; @@ -85,6 +102,18 @@ public class GantryPinionTileEntity extends KineticTileEntity { world.addEntity(movedContraption); } + @Override + protected void write(CompoundNBT compound, boolean clientPacket) { + AssemblyException.write(compound, lastException); + super.write(compound, clientPacket); + } + + @Override + protected void read(CompoundNBT compound, boolean clientPacket) { + lastException = AssemblyException.read(compound); + super.read(compound, clientPacket); + } + @Override public float propagateRotationTo(KineticTileEntity target, BlockState stateFrom, BlockState stateTo, BlockPos diff, boolean connectedViaAxes, boolean connectedViaCogs) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java index 4640e7fa9..f94f0bdc7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java @@ -16,7 +16,6 @@ import net.minecraft.state.properties.RailShape; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.ITextComponent; import java.util.List; @@ -50,17 +49,13 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay @Override public void write(CompoundNBT compound, boolean clientPacket) { - if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); + AssemblyException.write(compound, lastException); super.write(compound, clientPacket); } @Override protected void read(CompoundNBT compound, boolean clientPacket) { - if (compound.contains("LastException")) - lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); - else - lastException = null; + lastException = AssemblyException.read(compound); super.read(compound, clientPacket); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java index 1adfdb1cd..ce3cb1470 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java @@ -12,7 +12,6 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.ITextComponent; import java.util.List; @@ -158,8 +157,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme compound.putBoolean("Running", running); compound.putBoolean("Waiting", waitingForSpeedChange); compound.putFloat("Offset", offset); - if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); + AssemblyException.write(compound, lastException); super.write(compound, clientPacket); if (clientPacket && forceMove) { @@ -176,10 +174,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme running = compound.getBoolean("Running"); waitingForSpeedChange = compound.getBoolean("Waiting"); offset = compound.getFloat("Offset"); - if (compound.contains("LastException")) - lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); - else - lastException = null; + lastException = AssemblyException.read(compound); super.read(compound, clientPacket); if (!clientPacket) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java index 09565629a..e0b12b263 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java @@ -1,8 +1,8 @@ package com.simibubi.create.content.contraptions.components.structureMovement.piston; -import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionType; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.*; import com.simibubi.create.foundation.config.AllConfigs; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index 5f0bf3469..b20ff7fdc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -22,7 +22,6 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.ITextComponent; public class PulleyTileEntity extends LinearActuatorTileEntity { @@ -190,18 +189,12 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { @Override protected void read(CompoundNBT compound, boolean clientPacket) { initialOffset = compound.getInt("InitialOffset"); - if (compound.contains("LastException")) - lastException = new AssemblyException(ITextComponent.Serializer.fromJson(compound.getString("LastException"))); - else - lastException = null; super.read(compound, clientPacket); } @Override public void write(CompoundNBT compound, boolean clientPacket) { compound.putInt("InitialOffset", initialOffset); - if (lastException != null) - compound.putString("LastException", ITextComponent.Serializer.toJson(lastException.component)); super.write(compound, clientPacket); } diff --git a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java index fe1ec78cf..cf36c3c7a 100644 --- a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java +++ b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java @@ -1,25 +1,42 @@ package com.simibubi.create.foundation.command; import com.mojang.brigadier.CommandDispatcher; - +import com.mojang.brigadier.tree.CommandNode; +import com.mojang.brigadier.tree.LiteralCommandNode; import net.minecraft.command.CommandSource; import net.minecraft.command.Commands; +import net.minecraft.entity.player.PlayerEntity; + +import java.util.Collections; +import java.util.function.Predicate; public class AllCommands { - public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("create") - //general purpose - .then(ToggleDebugCommand.register()) - .then(OverlayConfigCommand.register()) - .then(FixLightingCommand.register()) - .then(ReplaceInCommandBlocksCommand.register()) + public static Predicate sourceIsPlayer = (cs) -> cs.getEntity() instanceof PlayerEntity; - //dev-util - //Comment out for release - .then(ClearBufferCacheCommand.register()) - .then(ChunkUtilCommand.register()) -// .then(KillTPSCommand.register()) + public static void register(CommandDispatcher dispatcher) { + + LiteralCommandNode createRoot = dispatcher.register(Commands.literal("create") + //general purpose + .then(ToggleDebugCommand.register()) + .then(OverlayConfigCommand.register()) + .then(FixLightingCommand.register()) + .then(ReplaceInCommandBlocksCommand.register()) + .then(HighlightCommand.register()) + + //dev-util + //Comment out for release + .then(ClearBufferCacheCommand.register()) + .then(ChunkUtilCommand.register()) + //.then(KillTPSCommand.register()) + ); + + CommandNode c = dispatcher.findNode(Collections.singleton("c")); + if (c != null) + return; + + dispatcher.register(Commands.literal("c") + .redirect(createRoot) ); } } diff --git a/src/main/java/com/simibubi/create/foundation/command/HighlightCommand.java b/src/main/java/com/simibubi/create/foundation/command/HighlightCommand.java new file mode 100644 index 000000000..6071c14f9 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/command/HighlightCommand.java @@ -0,0 +1,103 @@ +package com.simibubi.create.foundation.command; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.ArgumentBuilder; +import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException; +import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions; +import com.simibubi.create.foundation.networking.AllPackets; +import net.minecraft.command.CommandSource; +import net.minecraft.command.Commands; +import net.minecraft.command.arguments.BlockPosArgument; +import net.minecraft.command.arguments.EntityArgument; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.*; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.PacketDistributor; + +import java.util.Collection; + +public class HighlightCommand { + + public static ArgumentBuilder register() { + return Commands.literal("highlight") + .requires(cs -> cs.hasPermissionLevel(0)) + .requires(AllCommands.sourceIsPlayer) + .then(Commands.argument("pos", BlockPosArgument.blockPos()) + .requires(AllCommands.sourceIsPlayer) + .executes(ctx -> { + BlockPos pos = BlockPosArgument.getLoadedBlockPos(ctx, "pos"); + + AllPackets.channel.send( + PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()), + new HighlightPacket(pos) + ); + + return Command.SINGLE_SUCCESS; + }) + .then(Commands.argument("players", EntityArgument.players()) + .executes(ctx -> { + Collection players = EntityArgument.getPlayers(ctx, "players"); + BlockPos pos = BlockPosArgument.getBlockPos(ctx, "pos"); + + for (ServerPlayerEntity p : players) { + AllPackets.channel.send( + PacketDistributor.PLAYER.with(() -> p), + new HighlightPacket(pos) + ); + } + + return players.size(); + }) + ) + ) + .executes(ctx -> { + ServerPlayerEntity player = ctx.getSource().asPlayer(); + return highlightAssemblyExceptionFor(player, ctx.getSource()); + }); + + } + + private static void sendMissMessage(CommandSource source) { + source.sendFeedback(new StringTextComponent("Try looking at a Block that has failed to assemble a Contraption and try again."), true); + } + + private static int highlightAssemblyExceptionFor(ServerPlayerEntity player, CommandSource source) { + double distance = player.getAttribute(PlayerEntity.REACH_DISTANCE).getValue(); + Vec3d start = player.getEyePosition(1); + Vec3d look = player.getLook(1); + Vec3d end = start.add(look.x * distance, look.y * distance, look.z * distance); + World world = player.world; + + BlockRayTraceResult ray = world.rayTraceBlocks(new RayTraceContext(start, end, RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, player)); + if (ray.getType() == RayTraceResult.Type.MISS) { + sendMissMessage(source); + return 0; + } + + BlockPos pos = ray.getPos(); + TileEntity te = world.getTileEntity(pos); + if (!(te instanceof IDisplayAssemblyExceptions)) { + sendMissMessage(source); + return 0; + } + + IDisplayAssemblyExceptions display = (IDisplayAssemblyExceptions) te; + AssemblyException exception = display.getLastAssemblyException(); + if (exception == null) { + sendMissMessage(source); + return 0; + } + + if (!exception.hasPosition()) { + source.sendFeedback(new StringTextComponent("Can't highlight a specific position for this issue"), true); + return Command.SINGLE_SUCCESS; + } + + BlockPos p = exception.getPosition(); + String command = "/create highlight " + p.getX() + " " + p.getY() + " " + p.getZ(); + return player.server.getCommandManager().handleCommand(source, command); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/command/HighlightPacket.java b/src/main/java/com/simibubi/create/foundation/command/HighlightPacket.java new file mode 100644 index 000000000..7b4b10a4c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/command/HighlightPacket.java @@ -0,0 +1,55 @@ +package com.simibubi.create.foundation.command; + +import com.simibubi.create.AllSpecialTextures; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.networking.SimplePacketBase; +import net.minecraft.client.Minecraft; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.shapes.VoxelShapes; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +public class HighlightPacket extends SimplePacketBase { + + private final BlockPos pos; + + public HighlightPacket(BlockPos pos) { + this.pos = pos; + } + + public HighlightPacket(PacketBuffer buffer) { + this.pos = BlockPos.fromLong(buffer.readLong()); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeLong(pos.toLong()); + } + + @Override + public void handle(Supplier ctx) { + ctx.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { + performHighlight(pos); + })); + + ctx.get().setPacketHandled(true); + } + + @OnlyIn(Dist.CLIENT) + public static void performHighlight(BlockPos pos) { + if (Minecraft.getInstance().world == null || !Minecraft.getInstance().world.isBlockPresent(pos)) + return; + + CreateClient.outliner.showAABB("highlightCommand", VoxelShapes.fullCube().getBoundingBox().offset(pos), 200) + .lineWidth(1 / 32f) + .colored(0xEeEeEe) + //.colored(0x243B50) + .withFaceTexture(AllSpecialTextures.SELECTION); + + } +} diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 6c5342883..2cabdfb0a 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -1,19 +1,11 @@ package com.simibubi.create.foundation.networking; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; - import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraptionUpdatePacket; import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionFluidPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.sync.LimbSwingUpdatePacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.*; import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingCreationPacket; import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartControllerUpdatePacket; import com.simibubi.create.content.contraptions.fluids.actors.FluidSplashPacket; @@ -25,16 +17,12 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmPlacementPac import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket; import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket; import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket; -import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; -import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; -import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; -import com.simibubi.create.content.schematics.packet.SchematicSyncPacket; -import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; +import com.simibubi.create.content.schematics.packet.*; import com.simibubi.create.foundation.command.ConfigureConfigPacket; +import com.simibubi.create.foundation.command.HighlightPacket; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket; import com.simibubi.create.foundation.utility.ServerSpeedProvider; - import net.minecraft.network.PacketBuffer; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -46,8 +34,12 @@ import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor.TargetPoint; import net.minecraftforge.fml.network.simple.SimpleChannel; -import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_CLIENT; +import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER; public enum AllPackets { @@ -85,6 +77,7 @@ public enum AllPackets { FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT), CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new, PLAY_TO_CLIENT), GANTRY_UPDATE(GantryContraptionUpdatePacket.class, GantryContraptionUpdatePacket::new, PLAY_TO_CLIENT), + BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket::new, PLAY_TO_CLIENT) ; diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java index 39a019c65..9c442b89d 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java @@ -1,24 +1,18 @@ package com.simibubi.create.foundation.utility.outliner; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBox; import com.simibubi.create.foundation.utility.outliner.LineOutline.EndChasingLineOutline; import com.simibubi.create.foundation.utility.outliner.Outline.OutlineParams; - import net.minecraft.client.Minecraft; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import java.util.*; + public class Outliner { final Map outlines; @@ -57,6 +51,13 @@ public class Outliner { return entry.outline.getParams(); } + public OutlineParams showAABB(Object slot, AxisAlignedBB bb, int ttl) { + createAABBOutlineIfMissing(slot, bb); + ChasingAABBOutline outline = getAndRefreshAABB(slot, ttl); + outline.prevBB = outline.targetBB = bb; + return outline.getParams(); + } + public OutlineParams showAABB(Object slot, AxisAlignedBB bb) { createAABBOutlineIfMissing(slot, bb); ChasingAABBOutline outline = getAndRefreshAABB(slot); @@ -112,6 +113,12 @@ public class Outliner { return (ChasingAABBOutline) entry.getOutline(); } + private ChasingAABBOutline getAndRefreshAABB(Object slot, int ttl) { + OutlineEntry entry = outlines.get(slot); + entry.ticksTillRemoval = ttl; + return (ChasingAABBOutline) entry.getOutline(); + } + // Maintenance public Outliner() {