From 38c9415f87ae6ae60c73a85e98dca28723573fdf Mon Sep 17 00:00:00 2001 From: cripsy_chips1234 <60465425+CrispyChips6660@users.noreply.github.com> Date: Mon, 13 Apr 2020 14:52:18 +0800 Subject: [PATCH 01/11] Update zh_cn.json --- .../resources/assets/create/lang/zh_cn.json | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/resources/assets/create/lang/zh_cn.json b/src/main/resources/assets/create/lang/zh_cn.json index 73f4e0293..2763fbeed 100644 --- a/src/main/resources/assets/create/lang/zh_cn.json +++ b/src/main/resources/assets/create/lang/zh_cn.json @@ -6,12 +6,12 @@ "item.create.placement_handgun": "手持式方块放置器", "item.create.terrain_zapper": "手持式环境塑形器", "item.create.tree_fertilizer": "树木肥料", - "item.create.empty_blueprint": "空白原理图", - "item.create.andesite_alloy": "安山合金", + "item.create.empty_blueprint": "空白蓝图", + "item.create.andesite_alloy": "安山岩合金", "item.create.chromatic_compound": "谜之化合物", "item.create.shadow_steel": "暗影金属", - "item.create.blueprint_and_quill": "原理图与笔", - "item.create.blueprint": "原理图", + "item.create.blueprint_and_quill": "蓝图与笔", + "item.create.blueprint": "蓝图", "item.create.belt_connector": "传送带", "item.create.goggles": "工程师护目镜", "item.create.filter": "过滤器", @@ -79,9 +79,9 @@ "block.create.copper_shingles": "铜瓦堆", "block.create.zinc_ore": "锌矿", - "block.create.andesite_casing": "安山箱", - "block.create.brass_casing": "黄铜箱", - "block.create.copper_casing": "铜箱", + "block.create.andesite_casing": "安山套管", + "block.create.brass_casing": "黄铜套管", + "block.create.copper_casing": "铜套管", "block.create.cogwheel": "齿轮", "block.create.large_cogwheel": "大齿轮", @@ -100,7 +100,7 @@ "block.create.creative_motor": "动力马达", "block.create.belt": "传送带", "block.create.crushing_wheel": "粉碎轮", - "block.create.drill": "动力钻头", + "block.create.drill": "钻头", "block.create.portable_storage_interface": "移动式储物接口", "block.create.harvester": "收割机", "block.create.saw": "切割机", @@ -109,7 +109,7 @@ "block.create.mechanical_mixer": "搅拌器", "block.create.deployer": "机械手", "block.create.basin": "工作盆", - "block.create.mechanical_crafter": "机械制造机", + "block.create.mechanical_crafter": "机械制造台", "block.create.flywheel": "飞轮", "block.create.furnace_engine": "熔炉引擎", "block.create.speed_gauge": "速度表", @@ -120,13 +120,13 @@ "block.create.sticky_mechanical_piston": "粘性动力活塞", "block.create.mechanical_piston": "动力活塞", - "block.create.mechanical_piston_head": "Mechanical Piston Head", + "block.create.mechanical_piston_head": "动力活塞头", "block.create.piston_pole": "活塞杆", "block.create.mechanical_bearing": "动力轴承", "block.create.clockwork_bearing": "时钟轴承", "block.create.rope_pulley": "绳索滑轮", - "block.create.rope": "Rope", - "block.create.pulley_magnet": "Pulley Magnet", + "block.create.rope": "绳子", + "block.create.pulley_magnet": "滑轮磁铁", "block.create.translation_chassis": "机壳底盘", "block.create.rotation_chassis": "旋转底盘", @@ -145,7 +145,7 @@ "block.create.toggle_latch": "T触发器", "block.create.flexpeater": "高级中继器", "block.create.entity_detector": "传送带观察者", - "block.create.logistical_casing": "Logistical Casing", + "block.create.logistical_casing": "Logistical 套管", "block.create.logistical_controller": "Logistical Controller", "block.create.logistical_index": "Logistical Index", "block.create.logisticians_table": "Logistician's Table", @@ -308,8 +308,8 @@ "create.generic.speed": "速度", "create.generic.delay": "延时", "create.generic.unit.ticks": "Ticks", - "create.generic.unit.seconds": "Seconds", - "create.generic.unit.minutes": "Minutes", + "create.generic.unit.seconds": "秒", + "create.generic.unit.minutes": "分钟", "create.generic.unit.rpm": "RPM", "create.generic.unit.stress": "su", "create.generic.unit.degrees": "°", @@ -1170,4 +1170,4 @@ "item.create.logistical_filter.tooltip": "WIP", "itemGroup.create": "机械动力" -} \ No newline at end of file +} From db8e52be2ec856915ee27f3b6622cdf51755f3cd Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 16 Apr 2020 20:46:15 +0200 Subject: [PATCH 02/11] Bugs & Refactors - Added new selection/outline particles for use in place of bounding box rendering - Refactored JEI categories - Slots for chance outputs now have a slighly different appearance in JEI - Redstone links no longer cause a redstone update when loaded in - Redstone links no longer mess up windmill bearings on chunk reload - Fixed redstone links not working properly after movement in a contraption - Filter output amounts can no longer be increased beyond the stack limit - Chassis range visualization now uses the new outline particle - Kinetic networks are now aware of movement, such as NBT-item placement, schematic placement and other means of tileentity movement and will reset/reconnect - Fixed pistons/bearings/etc not being movable by chassis - Fixed pistons/bearings/etc moving a clone of themselves when attached to the initial block - Fixed pistons/bearings/etc stopping or losing their structure when loaded incorrecly - Pulleys can now be moved while extended, moving attached ropes and their own attached structure with them - Brittle blocks such as ladders/torches/etc can no longer be moved unless their attached block is moved - Fixed mechanical pistons messing up their kinetic information when changing into a different extension state. - Fixed misplaced client code introduced by a ScreenOpener hotfix - Fixed inconsistent belt initialization when belts are placed by schematics or structures, causing them to break at random - Clutches and Gearshifts now await their turn to re-attach when changed, allowing multiple to be used in a network and swapped within one tick without causing components to break. - Fixed flexcrate interface crashing if the block gets removed while open - Some additions/modifications in texture assets - Pistons no longer get blocked by their push limit if the blocks pushed are attached to each other --- build.gradle | 2 +- .../java/com/simibubi/create/AllItems.java | 29 ++-- .../simibubi/create/AllSpecialTextures.java | 1 + .../com/simibubi/create/ScreenResources.java | 3 +- .../simibubi/create/compat/jei/CreateJEI.java | 27 ---- .../jei/category/BlastingViaFanCategory.java | 27 +--- .../jei/category/BlockCuttingCategory.java | 37 +---- .../category/BlockzapperUpgradeCategory.java | 45 +----- .../jei/category/CreateRecipeCategory.java | 106 +++++++++++++ .../compat/jei/category/CrushingCategory.java | 42 +---- .../category/MechanicalCraftingCategory.java | 32 +--- .../compat/jei/category/MillingCategory.java | 59 ++------ .../compat/jei/category/MixingCategory.java | 50 +----- .../MysteriousItemConversionCategory.java | 40 +---- .../compat/jei/category/PackingCategory.java | 40 +---- .../jei/category/PolishingCategory.java | 39 +---- .../compat/jei/category/PressingCategory.java | 49 +----- .../category/ProcessingViaFanCategory.java | 13 +- .../compat/jei/category/SawingCategory.java | 45 +----- .../jei/category/SmokingViaFanCategory.java | 27 +--- .../jei/category/SplashingCategory.java | 54 ++----- .../base/PosBoundSmartTileEntity.java | 59 ++++++++ .../behaviour/base/SmartTileEntity.java | 5 +- .../filtering/FilteringBehaviour.java | 9 +- .../behaviour/filtering/FilteringHandler.java | 8 +- .../behaviour/linked/LinkBehaviour.java | 10 ++ .../scrollvalue/ScrollValueRenderer.java | 2 + .../foundation/utility/TessellatorHelper.java | 7 +- .../utility/outliner/AABBOutline.java | 55 +++++++ .../utility/outliner/BlockClusterOutline.java | 143 ++++++++++++++++++ .../foundation/utility/outliner/Outline.java | 109 +++++++++++++ .../utility/outliner/OutlineParticle.java | 58 +++++++ .../contraptions/base/KineticBlock.java | 15 +- .../contraptions/base/KineticTileEntity.java | 46 +++++- .../contraptions/BlockMovementTraits.java | 10 +- .../contraptions/ChassisRangeDisplay.java | 63 +++++--- .../components/contraptions/Contraption.java | 74 ++++++--- .../contraptions/ContraptionEntity.java | 2 +- .../bearing/BearingContraption.java | 7 +- .../bearing/ClockworkBearingTileEntity.java | 13 +- .../bearing/ClockworkContraption.java | 5 + .../bearing/MechanicalBearingTileEntity.java | 14 +- .../chassis/ChassisTileEntity.java | 8 +- .../mounted/MountedContraption.java | 11 +- .../piston/LinearActuatorTileEntity.java | 4 +- .../piston/MechanicalPistonTileEntity.java | 8 +- .../piston/PistonContraption.java | 27 +++- .../contraptions/pulley/PulleyBlock.java | 42 ++--- .../pulley/PulleyContraption.java | 10 ++ .../contraptions/pulley/PulleyTileEntity.java | 6 +- .../sequencer/SequencedGearshiftBlock.java | 9 +- .../contraptions/relays/belt/BeltBlock.java | 8 +- .../relays/belt/BeltTileEntity.java | 38 +++-- .../relays/encased/ClutchBlock.java | 11 +- .../relays/encased/GearshiftBlock.java | 26 +++- .../curiosities/symmetry/SymmetryHandler.java | 5 +- .../block/RedstoneLinkTileEntity.java | 6 +- .../logistics/block/StockswitchBlock.java | 9 +- .../block/inventories/FlexcrateScreen.java | 6 +- src/main/resources/META-INF/mods.toml | 2 +- .../resources/assets/create/lang/de_de.json | 10 +- .../resources/assets/create/lang/en_us.json | 12 +- .../resources/assets/create/lang/fr_fr.json | 10 +- .../resources/assets/create/lang/ja_jp.lang | 10 +- .../resources/assets/create/lang/nl_nl.json | 10 +- .../resources/assets/create/lang/pt_br.json | 10 +- .../resources/assets/create/lang/ru_ru.json | 10 +- .../resources/assets/create/lang/zh_cn.json | 10 +- .../create/models/item/antioxidant.json | 6 + .../assets/create/models/item/super_glue.json | 6 + .../block/oxidized/copper_block_0.png | Bin 553 -> 294 bytes .../block/oxidized/copper_block_1.png | Bin 575 -> 294 bytes .../block/oxidized/copper_block_2.png | Bin 490 -> 294 bytes .../block/oxidized/copper_block_3.png | Bin 509 -> 294 bytes .../block/oxidized/copper_block_4.png | Bin 501 -> 294 bytes .../block/oxidized/copper_block_5.png | Bin 514 -> 294 bytes .../block/oxidized/copper_block_6.png | Bin 484 -> 294 bytes .../block/oxidized/copper_block_7.png | Bin 266 -> 294 bytes .../create/textures/gui/jei/widgets.png | Bin 4495 -> 4613 bytes .../create/textures/item/antioxidant.png | Bin 0 -> 419 bytes .../create/textures/item/super_glue.png | Bin 0 -> 393 bytes .../assets/create/textures/item/whisk.png | Bin 522 -> 473 bytes .../assets/create/textures/special/blank.png | Bin 0 -> 139 bytes .../create/textures/special/selection.png | Bin 221 -> 218 bytes .../create/recipes/crushing/glowstone.json | 20 +++ .../recipes/crushing/nether_wart_block.json | 20 +++ 86 files changed, 1089 insertions(+), 762 deletions(-) create mode 100644 src/main/java/com/simibubi/create/compat/jei/category/CreateRecipeCategory.java create mode 100644 src/main/java/com/simibubi/create/foundation/behaviour/base/PosBoundSmartTileEntity.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java create mode 100644 src/main/resources/assets/create/models/item/antioxidant.json create mode 100644 src/main/resources/assets/create/models/item/super_glue.json create mode 100644 src/main/resources/assets/create/textures/item/antioxidant.png create mode 100644 src/main/resources/assets/create/textures/item/super_glue.png create mode 100644 src/main/resources/assets/create/textures/special/blank.png create mode 100644 src/main/resources/data/create/recipes/crushing/glowstone.json create mode 100644 src/main/resources/data/create/recipes/crushing/nether_wart_block.json diff --git a/build.gradle b/build.gradle index 3b85fffed..07066a4bf 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = 'mc1.14.4_v0.2.2b' +version = 'mc1.14.4_v0.2.3' group = 'com.simibubi.create' archivesBaseName = 'create' diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index fd8034a12..24df8e14d 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -75,8 +75,8 @@ public enum AllItems { ZINC_INGOT(new TaggedItem().withForgeTags("ingots/zinc")), BRASS_INGOT(new TaggedItem().withForgeTags("ingots/brass")), - SAND_PAPER(SandPaperItem::new), - RED_SAND_PAPER(SandPaperItem::new), + FLOUR, + DOUGH, OBSIDIAN_DUST, ROSE_QUARTZ, POLISHED_ROSE_QUARTZ, @@ -86,21 +86,17 @@ public enum AllItems { ELECTRON_TUBE, INTEGRATED_CIRCUIT, - __SCHEMATICS__(module()), - EMPTY_BLUEPRINT(Item::new, stackSize(1)), - BLUEPRINT_AND_QUILL(SchematicAndQuillItem::new, stackSize(1)), - BLUEPRINT(SchematicItem::new), - __CONTRAPTIONS__(module()), BELT_CONNECTOR(BeltConnectorItem::new), VERTICAL_GEARBOX(VerticalGearboxItem::new), - FLOUR, - DOUGH, PROPELLER, WHISK, BRASS_HAND, SLOT_COVER, - ZINC_HANDLE, + SUPER_GLUE, + ANTIOXIDANT, + SAND_PAPER(SandPaperItem::new), + RED_SAND_PAPER(SandPaperItem::new), WRENCH(WrenchItem::new), GOGGLES(GogglesItem::new), @@ -114,6 +110,7 @@ public enum AllItems { TERRAIN_ZAPPER(TerrainzapperItem::new), DEFORESTER(DeforesterItem::new), SYMMETRY_WAND(SymmetryWandItem::new), + ZINC_HANDLE, BLAZING_PICKAXE(p -> new BlazingToolItem(1, -2.8F, p, PICKAXE)), BLAZING_SHOVEL(p -> new BlazingToolItem(1.5F, -3.0F, p, SHOVEL)), @@ -129,6 +126,11 @@ public enum AllItems { SHADOW_STEEL_MATTOCK(p -> new ShadowSteelToolItem(2.5F, -1.5F, p, SHOVEL, AXE, HOE)), SHADOW_STEEL_SWORD(p -> new SwordItem(AllToolTiers.SHADOW_STEEL, 3, -2.0F, p)), + __SCHEMATICS__(module()), + EMPTY_BLUEPRINT(Item::new, stackSize(1)), + BLUEPRINT_AND_QUILL(SchematicAndQuillItem::new, stackSize(1)), + BLUEPRINT(SchematicItem::new), + ; private static class CategoryTracker { @@ -197,7 +199,8 @@ public enum AllItems { continue; entry.item = entry.taggedItem.getItemSupplier().apply(new Properties()); - entry.item = entry.taggedItem.getItemSupplier().apply(entry.specialProperties.apply(defaultProperties(entry))); + entry.item = + entry.taggedItem.getItemSupplier().apply(entry.specialProperties.apply(defaultProperties(entry))); entry.item.setRegistryName(Create.ID, Lang.asId(entry.name())); registry.register(entry.item); } @@ -226,11 +229,11 @@ public enum AllItems { private Set tagSetItem = new HashSet<>(); private Function itemSupplier; - public TaggedItem(){ + public TaggedItem() { this(Item::new); } - public TaggedItem(Function itemSupplierIn){ + public TaggedItem(Function itemSupplierIn) { this.itemSupplier = itemSupplierIn; } diff --git a/src/main/java/com/simibubi/create/AllSpecialTextures.java b/src/main/java/com/simibubi/create/AllSpecialTextures.java index 67aa34421..e8a3f15fa 100644 --- a/src/main/java/com/simibubi/create/AllSpecialTextures.java +++ b/src/main/java/com/simibubi/create/AllSpecialTextures.java @@ -8,6 +8,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber(value = Dist.CLIENT) public enum AllSpecialTextures { + BLANK("blank.png"), SELECTION("selection.png"), ; diff --git a/src/main/java/com/simibubi/create/ScreenResources.java b/src/main/java/com/simibubi/create/ScreenResources.java index 307b26599..3270590ab 100644 --- a/src/main/java/com/simibubi/create/ScreenResources.java +++ b/src/main/java/com/simibubi/create/ScreenResources.java @@ -41,7 +41,7 @@ public enum ScreenResources { FILTER("filter.png", 200, 100), ATTRIBUTE_FILTER("filter.png", 0, 100, 200, 86), - + SEQUENCER("sequencer.png", 156, 128), SEQUENCER_INSTRUCTION("sequencer.png", 14, 47, 131, 18), SEQUENCER_WAIT("sequencer.png", 14, 65, 131, 18), @@ -79,6 +79,7 @@ public enum ScreenResources { // JEI JEI_SLOT("jei/widgets.png", 18, 18), + JEI_CHANCE_SLOT("jei/widgets.png", 20, 156, 18, 18), JEI_CATALYST_SLOT("jei/widgets.png", 0, 156, 18, 18), JEI_ARROW("jei/widgets.png", 19, 10, 42, 10), JEI_LONG_ARROW("jei/widgets.png", 19, 0, 71, 10), diff --git a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java index 4bbf9f277..ff99bd785 100644 --- a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java +++ b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java @@ -1,7 +1,6 @@ package com.simibubi.create.compat.jei; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import com.google.common.base.Predicate; @@ -28,13 +27,11 @@ import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCraftingRecipe; import com.simibubi.create.modules.contraptions.components.mixer.MixingRecipe; import com.simibubi.create.modules.contraptions.components.press.MechanicalPressTileEntity; -import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen; import com.simibubi.create.modules.schematics.block.SchematicannonScreen; import mezz.jei.api.IModPlugin; import mezz.jei.api.JeiPlugin; -import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.registration.IGuiHandlerRegistration; import mezz.jei.api.registration.IRecipeCatalystRegistration; import mezz.jei.api.registration.IRecipeCategoryRegistration; @@ -226,28 +223,4 @@ public class CreateJEI implements IModPlugin { return byType; } - public static void addStochasticTooltip(IGuiItemStackGroup itemStacks, List results) { - itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> { - if (input) - return; - ProcessingOutput output = results.get(slotIndex - 1); - if (output.getChance() != 1) - tooltip.add(1, TextFormatting.GOLD - + Lang.translate("recipe.processing.chance", (int) (output.getChance() * 100))); - }); - } - - public static void addCatalystTooltip(IGuiItemStackGroup itemStacks, Map catalystIndices) { - itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> { - if (!input) - return; - if (!catalystIndices.containsKey(slotIndex)) - return; - Float chance = catalystIndices.get(slotIndex); - tooltip.add(1, TextFormatting.YELLOW + Lang.translate("recipe.processing.catalyst")); - tooltip.add(2, TextFormatting.GOLD - + Lang.translate("recipe.processing.chanceToReturn", (int) (chance.floatValue() * 100))); - }); - } - } diff --git a/src/main/java/com/simibubi/create/compat/jei/category/BlastingViaFanCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/BlastingViaFanCategory.java index a2970b286..e791f6637 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/BlastingViaFanCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/BlastingViaFanCategory.java @@ -2,38 +2,18 @@ package com.simibubi.create.compat.jei.category; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllItems; -import com.simibubi.create.Create; -import com.simibubi.create.compat.jei.DoubleItemIcon; import com.simibubi.create.foundation.gui.ScreenElementRenderer; -import com.simibubi.create.foundation.utility.Lang; -import mezz.jei.api.gui.drawable.IDrawable; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.FlowingFluidBlock; -import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.item.crafting.AbstractCookingRecipe; -import net.minecraft.util.ResourceLocation; public class BlastingViaFanCategory extends ProcessingViaFanCategory { - private static ResourceLocation ID = new ResourceLocation(Create.ID, "blasting_via_fan"); - private IDrawable icon; - public BlastingViaFanCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PROPELLER.get()), - () -> new ItemStack(Items.LAVA_BUCKET)); - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("blasting_via_fan", doubleItemIcon(AllItems.PROPELLER.get(), Items.LAVA_BUCKET)); } @Override @@ -41,11 +21,6 @@ public class BlastingViaFanCategory extends ProcessingViaFanCategory { +public class BlockCuttingCategory extends CreateRecipeCategory { - private AnimatedSaw saw; - private static ResourceLocation ID = new ResourceLocation(Create.ID, "block_cutting"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 70); + private AnimatedSaw saw = new AnimatedSaw(); public BlockCuttingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.SAW.get()), - () -> new ItemStack(Items.STONE_BRICK_STAIRS)); - saw = new AnimatedSaw(); - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("block_cutting", doubleItemIcon(AllBlocks.SAW.get(), Items.STONE_BRICK_STAIRS), emptyBackground(177, 70)); } @Override @@ -55,16 +34,6 @@ public class BlockCuttingCategory implements IRecipeCategory { - - private static ResourceLocation ID = new ResourceLocation(Create.ID, "blockzapper_upgrade"); - private IDrawable icon; +public class BlockzapperUpgradeCategory extends CreateRecipeCategory { public BlockzapperUpgradeCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PLACEMENT_HANDGUN.get()), - () -> ItemStack.EMPTY); // replace with uparrow when available - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("blockzapper_upgrade", itemIcon(AllItems.PLACEMENT_HANDGUN.get()), + new ScreenResourceWrapper(BLOCKZAPPER_UPGRADE_RECIPE)); } @Override @@ -57,16 +38,6 @@ public class BlockzapperUpgradeCategory implements IRecipeCategory> implements IRecipeCategory { + + private ResourceLocation uid; + private String name; + private IDrawable icon; + private IDrawable background; + + public CreateRecipeCategory(String id, IDrawable icon, IDrawable background) { + uid = new ResourceLocation(Create.ID, id); + name = id; + this.background = background; + this.icon = icon; + } + + @Override + public IDrawable getIcon() { + return icon; + } + + @Override + public ResourceLocation getUid() { + return uid; + } + + @Override + public String getTitle() { + return Lang.translate("recipe." + name); + } + + @Override + public IDrawable getBackground() { + return background; + } + + protected static ScreenResources getRenderedSlot(IRecipe recipe, int index) { + ScreenResources jeiSlot = ScreenResources.JEI_SLOT; + if (!(recipe instanceof ProcessingRecipe)) + return jeiSlot; + ProcessingRecipe processingRecipe = (ProcessingRecipe) recipe; + List rollableResults = processingRecipe.getRollableResults(); + if (rollableResults.size() <= index) + return jeiSlot; + if (processingRecipe.getRollableResults().get(index).getChance() == 1) + return jeiSlot; + return ScreenResources.JEI_CHANCE_SLOT; + } + + protected static IDrawable emptyBackground(int width, int height) { + return new EmptyBackground(width, height); + } + + protected static IDrawable doubleItemIcon(IItemProvider item1, IItemProvider item2) { + return new DoubleItemIcon(() -> new ItemStack(item1), () -> new ItemStack(item2)); + } + + protected static IDrawable itemIcon(IItemProvider item) { + return new DoubleItemIcon(() -> new ItemStack(item), () -> ItemStack.EMPTY); + } + + protected static void addStochasticTooltip(IGuiItemStackGroup itemStacks, List results) { + itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> { + if (input) + return; + ProcessingOutput output = results.get(slotIndex - 1); + if (output.getChance() != 1) + tooltip.add(1, TextFormatting.GOLD + + Lang.translate("recipe.processing.chance", (int) (output.getChance() * 100))); + }); + } + + protected static void addCatalystTooltip(IGuiItemStackGroup itemStacks, Map catalystIndices) { + itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> { + if (!input) + return; + if (!catalystIndices.containsKey(slotIndex)) + return; + Float chance = catalystIndices.get(slotIndex); + tooltip.add(1, TextFormatting.YELLOW + Lang.translate("recipe.processing.catalyst")); + tooltip.add(2, TextFormatting.GOLD + + Lang.translate("recipe.processing.chanceToReturn", (int) (chance.floatValue() * 100))); + }); + } + +} diff --git a/src/main/java/com/simibubi/create/compat/jei/category/CrushingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/CrushingCategory.java index 2b4bdc07a..0b2fb2238 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/CrushingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/CrushingCategory.java @@ -5,45 +5,23 @@ import java.util.List; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.CreateJEI; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.compat.jei.category.animations.AnimatedCrushingWheels; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.crusher.AbstractCrushingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -public class CrushingCategory implements IRecipeCategory { +public class CrushingCategory extends CreateRecipeCategory { - private static ResourceLocation ID = new ResourceLocation(Create.ID, "crushing"); private AnimatedCrushingWheels crushingWheels = new AnimatedCrushingWheels(); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 100); public CrushingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.CRUSHING_WHEEL.get()), - () -> new ItemStack(AllItems.CRUSHED_GOLD.get())); - } - - @Override - public IDrawable getBackground() { - return background; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("crushing", doubleItemIcon(AllBlocks.CRUSHING_WHEEL.get(), AllItems.CRUSHED_GOLD.get()), + emptyBackground(177, 100)); } @Override @@ -51,16 +29,6 @@ public class CrushingCategory implements IRecipeCategory return AbstractCrushingRecipe.class; } - @Override - public String getTitle() { - return Lang.translate("recipe.crushing"); - } - - @Override - public IDrawable getIcon() { - return icon; - } - @Override public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); @@ -81,7 +49,7 @@ public class CrushingCategory implements IRecipeCategory itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack()); } - CreateJEI.addStochasticTooltip(itemStacks, results); + addStochasticTooltip(itemStacks, results); } @Override @@ -93,7 +61,7 @@ public class CrushingCategory implements IRecipeCategory int size = results.size(); int offset = -size * 19 / 2; for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) - ScreenResources.JEI_SLOT.draw(getBackground().getWidth() / 2 + offset + 19 * outputIndex, 78); + getRenderedSlot(recipe, outputIndex).draw(getBackground().getWidth() / 2 + offset + 19 * outputIndex, 78); crushingWheels.draw(92, 49); } 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 9ee140650..9d6406833 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 @@ -3,65 +3,39 @@ package com.simibubi.create.compat.jei.category; import java.util.Arrays; import com.simibubi.create.AllBlocks; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.compat.jei.category.animations.AnimatedCrafter; import com.simibubi.create.foundation.utility.Lang; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; -import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; import net.minecraft.item.crafting.ShapedRecipe; import net.minecraft.util.NonNullList; -import net.minecraft.util.ResourceLocation; -public class MechanicalCraftingCategory implements IRecipeCategory { +public class MechanicalCraftingCategory extends CreateRecipeCategory { private AnimatedCrafter crafter; - private ResourceLocation id; - private IDrawable icon; - private IDrawable background; private boolean large; public MechanicalCraftingCategory(boolean large) { + super("mechanical_crafting" + (large ? "_large" : ""), itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()), + emptyBackground(large ? 177 : 177, large ? 235 : 81)); this.large = large; - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()), () -> ItemStack.EMPTY); crafter = new AnimatedCrafter(large); - id = new ResourceLocation(Create.ID, "mechanical_crafting" + (large ? "_large" : "")); - background = new EmptyBackground(large ? 177 : 177, large ? 235 : 81); } public static boolean isSmall(ShapedRecipe recipe) { return Math.max((recipe).getWidth(), (recipe).getHeight()) <= 4; } - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return id; - } - @Override public String getTitle() { return Lang.translate("recipe.mechanical_crafting"); } - @Override - public IDrawable getBackground() { - return background; - } - @Override public void setIngredients(ShapedRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MillingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MillingCategory.java index 25a555411..86e0b9b23 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MillingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MillingCategory.java @@ -5,45 +5,22 @@ import java.util.List; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.CreateJEI; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.compat.jei.category.animations.AnimatedMillstone; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.crusher.AbstractCrushingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -public class MillingCategory implements IRecipeCategory { +public class MillingCategory extends CreateRecipeCategory { - private static ResourceLocation ID = new ResourceLocation(Create.ID, "milling"); private AnimatedMillstone millstone = new AnimatedMillstone(); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 53); public MillingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MILLSTONE.get()), - () -> new ItemStack(AllItems.FLOUR.get())); - } - - @Override - public IDrawable getBackground() { - return background; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("milling", doubleItemIcon(AllBlocks.MILLSTONE.get(), AllItems.FLOUR.get()), emptyBackground(177, 53)); } @Override @@ -51,16 +28,6 @@ public class MillingCategory implements IRecipeCategory return AbstractCrushingRecipe.class; } - @Override - public String getTitle() { - return Lang.translate("recipe.milling"); - } - - @Override - public IDrawable getIcon() { - return icon; - } - @Override public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); @@ -83,7 +50,7 @@ public class MillingCategory implements IRecipeCategory itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack()); } - CreateJEI.addStochasticTooltip(itemStacks, results); + addStochasticTooltip(itemStacks, results); } @Override @@ -95,17 +62,19 @@ public class MillingCategory implements IRecipeCategory ScreenResources.JEI_ARROW.draw(85, 32); ScreenResources.JEI_DOWN_ARROW.draw(43, 4); - if (size > 1) { - for (int i = 0; i < size; i++) { - int xOffset = i % 2 == 0 ? 0 : 19; - int yOffset = (i / 2) * -19; - ScreenResources.JEI_SLOT.draw(133 + xOffset, 27 + yOffset); - } - } else { - ScreenResources.JEI_SLOT.draw(139, 27); + millstone.draw(57, 27); + + if (size == 1) { + getRenderedSlot(recipe, 0).draw(139, 27); + return; + } + + for (int i = 0; i < size; i++) { + int xOffset = i % 2 == 0 ? 0 : 19; + int yOffset = (i / 2) * -19; + getRenderedSlot(recipe, i).draw(133 + xOffset, 27 + yOffset); } - millstone.draw(57, 27); } } diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java index 00342dcb7..65e165a19 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java @@ -10,59 +10,32 @@ import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.CreateJEI; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.compat.jei.category.animations.AnimatedMixer; import com.simibubi.create.foundation.item.ItemHelper; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.mixer.MixingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.NonNullList; -import net.minecraft.util.ResourceLocation; -public class MixingCategory implements IRecipeCategory { +public class MixingCategory extends CreateRecipeCategory { - private AnimatedMixer mixer; - private static ResourceLocation ID = new ResourceLocation(Create.ID, "mixing"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 70); + private AnimatedMixer mixer = new AnimatedMixer(); public MixingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_MIXER.get()), - () -> new ItemStack(AllBlocks.BASIN.get())); - mixer = new AnimatedMixer(); + super("mixing", doubleItemIcon(AllBlocks.MECHANICAL_MIXER.get(), AllBlocks.BASIN.get()), + emptyBackground(177, 70)); } @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; - } - - @Override - public String getTitle() { - return Lang.translate("recipe.mixing"); - } - - @Override - public IDrawable getBackground() { - return background; + public Class getRecipeClass() { + return MixingRecipe.class; } @Override @@ -77,7 +50,7 @@ public class MixingCategory implements IRecipeCategory { NonNullList recipeIngredients = recipe.getIngredients(); List> actualIngredients = ItemHelper.condenseIngredients(recipeIngredients); - + Map catalystIndices = new HashMap<>(9); for (int i = 0; i < actualIngredients.size(); i++) { for (ProcessingIngredient processingIngredient : recipe.getRollableIngredients()) { @@ -107,13 +80,11 @@ public class MixingCategory implements IRecipeCategory { itemStacks.init(i, false, 141, 50); itemStacks.set(i, recipe.getRecipeOutput().getStack()); - CreateJEI.addCatalystTooltip(itemStacks, catalystIndices); + addCatalystTooltip(itemStacks, catalystIndices); } @Override public void draw(MixingRecipe recipe, double mouseX, double mouseY) { - // this might actually be pretty bad with big ingredients. ^ its a draw method - List> actualIngredients = ItemHelper.condenseIngredients(recipe.getIngredients()); int size = actualIngredients.size(); @@ -135,9 +106,4 @@ public class MixingCategory implements IRecipeCategory { mixer.draw(getBackground().getWidth() / 2 + 20, 8); } - @Override - public Class getRecipeClass() { - return MixingRecipe.class; - } - } diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MysteriousItemConversionCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MysteriousItemConversionCategory.java index 85277b79f..5dca137a5 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MysteriousItemConversionCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MysteriousItemConversionCategory.java @@ -5,29 +5,16 @@ import java.util.Arrays; import java.util.List; import com.simibubi.create.AllItems; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; import com.simibubi.create.compat.jei.ConversionRecipe; -import com.simibubi.create.compat.jei.CreateJEI; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -public class MysteriousItemConversionCategory implements IRecipeCategory { - - private static ResourceLocation ID = new ResourceLocation(Create.ID, "mystery_conversion"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 50); +public class MysteriousItemConversionCategory extends CreateRecipeCategory { public static List getRecipes() { List recipes = new ArrayList<>(); @@ -37,17 +24,7 @@ public class MysteriousItemConversionCategory implements IRecipeCategory AllItems.CHROMATIC_COMPOUND.asStack(), () -> ItemStack.EMPTY); - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("mystery_conversion", itemIcon(AllItems.CHROMATIC_COMPOUND.get()), emptyBackground(177, 50)); } @Override @@ -55,16 +32,6 @@ public class MysteriousItemConversionCategory implements IRecipeCategory results = recipe.getRollableResults(); - itemStacks.init(0, true, 26, 16); itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks())); itemStacks.init(1, false, 131, 16); itemStacks.set(1, results.get(0).getStack()); - - CreateJEI.addStochasticTooltip(itemStacks, results); } @Override diff --git a/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java index c7c0f7bad..90b1d180f 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java @@ -3,47 +3,25 @@ package com.simibubi.create.compat.jei.category; import java.util.Arrays; import com.simibubi.create.AllBlocks; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.compat.jei.category.animations.AnimatedPress; -import com.simibubi.create.foundation.utility.Lang; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; -import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.ICraftingRecipe; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.NonNullList; -import net.minecraft.util.ResourceLocation; -public class PackingCategory implements IRecipeCategory> { +public class PackingCategory extends CreateRecipeCategory> { - private AnimatedPress press; - private static ResourceLocation ID = new ResourceLocation(Create.ID, "packing"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 70); + private AnimatedPress press = new AnimatedPress(true); public PackingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_PRESS.get()), - () -> new ItemStack(AllBlocks.BASIN.get())); - press = new AnimatedPress(true); - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("packing", doubleItemIcon(AllBlocks.MECHANICAL_PRESS.get(), AllBlocks.BASIN.get()), + emptyBackground(177, 70)); } @Override @@ -51,16 +29,6 @@ public class PackingCategory implements IRecipeCategory> { return ICraftingRecipe.class; } - @Override - public String getTitle() { - return Lang.translate("recipe.packing"); - } - - @Override - public IDrawable getBackground() { - return background; - } - @Override public void setIngredients(IRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java index a12209cb7..fa1834570 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java @@ -5,66 +5,35 @@ import java.util.List; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllItems; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.CreateJEI; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import com.simibubi.create.modules.curiosities.tools.SandPaperPolishingRecipe; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemRenderer; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.NonNullList; -import net.minecraft.util.ResourceLocation; -public class PolishingCategory implements IRecipeCategory { +public class PolishingCategory extends CreateRecipeCategory { - private static ResourceLocation ID = new ResourceLocation(Create.ID, "sandpaper_polishing"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 55); private ItemStack renderedSandpaper; public PolishingCategory() { - icon = new DoubleItemIcon(() -> AllItems.SAND_PAPER.asStack(), () -> ItemStack.EMPTY); + super("sandpaper_polishing", itemIcon(AllItems.SAND_PAPER.get()), emptyBackground(177, 55)); renderedSandpaper = AllItems.SAND_PAPER.asStack(); } - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; - } - @Override public Class getRecipeClass() { return SandPaperPolishingRecipe.class; } - @Override - public String getTitle() { - return Lang.translate("recipe.sandpaper_polishing"); - } - - @Override - public IDrawable getBackground() { - return background; - } - @Override public void setIngredients(SandPaperPolishingRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); @@ -81,13 +50,13 @@ public class PolishingCategory implements IRecipeCategory { +public class PressingCategory extends CreateRecipeCategory { - private AnimatedPress press; - private static ResourceLocation ID = new ResourceLocation(Create.ID, "pressing"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 70); + private AnimatedPress press = new AnimatedPress(false); public PressingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.MECHANICAL_PRESS.get()), - () -> new ItemStack(AllItems.IRON_SHEET.get())); - press = new AnimatedPress(false); - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("pressing", doubleItemIcon(AllBlocks.MECHANICAL_PRESS.get(), AllItems.IRON_SHEET.get()), + emptyBackground(177, 70)); } @Override @@ -52,16 +29,6 @@ public class PressingCategory implements IRecipeCategory { return PressingRecipe.class; } - @Override - public String getTitle() { - return Lang.translate("recipe.pressing"); - } - - @Override - public IDrawable getBackground() { - return background; - } - @Override public void setIngredients(PressingRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); @@ -79,16 +46,16 @@ public class PressingCategory implements IRecipeCategory { itemStacks.init(outputIndex + 1, false, 131 + 19 * outputIndex, 50); itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack()); } - - CreateJEI.addStochasticTooltip(itemStacks, results); + + addStochasticTooltip(itemStacks, results); } @Override public void draw(PressingRecipe recipe, double mouseX, double mouseY) { ScreenResources.JEI_SLOT.draw(26, 50); - ScreenResources.JEI_SLOT.draw(131, 50); + getRenderedSlot(recipe, 0).draw(131, 50); if (recipe.getRollableResults().size() > 1) - ScreenResources.JEI_SLOT.draw(131 + 19, 50); + getRenderedSlot(recipe, 1).draw(131 + 19, 50); ScreenResources.JEI_SHADOW.draw(61, 41); ScreenResources.JEI_LONG_ARROW.draw(52, 54); press.draw(getBackground().getWidth() / 2, 8); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/ProcessingViaFanCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/ProcessingViaFanCategory.java index cd3d0ff7c..4ac5715d5 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/ProcessingViaFanCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/ProcessingViaFanCategory.java @@ -6,7 +6,6 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlocks; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics; import com.simibubi.create.foundation.gui.ScreenElementRenderer; @@ -15,22 +14,18 @@ import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.item.crafting.IRecipe; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; -public abstract class ProcessingViaFanCategory> implements IRecipeCategory { +public abstract class ProcessingViaFanCategory> extends CreateRecipeCategory { - private IDrawable background = new EmptyBackground(177, 70); - - @Override - public IDrawable getBackground() { - return background; + public ProcessingViaFanCategory(String name, IDrawable icon) { + super(name, icon, emptyBackground(177, 70)); } - + @Override public void setIngredients(T recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/SawingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/SawingCategory.java index 7a42a14ae..b0a17e4c2 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/SawingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/SawingCategory.java @@ -4,46 +4,23 @@ import java.util.Arrays; import java.util.List; import com.simibubi.create.AllBlocks; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.CreateJEI; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.compat.jei.category.animations.AnimatedSaw; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.saw.CuttingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.category.IRecipeCategory; -import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.util.ResourceLocation; -public class SawingCategory implements IRecipeCategory { +public class SawingCategory extends CreateRecipeCategory { - private AnimatedSaw saw; - private static ResourceLocation ID = new ResourceLocation(Create.ID, "sawing"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 70); + private AnimatedSaw saw = new AnimatedSaw(); public SawingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllBlocks.SAW.get()), () -> new ItemStack(Items.OAK_LOG)); - saw = new AnimatedSaw(); - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("sawing", doubleItemIcon(AllBlocks.SAW.get(), Items.OAK_LOG), emptyBackground(177, 70)); } @Override @@ -51,16 +28,6 @@ public class SawingCategory implements IRecipeCategory { return CuttingRecipe.class; } - @Override - public String getTitle() { - return Lang.translate("recipe.sawing"); - } - - @Override - public IDrawable getBackground() { - return background; - } - @Override public void setIngredients(CuttingRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); @@ -81,8 +48,8 @@ public class SawingCategory implements IRecipeCategory { itemStacks.init(outputIndex + 1, false, 117 + xOffset, 47 + yOffset); itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack()); } - - CreateJEI.addStochasticTooltip(itemStacks, results); + + addStochasticTooltip(itemStacks, results); } @Override @@ -92,7 +59,7 @@ public class SawingCategory implements IRecipeCategory { for (int i = 0; i < size; i++) { int xOffset = i % 2 == 0 ? 0 : 19; int yOffset = (i / 2) * -19; - ScreenResources.JEI_SLOT.draw(117 + xOffset, 47 + yOffset); + getRenderedSlot(recipe, i).draw(117 + xOffset, 47 + yOffset); } ScreenResources.JEI_DOWN_ARROW.draw(70, 6); ScreenResources.JEI_SHADOW.draw(58, 55); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/SmokingViaFanCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/SmokingViaFanCategory.java index 1444881d9..1ddd16611 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/SmokingViaFanCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/SmokingViaFanCategory.java @@ -1,36 +1,16 @@ package com.simibubi.create.compat.jei.category; import com.simibubi.create.AllItems; -import com.simibubi.create.Create; -import com.simibubi.create.compat.jei.DoubleItemIcon; import com.simibubi.create.foundation.gui.ScreenElementRenderer; -import com.simibubi.create.foundation.utility.Lang; -import mezz.jei.api.gui.drawable.IDrawable; import net.minecraft.block.Blocks; -import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.item.crafting.SmokingRecipe; -import net.minecraft.util.ResourceLocation; public class SmokingViaFanCategory extends ProcessingViaFanCategory { - private static ResourceLocation ID = new ResourceLocation(Create.ID, "smoking_via_fan"); - private IDrawable icon; - public SmokingViaFanCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PROPELLER.get()), - () -> new ItemStack(Items.BLAZE_POWDER)); - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("smoking_via_fan", doubleItemIcon(AllItems.PROPELLER.get(), Items.BLAZE_POWDER)); } @Override @@ -38,11 +18,6 @@ public class SmokingViaFanCategory extends ProcessingViaFanCategory Blocks.FIRE.getDefaultState()); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/SplashingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/SplashingCategory.java index fbf53fac5..df073ecc4 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/SplashingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/SplashingCategory.java @@ -5,52 +5,24 @@ import java.util.List; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllItems; -import com.simibubi.create.Create; import com.simibubi.create.ScreenResources; -import com.simibubi.create.compat.jei.CreateJEI; -import com.simibubi.create.compat.jei.DoubleItemIcon; -import com.simibubi.create.compat.jei.EmptyBackground; import com.simibubi.create.foundation.gui.ScreenElementRenderer; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.fan.SplashingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.FlowingFluidBlock; -import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.util.ResourceLocation; public class SplashingCategory extends ProcessingViaFanCategory { - private static ResourceLocation ID = new ResourceLocation(Create.ID, "splashing"); - private IDrawable icon; - private IDrawable background = new EmptyBackground(177, 70); - public SplashingCategory() { - icon = new DoubleItemIcon(() -> new ItemStack(AllItems.PROPELLER.get()), - () -> new ItemStack(Items.WATER_BUCKET)); - } - - @Override - public IDrawable getBackground() { - return background; - } - - @Override - public IDrawable getIcon() { - return icon; - } - - @Override - public ResourceLocation getUid() { - return ID; + super("splashing", doubleItemIcon(AllItems.PROPELLER.get(), Items.WATER_BUCKET)); } @Override @@ -58,11 +30,6 @@ public class SplashingCategory extends ProcessingViaFanCategory return SplashingRecipe.class; } - @Override - public String getTitle() { - return Lang.translate("recipe.splashing"); - } - @Override public void setIngredients(SplashingRecipe recipe, IIngredients ingredients) { ingredients.setInputIngredients(recipe.getIngredients()); @@ -85,7 +52,7 @@ public class SplashingCategory extends ProcessingViaFanCategory itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack()); } - CreateJEI.addStochasticTooltip(itemStacks, results); + addStochasticTooltip(itemStacks, results); } @Override @@ -97,14 +64,15 @@ public class SplashingCategory extends ProcessingViaFanCategory ScreenResources.JEI_SHADOW.draw(66, 39); ScreenResources.JEI_LONG_ARROW.draw(53, 51); - if (size > 1) { - for (int i = 0; i < size; i++) { - int xOffset = i % 2 == 0 ? 0 : 19; - int yOffset = (i / 2) * -19; - ScreenResources.JEI_SLOT.draw(133 + xOffset, 47 + yOffset); - } - } else { - ScreenResources.JEI_SLOT.draw(139, 47); + if (size == 1) { + getRenderedSlot(recipe, 0).draw(139, 47); + return; + } + + for (int i = 0; i < size; i++) { + int xOffset = i % 2 == 0 ? 0 : 19; + int yOffset = (i / 2) * -19; + getRenderedSlot(recipe, i).draw(133 + xOffset, 47 + yOffset); } } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/base/PosBoundSmartTileEntity.java b/src/main/java/com/simibubi/create/foundation/behaviour/base/PosBoundSmartTileEntity.java new file mode 100644 index 000000000..4bd838015 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/base/PosBoundSmartTileEntity.java @@ -0,0 +1,59 @@ +package com.simibubi.create.foundation.behaviour.base; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.math.BlockPos; + +public abstract class PosBoundSmartTileEntity extends SmartTileEntity { + + private boolean newPositionVisited; + + public PosBoundSmartTileEntity(TileEntityType tileEntityTypeIn) { + super(tileEntityTypeIn); + newPositionVisited = true; + } + + @Override + public void initialize() { + if (!world.isRemote && newPositionVisited) { + newPositionVisited = false; + initInNewPosition(); + } + super.initialize(); + } + + @Override + public void read(CompoundNBT compound) { + long positionInTag = new BlockPos(compound.getInt("x"), compound.getInt("y"), compound.getInt("z")).toLong(); + long positionKey = compound.getLong("BoundPosition"); + + newPositionVisited = false; + if (!hasWorld() || !world.isRemote) { + if (positionInTag != positionKey) { + removePositionDependentData(compound); + newPositionVisited = true; + } + } + + super.read(compound); + } + + /** + * Server-only. When this TE realizes, that it's reading its tag in a different + * position, it should remove all position dependent information here. + * + * @param nbt + */ + protected void removePositionDependentData(CompoundNBT nbt) { + + } + + /** + * Server-only. When a TE has been created or moved, it will call this before the + * regular init. + */ + protected void initInNewPosition() { + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/base/SmartTileEntity.java b/src/main/java/com/simibubi/create/foundation/behaviour/base/SmartTileEntity.java index fd761ff30..5ce414b0e 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/base/SmartTileEntity.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/base/SmartTileEntity.java @@ -86,8 +86,9 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka list.forEach(b -> behaviours.put(b.getType(), b)); } - forEachBehaviour(tb -> tb.readNBT(compound)); super.read(compound); + forEachBehaviour(tb -> tb.readNBT(compound)); + if (world != null && world.isRemote) updateClient(compound); } @@ -106,7 +107,7 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka public void lazyTick() { } - + protected void forEachBehaviour(Consumer action) { behaviours.values().forEach(tb -> { if (!tb.isPaused()) diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java index 82fa386e5..901ff7c8e 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java @@ -39,8 +39,7 @@ public class FilteringBehaviour extends TileEntityBehaviour { filter = ItemStack.EMPTY; slotPositioning = slot; showCount = false; - callback = stack -> { - }; + callback = stack -> {}; textShift = Vec3d.ZERO; count = 0; ticksUntilScrollPacket = -1; @@ -114,11 +113,7 @@ public class FilteringBehaviour extends TileEntityBehaviour { public void setFilter(ItemStack stack) { filter = stack.copy(); callback.accept(filter); - - if (filter.getItem() instanceof FilterItem) - count = 0; - else - count = stack.getCount(); + count = (filter.getItem() instanceof FilterItem) ? 0 : Math.min(stack.getCount(), stack.getMaxStackSize()); forceClientState = true; tileEntity.markDirty(); diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringHandler.java b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringHandler.java index 1fa219809..215f5355e 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringHandler.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringHandler.java @@ -87,12 +87,14 @@ public class FilteringHandler { return false; if (!filtering.testHit(objectMouseOver.getHitVec())) return false; - if (filtering.getFilter().isEmpty()) + ItemStack filterItem = filtering.getFilter(); + if (filterItem.isEmpty()) return false; filtering.ticksUntilScrollPacket = 10; - filtering.scrollableValue = (int) MathHelper - .clamp(filtering.scrollableValue + delta * (AllKeys.ctrlDown() ? 16 : 1), 0, 64); + int maxAmount = (filterItem.getItem() instanceof FilterItem) ? 64 : filterItem.getMaxStackSize(); + filtering.scrollableValue = + (int) MathHelper.clamp(filtering.scrollableValue + delta * (AllKeys.ctrlDown() ? 16 : 1), 0, maxAmount); return true; } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java index 1a3310a6c..10677554e 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java @@ -34,6 +34,7 @@ public class LinkBehaviour extends TileEntityBehaviour { ValueBoxTransform secondSlot; Vec3d textShift; + public boolean newPosition; private Mode mode; private Supplier transmission; private Consumer signalCallback; @@ -45,6 +46,7 @@ public class LinkBehaviour extends TileEntityBehaviour { firstSlot = slots.getLeft(); secondSlot = slots.getRight(); textShift = Vec3d.ZERO; + newPosition = true; } public static LinkBehaviour receiver(SmartTileEntity te, Pair slots, @@ -84,6 +86,8 @@ public class LinkBehaviour extends TileEntityBehaviour { } public void updateReceiver(boolean networkPowered) { + if (!newPosition) + return; signalCallback.accept(networkPowered); } @@ -97,6 +101,7 @@ public class LinkBehaviour extends TileEntityBehaviour { if (tileEntity.getWorld().isRemote) return; getHandler().addToNetwork(this); + newPosition = true; } public Pair getNetworkKey() { @@ -116,10 +121,15 @@ public class LinkBehaviour extends TileEntityBehaviour { super.writeNBT(compound); compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT())); compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT())); + compound.putLong("LastKnownPosition", tileEntity.getPos().toLong()); } @Override public void readNBT(CompoundNBT compound) { + long positionInTag = tileEntity.getPos().toLong(); + long positionKey = compound.getLong("LastKnownPosition"); + newPosition = positionInTag != positionKey; + super.readNBT(compound); frequencyFirst = new Frequency(ItemStack.read(compound.getCompound("FrequencyFirst"))); frequencyLast = new Frequency(ItemStack.read(compound.getCompound("FrequencyLast"))); diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java index 35b4263af..212634da5 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java @@ -61,6 +61,8 @@ public class ScrollValueRenderer { } else render(world, pos, face, behaviour, highlight); TessellatorHelper.cleanUpAfterDrawing(); + GlStateManager.enableAlphaTest(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); } protected static void render(ClientWorld world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour, diff --git a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java index 904c55da3..724452f80 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java @@ -23,7 +23,6 @@ public class TessellatorHelper { GlStateManager.pushMatrix(); GlStateManager.pushLightingAttributes(); GlStateManager.enableBlend(); - GlStateManager.enableAlphaTest(); GlStateManager.color4f(1, 1, 1, 1); ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo(); @@ -45,7 +44,7 @@ public class TessellatorHelper { GlStateManager.color3f(1, 1, 1); } - + public static void fightZFighting(int id) { long randomBits = (long) id * 493286711L; randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L; @@ -68,10 +67,10 @@ public class TessellatorHelper { } public static void cleanUpAfterDrawing() { - GlStateManager.disableAlphaTest(); - GlStateManager.disableBlend(); GlStateManager.popAttributes(); GlStateManager.popMatrix(); + GlStateManager.disableAlphaTest(); + GlStateManager.disableBlend(); } public static void drawString(String str, float x, float y, float z, boolean scalesUp, boolean hasDepth) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java new file mode 100644 index 000000000..da9ab87dd --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java @@ -0,0 +1,55 @@ +package com.simibubi.create.foundation.utility.outliner; + +import com.simibubi.create.AllSpecialTextures; +import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class AABBOutline extends Outline { + + private AxisAlignedBB bb = new AxisAlignedBB(new BlockPos(25, 70, 90)).expand(0, 1, 0); + + @Override + public void render(BufferBuilder buffer) { + begin(); + + Vec3d color = ColorHelper.getRGB(0xFFFFFF); + float alpha = 1f; + + AllSpecialTextures.BLANK.bind(); + Vec3d xyz = new Vec3d(bb.minX, bb.minY, bb.minZ); + Vec3d Xyz = new Vec3d(bb.maxX, bb.minY, bb.minZ); + Vec3d xYz = new Vec3d(bb.minX, bb.maxY, bb.minZ); + Vec3d XYz = new Vec3d(bb.maxX, bb.maxY, bb.minZ); + Vec3d xyZ = new Vec3d(bb.minX, bb.minY, bb.maxZ); + Vec3d XyZ = new Vec3d(bb.maxX, bb.minY, bb.maxZ); + Vec3d xYZ = new Vec3d(bb.minX, bb.maxY, bb.maxZ); + Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ); + + Vec3d start = xyz; + renderAACuboidLine(start, Xyz, color, alpha, buffer); + renderAACuboidLine(start, xYz, color, alpha, buffer); + renderAACuboidLine(start, xyZ, color, alpha, buffer); + + start = XyZ; + renderAACuboidLine(start, xyZ, color, alpha, buffer); + renderAACuboidLine(start, XYZ, color, alpha, buffer); + renderAACuboidLine(start, Xyz, color, alpha, buffer); + + start = XYz; + renderAACuboidLine(start, xYz, color, alpha, buffer); + renderAACuboidLine(start, Xyz, color, alpha, buffer); + renderAACuboidLine(start, XYZ, color, alpha, buffer); + + start = xYZ; + renderAACuboidLine(start, XYZ, color, alpha, buffer); + renderAACuboidLine(start, xyZ, color, alpha, buffer); + renderAACuboidLine(start, xYz, color, alpha, buffer); + + draw(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java new file mode 100644 index 000000000..131a24c10 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java @@ -0,0 +1,143 @@ +package com.simibubi.create.foundation.utility.outliner; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.simibubi.create.AllSpecialTextures; +import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class BlockClusterOutline extends Outline { + + private Cluster cluster; + private float alpha; + + public BlockClusterOutline(Iterable selection) { + cluster = new Cluster(); + selection.forEach(cluster::include); + alpha = .5f; + } + + @Override + public void render(BufferBuilder buffer) { + begin(); + Vec3d color = ColorHelper.getRGB(0xDDDDDD); + AllSpecialTextures.SELECTION.bind(); + + for (MergeEntry face : cluster.visibleFaces.keySet()) { + AxisDirection axisDirection = cluster.visibleFaces.get(face); + Direction direction = Direction.getFacingFromAxis(axisDirection, face.axis); + BlockPos pos = face.pos; + if (axisDirection == AxisDirection.POSITIVE) + pos = pos.offset(direction.getOpposite()); + renderFace(pos, direction, color, alpha * .25f, 1 / 64d, buffer); + } + + flush(); + AllSpecialTextures.BLANK.bind(); + + for (MergeEntry edge : cluster.visibleEdges) { + lineWidth = 1 / 16f * alpha; + Vec3d start = new Vec3d(edge.pos); + Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis); + renderAACuboidLine(start, new Vec3d(edge.pos.offset(direction)), color, 1, buffer); + } + + draw(); + } + + public void setAlpha(float alpha) { + this.alpha = alpha; + } + + private static class Cluster { + + Map visibleFaces; + Set visibleEdges; + + public Cluster() { + visibleEdges = new HashSet<>(); + visibleFaces = new HashMap<>(); + } + + public void include(BlockPos pos) { + + // 6 FACES + for (Axis axis : Axis.values()) { + Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); + for (int offset : new int[] { 0, 1 }) { + MergeEntry entry = new MergeEntry(axis, pos.offset(direction, offset)); + if (visibleFaces.remove(entry) == null) + visibleFaces.put(entry, offset == 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE); + } + } + + // 12 EDGES + for (Axis axis : Axis.values()) { + for (Axis axis2 : Axis.values()) { + if (axis == axis2) + continue; + for (Axis axis3 : Axis.values()) { + if (axis == axis3) + continue; + if (axis2 == axis3) + continue; + + Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis2); + Direction direction2 = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis3); + + for (int offset : new int[] { 0, 1 }) { + BlockPos entryPos = pos.offset(direction, offset); + for (int offset2 : new int[] { 0, 1 }) { + entryPos = entryPos.offset(direction2, offset2); + MergeEntry entry = new MergeEntry(axis, entryPos); + if (!visibleEdges.remove(entry)) + visibleEdges.add(entry); + } + } + } + + break; + } + } + + } + + } + + private static class MergeEntry { + + Axis axis; + BlockPos pos; + + public MergeEntry(Axis axis, BlockPos pos) { + this.axis = axis; + this.pos = pos; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof MergeEntry)) + return false; + + MergeEntry other = (MergeEntry) o; + return this.axis == other.axis && this.pos.equals(other.pos); + } + + @Override + public int hashCode() { + return this.pos.hashCode() * 31 + axis.ordinal(); + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java new file mode 100644 index 000000000..a0fe1646e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java @@ -0,0 +1,109 @@ +package com.simibubi.create.foundation.utility.outliner; + +import org.lwjgl.opengl.GL11; + +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public abstract class Outline { + + protected float lineWidth = 1 / 32f; + + public abstract void render(BufferBuilder buffer); + + protected void begin() { + BufferBuilder buffer = Tessellator.getInstance().getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + } + + protected void draw() { + Tessellator.getInstance().draw(); + } + + protected void flush() { + draw(); + begin(); + } + + protected void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, BufferBuilder buffer) { + Vec3d diff = end.subtract(start); + if (diff.x + diff.y + diff.z < 0) { + Vec3d temp = start; + start = end; + end = temp; + diff = diff.scale(-1); + } + + Vec3d extension = diff.normalize().scale(lineWidth / 2); + Vec3d plane = VecHelper.planeByNormal(diff); + Axis axis = Direction.getFacingFromVector(diff.x, diff.y, diff.z).getAxis(); + + start = start.subtract(extension); + end = end.add(extension); + plane = plane.scale(lineWidth / 2); + Vec3d a1 = plane.add(start); + Vec3d b1 = plane.add(end); + plane = VecHelper.rotate(plane, -90, axis); + Vec3d a2 = plane.add(start); + Vec3d b2 = plane.add(end); + plane = VecHelper.rotate(plane, -90, axis); + Vec3d a3 = plane.add(start); + Vec3d b3 = plane.add(end); + plane = VecHelper.rotate(plane, -90, axis); + Vec3d a4 = plane.add(start); + Vec3d b4 = plane.add(end); + + putQuad(b4, b3, b2, b1, rgb, alpha, buffer); + putQuad(a1, a2, a3, a4, rgb, alpha, buffer); + + putQuad(a1, b1, b2, a2, rgb, alpha, buffer); + putQuad(a2, b2, b3, a3, rgb, alpha, buffer); + putQuad(a3, b3, b4, a4, rgb, alpha, buffer); + putQuad(a4, b4, b1, a1, rgb, alpha, buffer); + } + + protected void renderFace(BlockPos pos, Direction face, Vec3d rgb, float alpha, double scaleOffset, + BufferBuilder buffer) { + Vec3d center = VecHelper.getCenterOf(pos); + Vec3d offset = new Vec3d(face.getDirectionVec()); + Vec3d plane = VecHelper.planeByNormal(offset); + Axis axis = face.getAxis(); + + offset = offset.scale(1 / 2f + scaleOffset); + plane = plane.scale(1 / 2f).add(offset); + + int deg = face.getAxisDirection().getOffset() * 90; + Vec3d a1 = plane.add(center); + plane = VecHelper.rotate(plane, deg, axis); + Vec3d a2 = plane.add(center); + plane = VecHelper.rotate(plane, deg, axis); + Vec3d a3 = plane.add(center); + plane = VecHelper.rotate(plane, deg, axis); + Vec3d a4 = plane.add(center); + + putQuad(a1, a2, a3, a4, rgb, alpha, buffer); + } + + protected void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, BufferBuilder buffer) { + putVertex(v1, rgb, 0, 0, alpha, buffer); + putVertex(v2, rgb, 1, 0, alpha, buffer); + putVertex(v3, rgb, 1, 1, alpha, buffer); + putVertex(v4, rgb, 0, 1, alpha, buffer); + } + + protected void putVertex(Vec3d pos, Vec3d rgb, float u, float v, float alpha, BufferBuilder buffer) { + int i = 15 << 20 | 15 << 4; + int j = i >> 16 & '\uffff'; + int k = i & '\uffff'; + buffer.pos(pos.x, pos.y, pos.z).tex(u, v).color((float) rgb.x, (float) rgb.y, (float) rgb.z, alpha) + .lightmap(j, k).endVertex(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java new file mode 100644 index 000000000..80feeb1ca --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java @@ -0,0 +1,58 @@ +package com.simibubi.create.foundation.utility.outliner; + +import com.mojang.blaze3d.platform.GlStateManager; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.particle.IParticleRenderType; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +public class OutlineParticle extends Particle { + + private Outline outline; + + private OutlineParticle(Outline outline, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn) { + super(worldIn, xCoordIn, yCoordIn, zCoordIn); + this.outline = outline; + this.maxAge = 1024; + } + + public static OutlineParticle create(Outline outline) { + Minecraft mc = Minecraft.getInstance(); + ClientPlayerEntity player = mc.player; + OutlineParticle effect = new OutlineParticle(outline, mc.world, player.posX, player.posY, player.posZ); + mc.particles.addEffect(effect); + return effect; + } + + public void remove() { + isExpired = true; + } + + @Override + public void renderParticle(BufferBuilder buffer, ActiveRenderInfo entityIn, float partialTicks, float rotationX, + float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { + GlStateManager.pushMatrix(); + Vec3d view = entityIn.getProjectedView(); + GlStateManager.translated(-view.x, -view.y, -view.z); + GlStateManager.depthMask(false); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + + GlStateManager.enableBlend(); + outline.render(buffer); + GlStateManager.disableBlend(); + + GlStateManager.depthMask(true); + GlStateManager.popMatrix(); + } + + @Override + public IParticleRenderType getRenderType() { + return IParticleRenderType.CUSTOM; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java index 45eaa4939..d70185a9a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.contraptions.base; import com.simibubi.create.foundation.item.ItemDescription.Palette; -import com.simibubi.create.modules.contraptions.RotationPropagator; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -47,7 +46,10 @@ public abstract class KineticBlock extends Block implements IRotate { return tool == ToolType.AXE || tool == ToolType.PICKAXE; } - // IRotate + @Override + public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { + // onBlockAdded is useless for init, as sometimes the TE gets re-instantiated + } @Override public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { @@ -64,8 +66,6 @@ public abstract class KineticBlock extends Block implements IRotate { return null; } - // Block - @Override public boolean hasTileEntity(BlockState state) { return true; @@ -79,8 +79,8 @@ public abstract class KineticBlock extends Block implements IRotate { @Override public abstract TileEntity createTileEntity(BlockState state, IBlockReader world); - @SuppressWarnings("deprecation") @Override + @SuppressWarnings("deprecation") public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { super.updateNeighbors(stateIn, worldIn, pos, flags); if (worldIn.isRemote()) @@ -90,8 +90,11 @@ public abstract class KineticBlock extends Block implements IRotate { if (!(tileEntity instanceof KineticTileEntity)) return; + // Remove previous information when block is added KineticTileEntity kte = (KineticTileEntity) tileEntity; - RotationPropagator.handleAdded(worldIn.getWorld(), pos, kte); + kte.warnOfMovement(); + kte.clearKineticInformation(); + kte.updateSpeed = true; } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java index de3df92b2..21b8f0e60 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java @@ -41,12 +41,14 @@ public abstract class KineticTileEntity extends SmartTileEntity public @Nullable Long network; public @Nullable BlockPos source; public boolean networkDirty; + public boolean updateSpeed; protected KineticEffectHandler effects; protected float speed; protected float capacity; protected float stress; protected boolean overStressed; + protected boolean wasMoved; private int flickerTally; private int networkSize; @@ -57,6 +59,7 @@ public abstract class KineticTileEntity extends SmartTileEntity public KineticTileEntity(TileEntityType typeIn) { super(typeIn); effects = new KineticEffectHandler(this); + updateSpeed = true; } @Override @@ -73,6 +76,9 @@ public abstract class KineticTileEntity extends SmartTileEntity @Override public void tick() { + if (!world.isRemote && needsSpeedUpdate()) + attachKinetics(); + super.tick(); effects.tick(); @@ -179,6 +185,9 @@ public abstract class KineticTileEntity extends SmartTileEntity public CompoundNBT write(CompoundNBT compound) { compound.putFloat("Speed", speed); + if (needsSpeedUpdate()) + compound.putBoolean("NeedsSpeedUpdate", true); + if (hasSource()) compound.put("Source", NBTUtil.writeBlockPos(source)); @@ -188,7 +197,7 @@ public abstract class KineticTileEntity extends SmartTileEntity networkTag.putFloat("Stress", stress); networkTag.putFloat("Capacity", capacity); networkTag.putInt("Size", networkSize); - + if (lastStressApplied != 0) networkTag.putFloat("AddedStress", lastStressApplied); if (lastCapacityProvided != 0) @@ -200,16 +209,21 @@ public abstract class KineticTileEntity extends SmartTileEntity return super.write(compound); } + public boolean needsSpeedUpdate() { + return updateSpeed; + } + @Override public void read(CompoundNBT compound) { + clearKineticInformation(); + + // DO NOT READ kinetic information when placed after movement + if (wasMoved) { + super.read(compound); + return; + } + speed = compound.getFloat("Speed"); - source = null; - network = null; - overStressed = false; - stress = 0; - capacity = 0; - lastStressApplied = 0; - lastCapacityProvided = 0; if (compound.contains("Source")) source = NBTUtil.readBlockPos(compound.getCompound("Source")); @@ -313,6 +327,7 @@ public abstract class KineticTileEntity extends SmartTileEntity } public void attachKinetics() { + updateSpeed = false; RotationPropagator.handleAdded(world, pos, this); } @@ -414,6 +429,21 @@ public abstract class KineticTileEntity extends SmartTileEntity } + public void clearKineticInformation() { + speed = 0; + source = null; + network = null; + overStressed = false; + stress = 0; + capacity = 0; + lastStressApplied = 0; + lastCapacityProvided = 0; + } + + public void warnOfMovement() { + wasMoved = true; + } + public int getFlickerScore() { return flickerTally; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java index 844833d8c..21ea16106 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java @@ -12,6 +12,8 @@ import com.simibubi.create.modules.contraptions.components.contraptions.piston.M import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock; import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock; import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; @@ -82,7 +84,7 @@ public class BlockMovementTraits { if (block instanceof PulleyBlock) { TileEntity te = world.getTileEntity(pos); if (te instanceof PulleyTileEntity) - return !((PulleyTileEntity) te).running && ((PulleyTileEntity) te).offset == 0; + return !((PulleyTileEntity) te).running; } if (AllBlocks.BELT.typeOf(blockState)) @@ -126,6 +128,10 @@ public class BlockMovementTraits { return true; if (block instanceof RedstoneLinkBlock) return true; + if (block instanceof RopeBlock) + return true; + if (block instanceof MagnetBlock) + return true; return false; } @@ -187,6 +193,8 @@ public class BlockMovementTraits { return state.get(PortableStorageInterfaceBlock.FACING) == facing; if (AllBlocks.HARVESTER.typeOf(state)) return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing; + if (AllBlocks.ROPE_PULLEY.typeOf(state)) + return facing == Direction.DOWN; return isBrittle(state); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java index b8a1b2e42..6714c05fc 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java @@ -13,10 +13,11 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.foundation.utility.outliner.BlockClusterOutline; +import com.simibubi.create.foundation.utility.outliner.OutlineParticle; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.Tessellator; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; @@ -30,13 +31,15 @@ public class ChassisRangeDisplay { private static GroupEntry lastHoveredGroup = null; private static class Entry { - Set includedPositions; + BlockClusterOutline outline; + OutlineParticle particle; ChassisTileEntity te; int timer; public Entry(ChassisTileEntity te) { this.te = te; - includedPositions = createSelection(te); + outline = new BlockClusterOutline(createSelection(te)); + particle = OutlineParticle.create(outline); timer = DISPLAY_TIME; } @@ -80,14 +83,19 @@ public class ChassisRangeDisplay { World world = Minecraft.getInstance().world; boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand()); - for (Iterator iterator = entries.keySet().iterator(); iterator.hasNext();) - if (tickEntry(entries.get(iterator.next()), hasWrench)) + for (Iterator iterator = entries.keySet().iterator(); iterator.hasNext();) { + Entry entry = entries.get(iterator.next()); + if (tickEntry(entry, hasWrench)) { + entry.particle.remove(); iterator.remove(); + } + } for (Iterator iterator = groupEntries.iterator(); iterator.hasNext();) { GroupEntry group = iterator.next(); if (tickEntry(group, hasWrench)) { iterator.remove(); + group.particle.remove(); if (group == lastHoveredGroup) lastHoveredGroup = null; } @@ -113,8 +121,11 @@ public class ChassisRangeDisplay { if (ctrl) { GroupEntry existingGroupForPos = getExistingGroupForPos(pos); if (existingGroupForPos != null) { - for (ChassisTileEntity included : existingGroupForPos.includedTEs) - entries.remove(included.getPos()); + for (ChassisTileEntity included : existingGroupForPos.includedTEs) { + Entry removed = entries.remove(included.getPos()); + if (removed != null) + removed.particle.remove(); + } existingGroupForPos.timer = DISPLAY_TIME; return; } @@ -162,13 +173,19 @@ public class ChassisRangeDisplay { public static void display(ChassisTileEntity chassis) { deselect(); if (AllKeys.ctrlDown()) { + groupEntries.forEach(e -> e.particle.remove()); groupEntries.clear(); GroupEntry hoveredGroup = new GroupEntry(chassis); - for (ChassisTileEntity included : hoveredGroup.includedTEs) - entries.remove(included.getPos()); + for (ChassisTileEntity included : hoveredGroup.includedTEs) { + Entry remove = entries.remove(included.getPos()); + if (remove != null) + remove.particle.remove(); + } groupEntries.add(hoveredGroup); } else { - entries.put(chassis.getPos(), new Entry(chassis)); + Entry old = entries.put(chassis.getPos(), new Entry(chassis)); + if (old != null) + old.particle.remove(); } } @@ -190,17 +207,23 @@ public class ChassisRangeDisplay { } public static void renderPositions(Entry entry, float partialTicks) { - TessellatorHelper.begin(); - BlockPos size = new BlockPos(1, 1, 1); +// GlStateManager.pushMatrix(); +// RenderHelper.disableStandardItemLighting(); +// GlStateManager.normal3f(0.0F, 1.0F, 0.0F); +// GlStateManager.color4f(1, 1, 1, 1); +// GlStateManager.enableTexture(); +// GlStateManager.depthMask(false); +// GlStateManager.enableBlend(); +// GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); +// float timer = entry.timer - partialTicks; - float alpha = timer > 20 ? .5f : timer / 40f; - GlStateManager.color4f(1, .7f, 0, alpha); - Set includedPositions = entry.includedPositions; - GlStateManager.depthMask(false); - for (BlockPos pos : includedPositions) - TessellatorHelper.cube(Tessellator.getInstance().getBuffer(), pos, size, 1 / 16f - 1 / 64f, true, false); - TessellatorHelper.draw(); - GlStateManager.depthMask(true); + float alpha = timer > 20 ? 1 : timer / 20f; + entry.outline.setAlpha(alpha); +// entry.outline.render(Tessellator.getInstance().getBuffer()); +// +// GlStateManager.disableBlend(); +// GlStateManager.depthMask(true); +// GlStateManager.popMatrix(); } private static GroupEntry getExistingGroupForPos(BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java index c4c0a9033..a272f87c0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java @@ -26,13 +26,16 @@ import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock; -import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock; import com.simibubi.create.modules.contraptions.components.saw.SawBlock; import com.simibubi.create.modules.contraptions.redstone.ContactBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; -import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock; import net.minecraft.block.AbstractButtonBlock; @@ -53,6 +56,7 @@ import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.Rotation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -117,7 +121,8 @@ public abstract class Contraption { if (bounds == null) bounds = new AxisAlignedBB(BlockPos.ZERO); - frontier.add(pos); + if (!BlockMovementTraits.isBrittle(world.getBlockState(pos))) + frontier.add(pos); if (!addToInitialFrontier(world, pos, forcedDirection, frontier)) return false; for (int limit = 100000; limit > 0; limit--) { @@ -147,6 +152,8 @@ public abstract class Contraption { if (!world.isBlockPresent(pos)) return false; + if (isAnchoringBlockAt(pos)) + return true; if (!BlockMovementTraits.movementNecessary(world, pos)) return true; if (!BlockMovementTraits.movementAllowed(world, pos)) @@ -154,6 +161,7 @@ public abstract class Contraption { BlockState state = world.getBlockState(pos); if (isChassis(state) && !moveChassis(world, pos, forcedDirection, frontier, visited)) return false; + if (AllBlocks.FLEXCRATE.typeOf(state)) FlexcrateBlock.splitCrate(world, pos); if (AllBlocks.BELT.typeOf(state)) { @@ -164,7 +172,27 @@ public abstract class Contraption { if (prevPos != null && !visited.contains(prevPos)) frontier.add(prevPos); } - + + // Pulleys drag their rope and their attached structure + if (state.getBlock() instanceof PulleyBlock) { + int limit = AllConfigs.SERVER.kinetics.maxRopeLength.get(); + BlockPos ropePos = pos; + while (limit-- >= 0) { + ropePos = ropePos.down(); + if (!world.isBlockPresent(ropePos)) + break; + BlockState ropeState = world.getBlockState(ropePos); + Block block = ropeState.getBlock(); + if (!(block instanceof RopeBlock) && !(block instanceof MagnetBlock)) { + if (!visited.contains(ropePos)) + frontier.add(ropePos); + break; + } + add(ropePos, capture(world, ropePos)); + } + } + + // Pistons drag their attaches poles and extension if (state.getBlock() instanceof MechanicalPistonBlock) { int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); Direction direction = state.get(MechanicalPistonBlock.FACING); @@ -188,7 +216,7 @@ public abstract class Contraption { if (limit <= -1) return false; } - + BlockPos searchPos = pos; while (limit-- >= 0) { searchPos = searchPos.offset(direction.getOpposite()); @@ -202,17 +230,19 @@ public abstract class Contraption { } break; } - + if (limit <= -1) return false; } - + + // Doors try to stay whole if (state.getBlock() instanceof DoorBlock) { BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1); if (!visited.contains(otherPartPos)) frontier.add(otherPartPos); } + // Slime blocks drag adjacent blocks if possible boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock; for (Direction offset : Direction.values()) { BlockPos offsetPos = pos.offset(offset); @@ -224,14 +254,15 @@ public abstract class Contraption { return false; continue; } - if (!visited.contains(offsetPos) - && (isSlimeBlock || BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()))) + if (!visited.contains(offsetPos) && ((isSlimeBlock && !BlockMovementTraits.isBrittle(blockState)) + || BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()))) frontier.add(offsetPos); } add(pos, capture(world, pos)); if (blocks.size() > AllConfigs.SERVER.kinetics.maxBlocksMoved.get()) return false; + return true; } @@ -497,8 +528,16 @@ public abstract class Contraption { && !blockState.getCollisionShape(world, targetPos).isEmpty()) continue; - world.destroyBlock(targetPos, blockState.getCollisionShape(world, targetPos).isEmpty()); + world.destroyBlock(targetPos, true); world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING); + + boolean verticalRotation = transform.rotationAxis == null || transform.rotationAxis.isHorizontal(); + verticalRotation = verticalRotation && transform.rotation != Rotation.NONE; + if (verticalRotation) { + if (state.getBlock() instanceof RopeBlock || state.getBlock() instanceof MagnetBlock) + world.destroyBlock(targetPos, true); + } + TileEntity tileEntity = world.getTileEntity(targetPos); CompoundNBT tag = block.nbt; if (tileEntity != null && tag != null) { @@ -506,22 +545,13 @@ public abstract class Contraption { tag.putInt("y", targetPos.getY()); tag.putInt("z", targetPos.getZ()); - if (tileEntity instanceof BeltTileEntity) { - tag.remove("Length"); - tag.remove("Index"); - tag.putBoolean("DontClearAttachments", true); + if (verticalRotation && tileEntity instanceof PulleyTileEntity) { + tag.remove("Offset"); + tag.remove("InitialOffset"); } tileEntity.read(tag); - if (tileEntity instanceof KineticTileEntity) { - KineticTileEntity kineticTileEntity = (KineticTileEntity) tileEntity; - kineticTileEntity.source = null; - kineticTileEntity.setSpeed(0); - kineticTileEntity.network = null; - kineticTileEntity.attachKinetics(); - } - if (storage.containsKey(block.pos)) { MountedStorage mountedStorage = storage.get(block.pos); if (mountedStorage.isWorking()) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index c4a347028..bf2655afc 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -432,7 +432,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } remove(); } - + @Override protected void doWaterSplashEffect() { } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java index e7d3edc64..d32d89010 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java @@ -36,6 +36,11 @@ public class BearingContraption extends Contraption { return construct; } + @Override + protected boolean isAnchoringBlockAt(BlockPos pos) { + return pos.equals(anchor.offset(facing.getOpposite())); + } + @Override public void add(BlockPos pos, Pair capture) { BlockPos localPos = pos.subtract(anchor); @@ -62,7 +67,7 @@ public class BearingContraption extends Contraption { public int getSailBlocks() { return sailBlocks; } - + public Direction getFacing() { return facing; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java index b8d4fd577..1f73f7449 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkBearingTileEntity.java @@ -148,6 +148,9 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe } public void assemble() { + if (!(world.getBlockState(pos).getBlock() instanceof ClockworkBearingBlock)) + return; + Direction direction = getBlockState().get(BlockStateProperties.FACING); // Collect Construct @@ -182,7 +185,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe } public void disassemble() { - if (!running) + if (!running && hourHand == null && minuteHand == null) return; hourAngle = 0; @@ -205,7 +208,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe public void attach(ContraptionEntity contraption) { if (!(contraption.getContraption() instanceof ClockworkContraption)) return; - + ClockworkContraption cc = (ClockworkContraption) contraption.getContraption(); markDirty(); Direction facing = getBlockState().get(BlockStateProperties.FACING); @@ -217,8 +220,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe this.minuteHand = contraption; minuteHand.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); } - if (!world.isRemote) + if (!world.isRemote) { + this.running = true; sendData(); + } } @Override @@ -302,5 +307,5 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe public boolean isRunning() { return running; } - + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java index 25d4687ee..e31759ed6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java @@ -32,6 +32,11 @@ public class ClockworkContraption extends Contraption { ignoreBlocks.add(anchor.add(blockPos)); } + @Override + protected boolean isAnchoringBlockAt(BlockPos pos) { + return pos.equals(anchor.offset(facing.getOpposite(), offset + 1)); + } + public static Pair assembleClockworkAt(World world, BlockPos pos, Direction direction) { if (isFrozen()) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java index d962824b6..bffbbc4e5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/MechanicalBearingTileEntity.java @@ -150,6 +150,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp } public void assemble() { + if (!(world.getBlockState(pos).getBlock() instanceof MechanicalBearingBlock)) + return; + Direction direction = getBlockState().get(FACING); // Collect Construct @@ -161,6 +164,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp if (contraption.blocks.isEmpty()) return; contraption.removeBlocksFromWorld(world, BlockPos.ZERO); + movedContraption = ContraptionEntity.createStationary(world, contraption).controlledBy(this); BlockPos anchor = pos.offset(direction); movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); @@ -172,7 +176,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp sendData(); updateGeneratedRotation(); } - + @Override public void updateGeneratedRotation() { super.updateGeneratedRotation(); @@ -180,7 +184,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp } public void disassemble() { - if (!running) + if (!running && movedContraption == null) return; if (movedContraption != null) movedContraption.disassemble(); @@ -267,8 +271,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp markDirty(); BlockPos anchor = pos.offset(blockState.get(FACING)); movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); - if (!world.isRemote) + if (!world.isRemote) { + this.running = true; sendData(); + } } @Override @@ -298,7 +304,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public boolean isAttachedTo(ContraptionEntity contraption) { return movedContraption == contraption; } - + public boolean isRunning() { return running; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java index d19225985..2cf714806 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java @@ -167,11 +167,7 @@ public class ChassisTileEntity extends SmartTileEntity { // Ignore replaceable Blocks and Air-like if (!BlockMovementTraits.movementNecessary(world, current)) break; - if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(currentState)) - break; - if (AllBlocks.MECHANICAL_PISTON.typeOf(currentState)) - break; - if (AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(currentState)) + if (BlockMovementTraits.isBrittle(currentState)) break; positions.add(current); @@ -212,6 +208,8 @@ public class ChassisTileEntity extends SmartTileEntity { continue; if (!BlockMovementTraits.movementNecessary(world, searchPos)) continue; + if (BlockMovementTraits.isBrittle(searchedState)) + continue; localVisited.add(searchPos); if (!searchPos.equals(pos)) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java index 1dd193592..610577738 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java @@ -8,6 +8,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes; +import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; import net.minecraft.block.BlockState; @@ -61,8 +62,14 @@ public class MountedContraption extends Contraption { if (!AllBlocks.CART_ASSEMBLER.typeOf(state)) return false; Axis axis = state.get(CartAssemblerBlock.RAIL_SHAPE) == RailShape.EAST_WEST ? Axis.Z : Axis.X; - for (AxisDirection axisDirection : AxisDirection.values()) - frontier.add(pos.offset(Direction.getFacingFromAxis(axisDirection, axis))); + for (AxisDirection axisDirection : AxisDirection.values()) { + Direction facingFromAxis = Direction.getFacingFromAxis(axisDirection, axis); + BlockPos offset = pos.offset(facingFromAxis); + BlockState blockState = world.getBlockState(offset); + if (!BlockMovementTraits.isBrittle(blockState) + || BlockMovementTraits.isBlockAttachedTowards(blockState, facingFromAxis.getOpposite())) + frontier.add(offset); + } return true; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java index 4642683f8..394fd07af 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/LinearActuatorTileEntity.java @@ -293,8 +293,10 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme @Override public void attach(ContraptionEntity contraption) { this.movedContraption = contraption; - if (!world.isRemote) + if (!world.isRemote) { + this.running = true; sendData(); + } } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java index 7dda90f67..b71d5cdc2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntity.java @@ -42,6 +42,9 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { @Override public void assemble() { + if (!(world.getBlockState(pos).getBlock() instanceof MechanicalPistonBlock)) + return; + Direction direction = getBlockState().get(BlockStateProperties.FACING); // Collect Construct @@ -83,10 +86,11 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity { @Override public void disassemble() { - if (!running) + if (!running && movedContraption == null) return; if (!removed) - getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3); + getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), + 3 | 16); if (movedContraption != null) { applyContraptionPosition(); movedContraption.disassemble(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java index cb2118760..0d115e2e7 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java @@ -13,6 +13,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes; import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; @@ -63,17 +64,24 @@ public class PistonContraption extends Contraption { BlockPos actualStart = pos; BlockState nextBlock = world.getBlockState(actualStart.offset(direction)); int extensionsInFront = 0; - boolean sticky = STICKY_MECHANICAL_PISTON.typeOf(world.getBlockState(pos)); + BlockState blockState = world.getBlockState(pos); + boolean sticky = STICKY_MECHANICAL_PISTON.typeOf(blockState); - if (world.getBlockState(pos).get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { + if (!(blockState.getBlock() instanceof MechanicalPistonBlock)) + return false; + + if (blockState.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { while (PISTON_POLE.typeOf(nextBlock) && nextBlock.get(FACING).getAxis() == direction.getAxis() || MECHANICAL_PISTON_HEAD.typeOf(nextBlock) && nextBlock.get(FACING) == direction) { actualStart = actualStart.offset(direction); poles.add(new BlockInfo(actualStart, nextBlock.with(FACING, direction), null)); extensionsInFront++; - nextBlock = world.getBlockState(actualStart.offset(direction)); + if (MECHANICAL_PISTON_HEAD.typeOf(nextBlock)) + break; + + nextBlock = world.getBlockState(actualStart.offset(direction)); if (extensionsInFront > MechanicalPistonBlock.maxAllowedPistonPoles()) return false; } @@ -122,6 +130,11 @@ public class PistonContraption extends Contraption { return true; } + @Override + protected boolean isAnchoringBlockAt(BlockPos pos) { + return pistonExtensionCollisionBox.contains(VecHelper.getCenterOf(pos.subtract(anchor))); + } + @Override protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List frontier) { frontier.clear(); @@ -138,6 +151,8 @@ public class PistonContraption extends Contraption { if (!BlockMovementTraits.movementNecessary(world, currentPos)) return true; BlockState state = world.getBlockState(currentPos); + if (BlockMovementTraits.isBrittle(state)) + return true; if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite()) return true; if (!BlockMovementTraits.movementAllowed(world, currentPos)) @@ -146,7 +161,7 @@ public class PistonContraption extends Contraption { if (BlockMovementTraits.notSupportive(state, orientation)) return true; } - return false; // too many + return true; } @Override @@ -165,7 +180,7 @@ public class PistonContraption extends Contraption { return true; if (!AllBlocks.PISTON_POLE.typeOf(state) && pistonState.getBlock() instanceof MechanicalPistonBlock) world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED), - 3); + 3 | 16); return true; } return false; @@ -178,7 +193,7 @@ public class PistonContraption extends Contraption { BlockPos pistonPos = anchor.offset(orientation, -1); BlockState blockState = world.getBlockState(pos); if (pos.equals(pistonPos) && blockState.getBlock() instanceof MechanicalPistonBlock) { - world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66); + world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66 | 16); return true; } return false; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java index cfae85eea..eb7303834 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyBlock.java @@ -1,6 +1,5 @@ package com.simibubi.create.modules.contraptions.components.contraptions.pulley; -import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.block.IHaveNoBlockItem; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.utility.AllShapes; @@ -9,6 +8,7 @@ import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.material.PushReaction; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.state.EnumProperty; import net.minecraft.state.properties.BlockStateProperties; @@ -41,6 +41,18 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE anchor.getY() + initialOffset + 1) + return false; + return true; + } + @Override public CompoundNBT writeNBT() { CompoundNBT writeNBT = super.writeNBT(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java index d65f0a5f3..a751277d4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/pulley/PulleyTileEntity.java @@ -37,6 +37,8 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { @Override protected void assemble() { + if (!(world.getBlockState(pos).getBlock() instanceof PulleyBlock)) + return; if (speed == 0) return; if (offset >= getExtensionRange() && getSpeed() > 0) @@ -81,7 +83,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { @Override public void disassemble() { - if (!running) + if (!running && movedContraption == null) return; offset = getGridOffset(offset); if (movedContraption != null) @@ -137,6 +139,8 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { BlockPos posBelow = pos.down((int) (offset + getMovementSpeed()) + 1); if (!BlockMovementTraits.movementNecessary(world, posBelow)) return; + if (BlockMovementTraits.isBrittle(world.getBlockState(posBelow))) + return; disassemble(); assembleNextTick = true; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java index 1ea746fde..1777303b1 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java @@ -87,14 +87,15 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen return false; } - if (player instanceof ClientPlayerEntity) - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> withTileEntityDo(worldIn, pos, this::displayScreen)); + DistExecutor.runWhenOn(Dist.CLIENT, + () -> () -> withTileEntityDo(worldIn, pos, te -> this.displayScreen(te, player))); return true; } @OnlyIn(value = Dist.CLIENT) - protected void displayScreen(SequencedGearshiftTileEntity te) { - ScreenOpener.open(new SequencedGearshiftScreen(te)); + protected void displayScreen(SequencedGearshiftTileEntity te, PlayerEntity player) { + if (player instanceof ClientPlayerEntity) + ScreenOpener.open(new SequencedGearshiftScreen(te)); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java index 5b3575587..14127dc93 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java @@ -418,9 +418,9 @@ public class BeltBlock extends HorizontalKineticBlock // Init belts int index = 0; - List beltChain = getBeltChain(world, pos); + List beltChain = getBeltChain(world, currentPos); if (beltChain.size() < 2) { - world.destroyBlock(pos, true); + world.destroyBlock(currentPos, true); return; } @@ -428,7 +428,7 @@ public class BeltBlock extends HorizontalKineticBlock TileEntity tileEntity = world.getTileEntity(beltPos); if (tileEntity instanceof BeltTileEntity) { BeltTileEntity te = (BeltTileEntity) tileEntity; - te.setController(pos); + te.setController(currentPos); te.beltLength = beltChain.size(); te.index = index; te.attachKinetics(); @@ -446,7 +446,7 @@ public class BeltBlock extends HorizontalKineticBlock if (te.isController() && isVertical) te.getInventory().ejectAll(); } else { - world.destroyBlock(pos, true); + world.destroyBlock(currentPos, true); return; } index++; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java index 1842a17d2..18b546483 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java @@ -66,11 +66,6 @@ public class BeltTileEntity extends KineticTileEntity { color = -1; } - @Override - public void initialize() { - super.initialize(); - } - @Override public void tick() { super.tick(); @@ -164,7 +159,9 @@ public class BeltTileEntity extends KineticTileEntity { @Override public CompoundNBT write(CompoundNBT compound) { attachmentTracker.write(compound); - compound.put("Controller", NBTUtil.writeBlockPos(controller)); + + if (controller != null) + compound.put("Controller", NBTUtil.writeBlockPos(controller)); compound.putBoolean("IsController", isController()); compound.putInt("Color", color); compound.putInt("Length", beltLength); @@ -178,21 +175,32 @@ public class BeltTileEntity extends KineticTileEntity { @Override public void read(CompoundNBT compound) { super.read(compound); + if (compound.getBoolean("IsController")) controller = pos; - else - controller = NBTUtil.readBlockPos(compound.getCompound("Controller")); - if (!compound.contains("DontClearAttachments")) + if (!wasMoved) { + if (!isController()) + controller = NBTUtil.readBlockPos(compound.getCompound("Controller")); trackerUpdateTag = compound; - color = compound.getInt("Color"); - beltLength = compound.getInt("Length"); - index = compound.getInt("Index"); + color = compound.getInt("Color"); + beltLength = compound.getInt("Length"); + index = compound.getInt("Index"); + } if (isController()) getInventory().read(compound.getCompound("Inventory")); } + @Override + public void clearKineticInformation() { + super.clearKineticInformation(); + beltLength = 0; + index = 0; + controller = null; + trackerUpdateTag = new CompoundNBT(); + } + public void applyColor(DyeColor colorIn) { int colorValue = colorIn.getMapColor().colorValue; for (BlockPos blockPos : BeltBlock.getBeltChain(world, getController())) { @@ -206,6 +214,8 @@ public class BeltTileEntity extends KineticTileEntity { } public BeltTileEntity getControllerTE() { + if (controller == null) + return null; if (!world.isBlockPresent(controller)) return null; TileEntity te = world.getTileEntity(controller); @@ -219,11 +229,11 @@ public class BeltTileEntity extends KineticTileEntity { } public BlockPos getController() { - return controller; + return controller == null ? pos : controller; } public boolean isController() { - return controller.equals(pos); + return pos.equals(controller); } public float getBeltMovementSpeed() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/ClutchBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/ClutchBlock.java index 824e5f7dc..07e9a48e8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/ClutchBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/ClutchBlock.java @@ -1,8 +1,5 @@ package com.simibubi.create.modules.contraptions.relays.encased; -import com.simibubi.create.modules.contraptions.RotationPropagator; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.tileentity.TileEntity; @@ -26,13 +23,7 @@ public class ClutchBlock extends GearshiftBlock { boolean previouslyPowered = state.get(POWERED); if (previouslyPowered != worldIn.isBlockPowered(pos)) { worldIn.setBlockState(pos, state.cycle(POWERED), 2 | 16); - TileEntity te = worldIn.getTileEntity(pos); - if (te == null || !(te instanceof KineticTileEntity)) - return; - if (previouslyPowered) - RotationPropagator.handleAdded(worldIn, pos, (KineticTileEntity) te); - else - RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) te); + detachKinetics(worldIn, pos, previouslyPowered); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java index f9e6eb079..ef370c071 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java @@ -1,7 +1,10 @@ package com.simibubi.create.modules.contraptions.relays.encased; +import java.util.Random; + import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.modules.contraptions.RotationPropagator; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.relays.gearbox.GearshiftTileEntity; import net.minecraft.block.Block; @@ -15,6 +18,7 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; +import net.minecraft.world.TickPriority; import net.minecraft.world.World; public class GearshiftBlock extends EncasedShaftBlock implements ITE { @@ -51,7 +55,7 @@ public class GearshiftBlock extends EncasedShaftBlock implements ITE RotationPropagator.handleRemoved(worldIn, pos, te)); + detachKinetics(worldIn, pos, true); worldIn.setBlockState(pos, state.cycle(POWERED), 2); } } @@ -65,4 +69,24 @@ public class GearshiftBlock extends EncasedShaftBlock implements ITE () -> withTileEntityDo(worldIn, pos, this::displayScreen)); + DistExecutor.runWhenOn(Dist.CLIENT, + () -> () -> withTileEntityDo(worldIn, pos, te -> this.displayScreen(te, player))); return true; } @OnlyIn(value = Dist.CLIENT) - protected void displayScreen(StockswitchTileEntity te) { - ScreenOpener.open(new StockswitchScreen(te)); + protected void displayScreen(StockswitchTileEntity te, PlayerEntity player) { + if (player instanceof ClientPlayerEntity) + ScreenOpener.open(new StockswitchScreen(te)); } @Override diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateScreen.java b/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateScreen.java index 5ef02e6fe..c699b9737 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateScreen.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateScreen.java @@ -107,6 +107,10 @@ public class FlexcrateScreen extends AbstractSimiContainerScreen= 0) lastModification++; @@ -114,7 +118,7 @@ public class FlexcrateScreen extends AbstractSimiContainerScreenJ?BaCU{e|@jpAv@8UEl##qYN74rwA9trdqpZGOM)p52ZUmo3ip?J8BP zO|FSpd`sq=qhROA@I7x|)3 jB3NXVKF@AjHl82M>?;*kv#;#E0&=#etDnm{r-UW|BPLZfTEWknjC_*2x8Zk>^vlr7P;hR zmQn%~XciPjQZqZlUFk@q-igD$sm?xNp7u)p{QOY}WVVVUb5cBgNEFC*DMgjow%dOc zNpbSV+g@*Ehv@Cix=8;m~i^X0wWZNJKb+ z6hlYxe0h3uegUu$kV*0cZ;?27C@^Pp%)yypI?P(DqA1@83@3KirVu9R6g;n%vwAsO z)RNG3I1&OKdXbLw51N?{7TPp8nsk5cubb~eC}u})zk?H$LdFLL%H=6=)6E0@8Y3FEM}>oxClpW9)!NdelP*cQ|j4wZJuS-x#C!rriqxmi+VMWL;(+b$}-;R+IOxZQz2VU~*ZXJHP z-JyL*3^SPD$|rX7GEkJWz$3Dlfr0N32s4Umcr^e8>pfi@LnJQqo;Kt=WWeM0aK7{f z=>;sMdWBw*%GL(TM>jNGsYurhe{iGXciVS|G!c!~ibJ0^zu$JxZpVqs7H9f)m8#Vy z*F-G7C3DSET7JWfZLep^#JXDgN^HG)EJS9JQt`oy+!O5-y9({r^TjVJatz>$e91>17zqdh0001xk!UuNAs~MVa7bBm000id000id0mpBsWB>pG)Ja4^ zR5(v{QOj-_&LI+soY+~vcV>4zGu=H@ z?>Y!17|qVkqpP~QI-AXA=0BqqZ0KYAah$J@Y^dK=t=U6C_*kykq z!im{i_v7=I7O-AQ4BnL{B_U#B_f#-Zi%&+9Fdq+x{r$t@`nIQhi4l#^*fjh3<6-{5 zK7bN|NF_{wy*NLA`SuNh6`)KhaR~NlB_SrL>&RI`Rr%6l%`%hc{bvA@5}l%d*P$Z~ z$CKf7Iv9V(V%~ib&Z?Y)WJDlmJob%b*X@SFmT0Ml|VOh2gveX ze>B1$^!@Qjh|5KR`yOoea1ivZVoYrC&}9hLLP>O$5UN+M9$Eu2C>oT*$po`?fV*RV zGKNfoAIpNgR{%a&te^**EYGn#=i!tRRkgNMgnV$Dg90F_+3q^&?V7qguqA(3l`0`P zG@H;CwWPK6Z`bjlCOR9BM{SOZ2_|a;JHTK%)on`o*%`7oyIsBAQr+0c<^FCSss`ms zBq&2vcJ=Mz{^D!1*(d__9UIuE1sH=Wp}SL}z4hVe_4n-4`*-WRg=T06T65a{a~Sgr Y?K#1NX=NXn00000NkvXXu0jG}g55~@CIA2c diff --git a/src/main/resources/assets/create/textures/block/oxidized/copper_block_2.png b/src/main/resources/assets/create/textures/block/oxidized/copper_block_2.png index 53393dfc821d62e140895f663273c9dbb6fe756a..f2be5bd4f7378398a91a09c3e28c027b931a7ed8 100644 GIT binary patch delta 250 zcmaFGyo_mr1SbnK0|Ud`yN`kJZ=x?OJ9&) zz*4GL=oP7KZJ>N~L(`Rtbj|PwH!6O&eRoI`(P*tW^l9_^ZTIYUoVaXprf*lNT5WPo z#Nt~r*DR&wH_X`fdX`MAtEI2R)~m-tWELqEAH2vt(N3|e&~80n{GuYq0KUih7zqdh0001xk!UuNAs~MVa7bBm000id000id0mpBsWB>pGe@R3^ zR5(v{l1)y-Kn#VGG>Je$NQE1);3OP}1qa}Mh&@7V*_MPR&15E-{PB65wi1FTYvef3 z_8WWR=cmW$ADDf4wY}wBzoY2w$|RV&YHIRDh}nhscMX0BsgOTLJkSbGI-C)zqYP1C8<#kPJVfDeY0H?REd_E z#xn^}2qm0x6aylX5cDs~K2a5Eo@IHSW|^uWA_-hDbf15*mBH?B8EN5qO2t-l2}<_uFyU*mR_VH#!->-VftYYM^Kol%Z$SinKBSD z^f^KjR5t<`7nS6VILD1yx!G58V|{4>l0e8B*$&~&9DT{HZ_jf&rG-yPCKG+HYTecJqf+daD-CoWr@>DyJRR-0TC zvG|tEHA`vv4KudAo+T6OYUwMn_3E(@nMF#)2QP9@v{URVv|G;?zo^JDfG_ezpG2_8 gDt(^awro5pGl1W5C zR5(v{Qd>^LFc5UoraXjH#6kGvEF6SCF2LCk7XS{xM`_w7aqRW_!E83PAi>14*759k zyzA=e@xlCq@z7qbZ!phmW8R)$B!S#uaxTS~l651c6k{woA$Eh!QG!79@%moNe$Ic` zC+~>Jd+)}vYulmS*?otRIOded+P;;eBmvsYTnZGU>ki{#Cg~_yj%_Z^uddf~f;s`+ z4?~JLZYBXS1P+AR6jR~T1XzWu|*iW%#j0= z$F$jXl2F&Rw z2L*u{$Y<0; z-h%ew8xTg-K?P8m#CReTd%B@Q5*qc5#w-@7Z1f%@h3I-bjeQIZc}NIH6F5HvJQd$t zc0M>dY}@_jb7;5ZyzM&I_ZZUFsd3f)-7Ox^lq^7N=IBot^94v(hL_#`N7MiS002ov JPDHLkV1k$>+q3`x diff --git a/src/main/resources/assets/create/textures/block/oxidized/copper_block_4.png b/src/main/resources/assets/create/textures/block/oxidized/copper_block_4.png index 6f7ee0aae2e78086935e0da3164310ce4455838d..39c727abb7e10f893668cf551456e64a5b64c1d5 100644 GIT binary patch delta 250 zcmey$yo_mr1SbnK0|Ud`yN`k-ahuh6g#uMtG(qhG(QF z=459Bm12UL``p`sqMQXDk;M!Qe1|}oQB=dL0Vr7S>Eak7ahdnDA>Sbb9=C_{r7uV? zU@6rr^omrrHc&pgq3KFRx@P!;8x_CXzB{CeXtY)w`n37|wtIFvPF%J))3>Wstv0zP zV(~4RYnIaT8)j^KJxeCm)zVjD>(yf+GK-Xo4_@S+Xs6g!Xt$m(eo>KQ0AJ*bK8awF gRr)-;ZP|E!Fte{zSk1n&_X^0_p00i_>zopr0Gbt5y8r+H delta 459 zcmV;+0W|)m0`&us7zqdh0001xk!UuNAs~MVa7bBm000id000id0mpBsWB>pGib+I4 zR5(v{l0kCZAP_~7M)FiSRY`7=L-+u`iuYdlh_1@gii5)qb&y>m%4Sl96O`m28> zg3a%+`VfNmesS(RoaSM$)0rVra!$d!dDK#xfOd?r6cokV$(?sn9W2A?kH;_HzU~Rt z3G}d7iTO$bA~DL!Z1BsoR}h1IWnZZkUEgxWO};qk zx}H&EK#X>2*koSpnIsm~5=Zm5pU*l_OTx_7!W^!a{G!nnwGJJ?k3lJ^yt>$~!FCQ8 zAWS!)0y@L9v)RA}n$Y(*8gejAtJD}6Dav9eJB{2LgsBNN-@Fd(lh6PqMQXDk;M!Qe1|}oQB=dL0Vr7S>Eak7ahdnDA>Sbb9=C_{r7uV? zU@6rr^omrrHc&pgq3KFRx@P!;8x_CXzB{CeXtY)w`n37|wtIFvPF%J))3>Wstv0zP zV(~4RYnIaT8)j^KJxeCm)zVjD>(yf+GK-Xo4_@S+Xs6g!Xt$m(eo>KQ0AJ*bK8awF gRr)-;ZP|E!Fte{zSk1n&_X^0_p00i_>zopr004_uq5uE@ delta 472 zcmV;}0Vn>Z0)hmP7zqdh0001xk!UuNAs~MVa7bBm000id000id0mpBsWB>pGmq|oH zR5(v{Qp--mFc7rUk`^IV0*U|NH#qW5oH_AFoZ-k7apIwd=3&Qgdl|=Rix5mKYvat$ zj(5ZF?r+&YXov0j<`Vn-&e+rALrxgRo^#^F5}pYm1m}E80kKvxc#ptZ^ZN2!Ap(Cp z1TWR7l$LUoLbkhY-)=?UVtMZpC4A}H2IMJ$knK`RF?y{#G3*MdEFuDDeR{SzznBw> z6QXF0@GcxkfOC*C*zuV&j+30gB7=NkAE*WOYF#huljRADp)5{vf(;Jx!Np(fEX z&_NXwoPB?5a>8O!89li5OW07^$M%R0AgsvWeQ13^f%%#Tf%65`Z?C&JW_-iViaRkYHvwR<_;)z&=&Zi z6k!JPM2Yi5Tlau49G8iqGk6Lc@-w3(%)U9Vc!hyjhl^_OypX%TZ}8VZ9>_$Tk^tdx z6jBVv8mHA)vu&D>uKU#ZPrBVO^jJ~~M!A#x`sPZBZc5I;Xy)ioF!l{^E`Fqx4vr`Q O0000AKa+;-S*ufO+=%$;?Sqf@3-Bv+i~Ku#hJccrE0aw zH4%$%$y~FPmftXA+v`~}v96ZB5?ikx3z1o*RDAFv_e49zu0p%@eDRBl90T|wU-U@? ji>%V;*=@_l^MjdvrNV0VmAzMhZej3r^>bP0l+XkKqm*04 delta 442 zcmV;r0Y(0%0^|db7zqdh0001xk!UuNAs~MVa7bBm000id000id0mpBsWB>pGc}YY; zR5(vSt16BXL97s*AOQVH@*Rxfy^j-+FMg?CmAFtwXC*NRj#y?=eH;I z2iChh&APEY6t^GsaXwY*{pD2zpUroo7<&#Y;5~cise!Y7G-1f?ZKa znJ}q`Js_MYpm8(<>7K^PQa81iuDvvU-C)*46KO(eqdO*QKu#VW k?{OZ)0zA#!{R^dj011F=FU~%4xc~qF07*qoM6N<$g8$~e1poj5 diff --git a/src/main/resources/assets/create/textures/block/oxidized/copper_block_7.png b/src/main/resources/assets/create/textures/block/oxidized/copper_block_7.png index 8583fdc59cc1f7e6838b1d2b2d1213f3aeb95be8..7b5b9643b90990b8ce924a0c8ea467d59de47594 100644 GIT binary patch delta 232 zcmeBTTE;ZNt-fqxedFwo-lbEfuba2-z?NMn51hYw<=&HruV24rzy?I_ZkGUxa~60+ z7BevL9RguSQ4OyKpkTeHi(`nyW!}?6r~rYjZc zn&A&_RQzuH?jWMkT5%}x)8_Zv?%C})aoOTb->y=%+T@yu#kXXxSxU=qn6d5kESXqW zOJ9ktSC56rEK({yc#(Ueonlv^-Fm+GMMaJQe338uB!Wd&>GSNiW#jq5%)U}#HT%lm QD9dco88Eb^nyr}n}y;}6a nxeBJrjfOj-eIGtyE@C*q9WAMLv#GfwALKGmS3j3^P6m>Uy zM3^i?vW_JU#y$#JXCBY}JkRgkzu!5}U%%^*>+`UQ5msweEhw2=pK*#)vE!L4T(Rc&!wuij8gAe=TQfP04#M#-011>&2mwLNN zevve4@2}8_pcNB2+gE-5UF3Tr3AU2YA`BBESRH!PvJ}3bp&Ec(OPNmP>?y@0cI+y9 z%R{*#hwI0ut+d#|4>L2b+eR$sIn0WwAPL-^z#lDJ^ft4L@87?-xp%76IkP^@W0OLo zoz!WptEsCaR+jtwgrd>t(0~Bc+UVZi-iMQ6n1GZVM<+XHJ3HqrMPArbG`a15>zZpx zF+Ovlzn_n=)&bB6Gqu0zu}?+PM_EW$Yc?F09@3eo1xh1zy&PtY?15&o}qmFZw8$NwrMI#B6J)s7HG6rw!Ws1=-a^ zDt10(Cqp|VeLx7Pkx{#}v{5f79R5W57T*~qC6)K(pI#`xylt!mh`n^V3Q=dC_acK- zHAC(NySatCyBoE^{U^Tso{Au+<=22Ej;o%$(Dgg>?$t_PGN?N$+085p4au7Q;M&@m zbn>?e;VEG-JKAkeNa~6v!JZ|=)uGjUzP+grUmUh~7%C&<1G4dW%{BG5xDxD`cB>Ig zDuDI=p4FtOd`ayx@KZ1M&-tRxxcE8a9!~iB4-;aiDxm;i(uUiLMz-6&3b{-)>~Cmb zoA%*5n=2YFla1Rm318c`M~dR_&Ovu^t@A2zoD3o1>=*TsKNC%y949A8K|gnB0}R)f z+qx)sFsrp+p8V{2)sxoG*j1YSi{vg2vq>gR5WDyAk#Yr~u5lp^l5WNCLc7x-Ki_kT zzhH}Gc@2xK@?-S>ST5-SSKBCXnW)2DS49OgbDAQLizxZRbrQdzM(s*PwF| z9d|q0GZuil*R$sS@WZF}L;Y{v-iAurC#2(h7dL90%xBq(zJaxuoy!!dZial}sSi}R zu3b$aOfLF97y_i9^MAgp*pFR{^#Dz1x@EO<)K$+8VdOC&L5@nS*)6 zR98i>RpmdmFSE`=Vv*_|HBIfp>esSn&mxRy~|VAdlQ@IpVY;Lr$Lm}J|$3hJY&5+A(Jl)CIoDLIr$^R++vxFr=R zJ9IK#9siE_SNo%&Qi`dNtNZ|_bW!dHXA{n9t#8WoI?& z%l`g8Tk9*ZAX*qfoy6gGcf!JOVHTU=>GRvF5HvR40E@M;!P@+ali#Pe7fGX#Y+0pW z?DyQ%2u*zbFS-fYQ$_kl~Ky`E^J4aP!M6D?q2at`U8> z?nZb&`qgoIb~d609em9LWNAEm8GvX+8?U^YEE-D*wHXSaIN`tKSYY$d)@p&8JuO&j zK|d}Ahhb;=1?Ns^CrWG8v%(u7G*R&lcr(jcEBkt<2dLku>B}LkB7lC{VAVRY1}@Yi zP_5>z7xshYMkaEuOTAVh(^*^m-oGrA+v4sdPHF4rcUe^ySOVAI;90&n9L@n(Zw<}T z?EAV=P}=idwe7dr?0F029&iHY#+%etQW9;_MC!`KV2;;)v&wV%DpMh+JS>=~--EgW zr=&19r6(a6B3B9o&<1Z-^RI>I@Me6*b3e(R)$CiAjY%BnTV8&GSn`R(@`iE@Ad}ke zR)pwatmPnuFvf=ddmNK3{R8_zyq4A7Q!iOq~2l5!B0};o6 zSuI?96p<@xup(LBbSCN36A=MJ`*RnOjzgnksSM1E?;r)BhJS6?fsj}wl2BE}p`%ad zP34X2@BpPqD-DiKtM*qkozxagiq5V>tS5um5AU4jT{1F@w}#SH^rS|!^M)v~pk!&ha+)q*7TxfO zYLF`-{?nBzx(=C~1KL*42SC)dTwfm*iOU;u$s+>+UbziXBA^hl5J?adzlvoUunf9& z{oa?2j5$t2ANZ5yjI`VUwG(iXlzu@gq?vq26$c71V9nmcYh(hSsoyu!>%iM^TZfi1 zzF_7rkX|$wH8{`rmzpR?jfn!Id1bR^d?i&wtQY+5Qnl5RS7_fNPqS57CT%^5S4R;C z&_puEmc`Q=!HaNPly|!bnT}zc#P6aA66>?~xH*1Ji?N={Qpe5B%@qnhf2ChghHQN^ zTDxy|{%~SPCU;y)PaKYjfn z6i)v(XRyBpN#;}S^Xcm$ur`aXVQ!FcAB5ECt60USfnR-2jAmVRR|p&L8^*U*9QW>9 zi)jQVCw53T5ySWIFK!N`SAiYv28~RG|AYv4=uoegeFrfk(5+53W)90DG(xI60eQPp zTis3iLC_xty9<%1)YZd4O{bFq&isH|y1!^l9gUQ5xA5n1Vb0Yda`|_1E`K0M1s-93 z{krMB%S{D83Jae+GE*+QqZO33S~C7H%7Uo}t0k0{Hs5x-b<3mLW)wIAsd=|Lzs3co zI7nK=j%p>xTa;aC&rBH_UdEJ{cf4U>9{AgB(Pt`G@w7^Vj==1d^B?II7_^3n#v9k;f<*9i*{evHR<(8*DK!%I*{CVq%DEAT-CiLQRYqT{;1%wl&_?Uz z@oU$}qRa1&IRTG_s+{U6n3Q}K0>vUP%aA{dfe}ANoAF>^DSMAp2&=SOtEts+XE{h9 zwg=co8R0#lx)8Y{Be{(!Smy`3hw05)Wex`=H%i z4ssf?uRsN$-od-2PKsnuzQS;vP%JK$0{Ynk-E;!PF^4Q9vZ>hTjL@k|2k&yg-PF7R za1us(ea<{=VN3iVF=w*-Orm8$wLtvk8A*=r9TPdoF{v&2 z`FSBGy^*($?c~7Qv|VJv9u@u@_oV%wPmX-c4h5-^1J3_1I{I4{-ZLi@GZr-5B~g_` z9Pv^WzF7XJv4lV;bA*pVOz;XSZ{2ZJ7cwj07PWXC9osMaHp(leH~nV%oSW|2n9rrF zRUYq+>W040J555AbshBWs?N;%F^LVz3;2)QTR9VdG<%xK1d{6 z2en+kq8S0mTvHpD{VB}k1-OaJb}S2e!N`SBadnkP-a;?sbJuO$9Mk?9ia2C&a8N)% zpsSq{$7yT(JnBGnraC$B01Qg)n|s{0#N$~cB2+VbmZYWzYu>pfHgxoHONR(xykR@Z^`AzgB%Jv|U?TIlY`$>v+F(Gk?QW?IeQ+=XU7jWVS5-CNfj#HNiF% zqrM=KaR*H=io|)c*J?zPT-C)b@8@Z)C51#+(<6uHa{DEwKTM~fzWHg6Eh#uyH+z!iYSfkrxWYy zdME4`W;zE320D9sR(g8d+uKV^*SI}`T8;Hh)xWuFA0C4p4y4hoM;ocPZCY;xhK8PI zHj?m6pz}j<9`6rrzY{YA|GY2V_F1{PnYcz3)obeN5xxav-3)(Y1#*;CI;I~n6|&SE+6%`UMC*{Nsb z!pL18*26z)ZXSI|$Sf4dXK@(Z&2Qt}?_NPSHP5Fq2(2maf1o_EfUS5dp=?)06sSzV z=|Z4?du_~d$HzArjO-T(PE#pT9!*fV?gugSQ#&y}X}H-UJ)q{4Jc%)`Cen()N_!M1 zdiyV#uP>3bD}4Le4|WG-b*@U-?GGMd`#2;g0%Wk*%JSkRjIKPS(L})oWaCa0;9MxH z7iEUah6jy*ppSp+p8LUjGU*Dq70Jpey~zFq-&jfQmK`GG?$2#i#bs`_6YFMi!;S0f z8o@1l@a>Jy8n}_B<%#t=V*6HRT-ECLeevZ0)i?oeSK{Z3_GDi>lF~c;;*S>JNB3OS z21(STqtr z&hwAps51FNlv4rzVc0~U;}pTJl%*&88sf8dG~ttyBboo`t9k+kSRELhW8b9iqgc=S z!I1B(CuQBHPG%%V7@uV?%FU!I(DlT*(A0)OR?NVXZ_Fp+opv0u6!dTgRI zCS8l%WkS3kGQAdgp}?an7?XdgR9Xg=eqHNBn_5>7`LVvuQ!Wn<7j1ULNxU;i-IcDn zt|5V7MMqVT%Ip8JxMSh1tXTIw{@m-b+Ha1I7SqKgWvd~3I*Knv%r$9p`)RZV@MeWa1U>J5C~%dP(*|wvH9j z>3W!g=_$PVg_5-_58+}s+t@RA@iOdIsG2`Th)Kpsjt2Lm=6)FRq)-fkcTp- z;$KC`oUa1X!1ly+6+&sPCDbSVb|+{SJ3rM_!k4sE8hk?g*N(fn_LfDb^AJ^UWPaj! z)OvaKzT1)+0Pv`=ZPFrT|AaW$|czoM%pX&ukGD>A}3*C5J)9>USb||qMjW)Mh;LA?z>#M)butyL$ zszX3m01%H|?2IrQ%XaQ~UqD$^CJoZ|z?OKSxyAbWqMk_=kbA+1do=kq%3xRtaK?w9 z{kCYuo$d?Rrt}58CCa3mWOjmbb_$Y8h6dY(<(?v=@jC<+b5;tLC!Y@8Mk^{Reo|B{ zQpqnUs9F7zGf#4lFX$e$8*IM{Qyb7q$5M90{Qz`2U#P!n^?T&^Y_)VS2`%p*jc>o& zaS`V23=5oba3Wgf0f0iLvGia3{->9&Rk6;jB|ybA&595wFlyTlKDp;YY89zGp6-ey%Q()5`h}`{ae9~ z;j`f%=l$}f{IkYt4+S|JO@fYEa?^I=oFp&+QIVs%c8q=R`3a%s{KOV_zir(G~aIRi4n{FDp2Bs!#(w)k}pOh2+ECI%iZ<|(#8EBd)muRxk; zVzVx@RU5Q>Kpn%v4lQ_U!hLe=nK45w&T@zVo+bi&xBUZKRWM;tp?AQXQtr>vHhdUT z(#qm&03ko5$HXe93F$>aXTWCO9XM!X9u%dE_wvGU9JA@T%LkiCEiJ?Ie&ksPs48L6 z`y_6#(vtJ6dAae_barF^&YS!ojYixX#w`D!H7<$rc>?7Mg{;7BTd}Iy`IC&V%iPdT zd$ndUE_>EKu>3wYqxAE%nl9k(I|4M1Z|v6pG|*tQD)G4mFs1`~e!dG7zw!z^ zNW_hyFA*$BKh}|nVL4AxDQEQtYK1~`YU)Mi2o+@|WtUsP5n|PrWHOGc41N*T0Y46A75e4GjVQj;sr0L1_95lj^01`Kq+kKj?Htr?;($` z%TF9vBdh~YjDx~mh-1dYsw14v>OPB6#u*M~^087FLXM!lDB*1+^C;b@Qtzp{Q|!Bk z!CrJMd;5HBZt$+9Tm@g_X9pc410Xasv^`aWb2&vw2r zVq(K@=O`15Ugx$P@4Rod29M0Pu@-N|$Zh7u*x$^saZ*rLP^cL+o!5Q>{?Qw}&V34+ zP!uFt5h3GmSPIPLu<;W?WW-z$n%iY!YHDg?a>E65#P4#)vak(2>Npw>NW!k^!jKz+ z%#5@FlWrFRhN>{0XaPUx`vA*6fE`!2i%T%6`g9A*U86GfjL6R)CqlR``i>^w)}Ev4 z|8jmkf2o9V3(CY8ap^e2J$Qh3@LHJs9{goOlp?8dbLr=3n}LBrz^hJBm|X$8WbAYf zyY)s%3}W!7E%)c0P@>$OP6 zUEFc5GS)0_m%6H^DE>*a%|<$9BD2waH^|QMYh;9h;GGTkZTwPov+owli44vPKvc3o z(c1B-`E*YFZeCw7VHu^`3a)3jleeFjF)Z-me~}>r2zUbBQ5rY3%le-+#Z{y zU4ycw?k!g}-l<1&^!CLcjIefd80K5?(w4Y5-+#q(c~886Ee`i(!f!irS|2*@=bs#f zL)}sD^B+Cx@V;+i4%}s!Sd-BQ$}pwYDNRYRBTh1cqaSpNVN}5*X{MnN=}+2tLhaVn zkz{pVGq?wsq#|L)rMqV&;$K+$6RwsbF^>OHW=>Gy7guN{Q diff --git a/src/main/resources/assets/create/textures/item/antioxidant.png b/src/main/resources/assets/create/textures/item/antioxidant.png new file mode 100644 index 0000000000000000000000000000000000000000..67ad63c3451e8644c976e32888a138f9648d916b GIT binary patch literal 419 zcmV;U0bKrxP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!T)ow zhLe*FO| z3jsI{D4*2uKhh(V!O<%KY{=z{*TIIM1EK;^Nkff6L{gGr-=5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/item/super_glue.png b/src/main/resources/assets/create/textures/item/super_glue.png new file mode 100644 index 0000000000000000000000000000000000000000..b891cb527d74cb41ef71040efe213fd0dc975f30 GIT binary patch literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc4RW3?jv*HQ$$$R;w`W#u;Pjfz`(f9D^lO1_ zz5PiKx&AyAGj4h@$t2rAo~5JcV2h5V0h?r7jsk~(D4W={JqfP=-U@8J{jJ0B&%NKX z9v=C4zNdn>V8@%&AIhIz{eLOSUt(U|WX5bJ#@0LYdHB^fKQ=$G&5cusvFO*j=;so8 zcE4H8SXdIaHQ$h6Q^*c^{G7G>?ynz`IUF1fJWV(G9xax5ASv`~f9fUgIZ}!D8Zy}! zcQ7iPmGso)F@AP7kwKD)>4abVPx(k=i3T2q#Qp~p{)fxi{okMXy6?Zjww-e)7t>|Hod^hCxJA~W80o8`3M?l>Qo!lUNEcECj0Td4UV lPmxKp!M!OS5(Wkg45cp}wmiEz)f5qfGvz&DIxzAjFh4)@{$ZGh zGD3(<>Cn6Kdm|eqG+{IvX(`+77QXNEe8c!JlPXW9;)lTiuYc<`n$0HSIA(vp-?R2S zuMlGLJ%xI3dZ9xrqd~Uy?Z#0!&}HvYvdOY!{Ja& zCQs;e?yy?DAc~^Y6|ij^v)OaHy+^pNTUfCWK-l(edKU=851h|u_QEifei)fsA*``e!q{+ zX2ZuwCqet4&*z02Eg*-2Xv{k>2m(2&s-}S2uGIj4iW4rZH>Av!s{jB107*qoM6N<$ Ef?|oidH?_b delta 459 zcmV;+0W|*E1BwKYNq@rt01m?e$8V@)0004>Nkl5XL`t5fYV1(d@Mc z@C;IyuIq|dX|Fv6ui&B*Z-BaWBU+-{_!}iHySBDx#@S`jyZ(~hnKNhR+cSFx=h(I_ zy-R5CeBURn3ni3Fr3;mAw~J=8$@xCtvCQ=xWh#Cs6!6k+BYz%`W3gCpyw~foU#rzT zB7S}gDBuKN`+fQv>h(HXdWi9O?8zgJo}gGPx<@aU%do6H27@1H&*d91f69r;*R+;rA<;PN$E$u0K(o+X68fji70F(Diqi zrYVyB2!(>YCw~gqioYf80gr$~qtW1EMN!xW0s)R)!y^!lMx_TtB4Mbiif}kAT8YUh zkW40}cfcbM2-?_e4C(u@-EOd4equJ8bBvfwrbwkya`i_GgmY8-{r=zx=pUWq5%|#O z;_58qayhJ5-`MReDPVK#fX(yZ;1Qr?x1ycETR|K|Vz002ovPDHLkV1h9# B;PC(e diff --git a/src/main/resources/assets/create/textures/special/blank.png b/src/main/resources/assets/create/textures/special/blank.png new file mode 100644 index 0000000000000000000000000000000000000000..58ef6694ad06130546c71ded5d03b68da2c70e00 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXP{Gs1F~q_@`Op9V_RN|MoL<7bZl(gvAe^zb cv5}D>G?!WS+@k&Wfod5%UHx3vIVCg!0L2?1^Z)<= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/special/selection.png b/src/main/resources/assets/create/textures/special/selection.png index 7d5539cc7cb4ae8a3f3e3943049e817a362affb6..4bdb5567e85494abce9f826b8a4bdd5e01e44d9c 100644 GIT binary patch delta 167 zcmV;Y09gOs0onnOBnkm@Qb$4nuFf3kks%v@zW@LZzX3P}QzQTY0B=b|K~y+T?UFGH zz#t4oVvhdLk3+-&RIo-y!U7?a~@f@Wy}9N_`n?qEs@<4 Vz?F-7Aiw|s002ovPDHLkV1hI8Moa(z delta 172 zcmcb`c$aa4%0xqn`U4CMd&3VGr{o^o-I}BNsN;~+nLqrNdmDQm$9&!w z_-5<5#Vd-_CR%PjF()$RoQ_etSgxGwQ9JKN=N|jlgZVR!mAcQ&bbWSa(b>f-ZX{>N Y3E8TAkn%e=4`>gAr>mdKI;Vst00am}`~Uy| diff --git a/src/main/resources/data/create/recipes/crushing/glowstone.json b/src/main/resources/data/create/recipes/crushing/glowstone.json new file mode 100644 index 000000000..3aaadcf6c --- /dev/null +++ b/src/main/resources/data/create/recipes/crushing/glowstone.json @@ -0,0 +1,20 @@ +{ + "type": "create:crushing", + "ingredients": [ + { + "item": "minecraft:glowstone" + } + ], + "results": [ + { + "item": "minecraft:glowstone_dust", + "count": 3 + }, + { + "item": "minecraft:glowstone_dust", + "count": 1, + "chance": 0.5 + } + ], + "processingTime": 150 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crushing/nether_wart_block.json b/src/main/resources/data/create/recipes/crushing/nether_wart_block.json new file mode 100644 index 000000000..e91740324 --- /dev/null +++ b/src/main/resources/data/create/recipes/crushing/nether_wart_block.json @@ -0,0 +1,20 @@ +{ + "type": "create:crushing", + "ingredients": [ + { + "item": "minecraft:nether_wart_block" + } + ], + "results": [ + { + "item": "minecraft:nether_wart", + "count": 6 + }, + { + "item": "minecraft:nether_wart", + "count": 2, + "chance": 0.5 + } + ], + "processingTime": 150 +} \ No newline at end of file From c62d356f9b75df4b478a9e880f98e4d415a8aab7 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Mon, 20 Apr 2020 23:27:34 +0200 Subject: [PATCH 03/11] Superglue - Added superglue, an alternative to chassis blocks - Added some random safety checks - Fixed some more bad gl states left by event handlers --- .../java/com/simibubi/create/AllEntities.java | 6 +- .../java/com/simibubi/create/AllItems.java | 6 +- .../java/com/simibubi/create/AllPackets.java | 2 + .../com/simibubi/create/config/CClient.java | 2 + .../create/config/CDamageControl.java | 9 +- .../behaviour/ValueBoxRenderer.java | 2 + .../scrollvalue/ScrollValueRenderer.java | 1 + .../foundation/gui/ScreenElementRenderer.java | 6 +- .../create/foundation/utility/Iterate.java | 1 + .../foundation/utility/RayTraceWorld.java | 37 ++ .../foundation/utility/TessellatorHelper.java | 1 - .../components/contraptions/Contraption.java | 72 +++- .../contraptions/ContraptionEntity.java | 2 +- .../contraptions/StructureTransform.java | 4 +- .../contraptions/glue/GlueEffectPacket.java | 49 +++ .../contraptions/glue/SuperGlueEntity.java | 390 ++++++++++++++++++ .../contraptions/glue/SuperGlueHandler.java | 105 +++++ .../contraptions/glue/SuperGlueItem.java | 104 +++++ .../contraptions/glue/SuperGlueRenderer.java | 125 ++++++ .../mounted/MountedContraption.java | 4 +- .../piston/PistonContraption.java | 4 +- .../crafter/ConnectedInputHandler.java | 10 +- .../crafter/MechanicalCrafterTileEntity.java | 7 +- .../relays/belt/item/BeltConnectorItem.java | 2 +- .../schematics/client/SchematicHologram.java | 1 - .../resources/assets/create/lang/en_us.json | 12 +- .../textures/entity/super_glue/ghostly.png | Bin 0 -> 367 bytes .../textures/entity/super_glue/slime.png | Bin 0 -> 588 bytes .../create/textures/item/super_glue.png | Bin 393 -> 394 bytes .../recipes/crafting_shaped/super_glue.json | 22 + 30 files changed, 946 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/utility/RayTraceWorld.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/GlueEffectPacket.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueHandler.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueItem.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java create mode 100644 src/main/resources/assets/create/textures/entity/super_glue/ghostly.png create mode 100644 src/main/resources/assets/create/textures/entity/super_glue/slime.png create mode 100644 src/main/resources/data/create/recipes/crafting_shaped/super_glue.json diff --git a/src/main/java/com/simibubi/create/AllEntities.java b/src/main/java/com/simibubi/create/AllEntities.java index 7da80aa5f..aa9af81f1 100644 --- a/src/main/java/com/simibubi/create/AllEntities.java +++ b/src/main/java/com/simibubi/create/AllEntities.java @@ -5,6 +5,8 @@ import java.util.function.Function; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer; +import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueRenderer; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityClassification; @@ -23,6 +25,8 @@ public enum AllEntities { ContraptionEntity::build), STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 40, false, ContraptionEntity::build), + SUPER_GLUE(SuperGlueEntity::new, EntityClassification.MISC, 30, Integer.MAX_VALUE, false, SuperGlueEntity::build), + ; private IFactory factory; @@ -62,8 +66,8 @@ public enum AllEntities { @OnlyIn(value = Dist.CLIENT) public static void registerRenderers() { -// RenderingRegistry.registerEntityRenderingHandler(CardboardBoxEntity.class, CardboardBoxEntityRenderer::new); RenderingRegistry.registerEntityRenderingHandler(ContraptionEntity.class, ContraptionEntityRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(SuperGlueEntity.class, SuperGlueRenderer::new); } } diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index 24df8e14d..ee2527e0d 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -16,6 +16,7 @@ import com.simibubi.create.foundation.utility.data.ITaggable; import com.simibubi.create.modules.IModule; import com.simibubi.create.modules.contraptions.GogglesItem; import com.simibubi.create.modules.contraptions.WrenchItem; +import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueItem; import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem; import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem; import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem; @@ -76,7 +77,7 @@ public enum AllItems { BRASS_INGOT(new TaggedItem().withForgeTags("ingots/brass")), FLOUR, - DOUGH, + DOUGH, OBSIDIAN_DUST, ROSE_QUARTZ, POLISHED_ROSE_QUARTZ, @@ -93,8 +94,7 @@ public enum AllItems { WHISK, BRASS_HAND, SLOT_COVER, - SUPER_GLUE, - ANTIOXIDANT, + SUPER_GLUE(SuperGlueItem::new), SAND_PAPER(SandPaperItem::new), RED_SAND_PAPER(SandPaperItem::new), WRENCH(WrenchItem::new), diff --git a/src/main/java/com/simibubi/create/AllPackets.java b/src/main/java/com/simibubi/create/AllPackets.java index a7ad8772e..45c5adb12 100644 --- a/src/main/java/com/simibubi/create/AllPackets.java +++ b/src/main/java/com/simibubi/create/AllPackets.java @@ -13,6 +13,7 @@ import com.simibubi.create.foundation.packet.SimplePacketBase; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.modules.contraptions.components.contraptions.CancelPlayerFallPacket; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionStallPacket; +import com.simibubi.create.modules.contraptions.components.contraptions.glue.GlueEffectPacket; import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket; import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket; import com.simibubi.create.modules.curiosities.zapper.ZapperBeamPacket; @@ -51,6 +52,7 @@ public enum AllPackets { CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new), CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new), TOOL_HARVEST(AbstractToolItem.HarvestPacket.class, AbstractToolItem.HarvestPacket::new), + GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new), ; diff --git a/src/main/java/com/simibubi/create/config/CClient.java b/src/main/java/com/simibubi/create/config/CClient.java index 718a2b33d..9d8a451aa 100644 --- a/src/main/java/com/simibubi/create/config/CClient.java +++ b/src/main/java/com/simibubi/create/config/CClient.java @@ -12,6 +12,8 @@ public class CClient extends ConfigBase { public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity"); public ConfigBool rainbowDebug = b(true, "enableRainbowDebug", "Show colourful debug information while the F3-Menu is open."); + public ConfigBool showHiddenSuperGlue = + b(false, "showHiddenSuperGlue", "Show indications for hidden glue between blocks while holding the item."); @Override public String getName() { diff --git a/src/main/java/com/simibubi/create/config/CDamageControl.java b/src/main/java/com/simibubi/create/config/CDamageControl.java index e62192518..5d542d203 100644 --- a/src/main/java/com/simibubi/create/config/CDamageControl.java +++ b/src/main/java/com/simibubi/create/config/CDamageControl.java @@ -5,9 +5,9 @@ public class CDamageControl extends ConfigBase { public ConfigBool freezeCrushing = b(false, "freezeCrushing", Comments.freezeCrushing); public ConfigBool freezeExtractors = b(false, "freezeExtractors", Comments.freezeExtractors); public ConfigBool freezeInWorldProcessing = b(false, "freezeInWorldProcessing", Comments.freezeInWorldProcessing); - public ConfigBool freezeRotationPropagator = b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator); - public ConfigBool freezeBearingConstructs = b(false, "freezeBearingConstructs", Comments.freezeBearingConstructs); - public ConfigBool freezePistonConstructs = b(false, "freezePistonConstructs", Comments.freezePistonConstructs); + public ConfigBool freezeRotationPropagator = + b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator); + public ConfigBool freezeContraptions = b(false, "freezeContraptions", Comments.freezeContraptions); @Override public String getName() { @@ -20,8 +20,7 @@ public class CDamageControl extends ConfigBase { static String freezeInWorldProcessing = "In case Encased Fans tried smelting your hardware."; static String freezeRotationPropagator = "Pauses rotation logic altogether - Use if crash mentions RotationPropagators."; - static String freezeBearingConstructs = "In case Mechanical Bearings turned against you."; - static String freezePistonConstructs = "In case Mechanical Pistons pushed it too far."; + static String freezeContraptions = "In case Moving contraptions pushed it too far."; } } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java index 873fa7e94..3d1eba064 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java @@ -71,6 +71,8 @@ public class ValueBoxRenderer { } box.render(highlighted); + GlStateManager.disableBlend(); + GlStateManager.disableAlphaTest(); } public static void renderText(ValueBox box, FontRenderer font, String text) { diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java index 212634da5..55d926bcb 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java @@ -60,6 +60,7 @@ public class ScrollValueRenderer { } } else render(world, pos, face, behaviour, highlight); + TessellatorHelper.cleanUpAfterDrawing(); GlStateManager.enableAlphaTest(); GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); diff --git a/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java b/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java index cd7bc5fb8..d6c11bc94 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/gui/ScreenElementRenderer.java @@ -67,10 +67,9 @@ public class ScreenElementRenderer { BlockRendererDispatcher blockRenderer = mc.getBlockRendererDispatcher(); IBakedModel modelToRender = null; BlockState blockToRender = null; - boolean stateMode = transformsAndModel == null; boolean fire = false; - if (stateMode) { + if (transformsAndModel == null) { blockToRender = transformsAndState.get(); fire = (blockToRender.getBlock() instanceof FireBlock); modelToRender = blockRenderer.getModelForState(blockToRender); @@ -81,7 +80,6 @@ public class ScreenElementRenderer { GlStateManager.scaled(50, -50, 50); mc.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); - GlStateManager.pushMatrix(); if (fire) { blockRenderer.renderBlockBrightness(blockToRender, 1); @@ -97,7 +95,7 @@ public class ScreenElementRenderer { } GlStateManager.popMatrix(); - if (stateMode && !blockToRender.getFluidState().isEmpty()) { + if (blockToRender != null && !blockToRender.getFluidState().isEmpty()) { RenderHelper.disableStandardItemLighting(); Tessellator tessellator = Tessellator.getInstance(); BufferBuilder bufferbuilder = tessellator.getBuffer(); diff --git a/src/main/java/com/simibubi/create/foundation/utility/Iterate.java b/src/main/java/com/simibubi/create/foundation/utility/Iterate.java index da562aa42..86a15ee16 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/Iterate.java +++ b/src/main/java/com/simibubi/create/foundation/utility/Iterate.java @@ -10,6 +10,7 @@ import net.minecraft.util.math.BlockPos; public class Iterate { public static final boolean[] trueAndFalse = { true, false }; + public static final int[] zeroAndOne = { 1, -1 }; public static final int[] positiveAndNegative = { 1, -1 }; public static final Direction[] directions = Direction.values(); public static final Direction[] horizontalDirections = getHorizontals(); diff --git a/src/main/java/com/simibubi/create/foundation/utility/RayTraceWorld.java b/src/main/java/com/simibubi/create/foundation/utility/RayTraceWorld.java new file mode 100644 index 000000000..858da32eb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/RayTraceWorld.java @@ -0,0 +1,37 @@ +package com.simibubi.create.foundation.utility; + +import java.util.function.BiFunction; + +import net.minecraft.block.BlockState; +import net.minecraft.fluid.IFluidState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorld; + +public class RayTraceWorld implements IBlockReader { + + private IWorld template; + private BiFunction stateGetter; + + public RayTraceWorld(IWorld template, BiFunction stateGetter) { + this.template = template; + this.stateGetter = stateGetter; + } + + @Override + public TileEntity getTileEntity(BlockPos pos) { + return template.getTileEntity(pos); + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return stateGetter.apply(pos, template.getBlockState(pos)); + } + + @Override + public IFluidState getFluidState(BlockPos pos) { + return template.getFluidState(pos); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java index 724452f80..1ebc38283 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java @@ -69,7 +69,6 @@ public class TessellatorHelper { public static void cleanUpAfterDrawing() { GlStateManager.popAttributes(); GlStateManager.popMatrix(); - GlStateManager.disableAlphaTest(); GlStateManager.disableBlend(); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java index a272f87c0..62aed5140 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java @@ -25,14 +25,16 @@ import com.simibubi.create.foundation.utility.WrappedWorld; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueHandler; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock; -import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity; import com.simibubi.create.modules.contraptions.components.saw.SawBlock; import com.simibubi.create.modules.contraptions.redstone.ContactBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; @@ -74,6 +76,7 @@ public abstract class Contraption { public List> actors; public CombinedInvWrapper inventory; public List customRenderTEs; + public Set> superglue; public AxisAlignedBB bounds; public boolean stalled; @@ -83,13 +86,16 @@ public abstract class Contraption { protected BlockPos anchor; List renderOrder; + List glueToRemove; public Contraption() { blocks = new HashMap<>(); storage = new HashMap<>(); actors = new ArrayList<>(); + superglue = new HashSet<>(); renderOrder = new ArrayList<>(); customRenderTEs = new ArrayList<>(); + glueToRemove = new ArrayList<>(); } public Set getColliders(World world, Direction movementDirection) { @@ -242,6 +248,8 @@ public abstract class Contraption { frontier.add(otherPartPos); } + Map superglue = SuperGlueHandler.gatherGlue(world, pos); + // Slime blocks drag adjacent blocks if possible boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock; for (Direction offset : Direction.values()) { @@ -254,9 +262,18 @@ public abstract class Contraption { return false; continue; } - if (!visited.contains(offsetPos) && ((isSlimeBlock && !BlockMovementTraits.isBrittle(blockState)) - || BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()))) + + boolean wasVisited = visited.contains(offsetPos); + boolean faceHasGlue = superglue.containsKey(offset); + boolean blockAttachedTowardsFace = + BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()); + boolean brittle = BlockMovementTraits.isBrittle(blockState); + + if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue)) frontier.add(offsetPos); + + if (faceHasGlue) + addGlue(superglue.get(offset)); } add(pos, capture(world, pos)); @@ -325,6 +342,14 @@ public abstract class Contraption { return compoundnbt; } + public void addGlue(SuperGlueEntity entity) { + BlockPos pos = entity.getHangingPosition(); + Direction direction = entity.getFacingDirection(); + BlockPos localPos = pos.subtract(anchor); + this.superglue.add(Pair.of(localPos, direction)); + glueToRemove.add(entity); + } + public void add(BlockPos pos, Pair pair) { BlockInfo captured = pair.getKey(); BlockPos localPos = pos.subtract(anchor); @@ -402,6 +427,13 @@ public abstract class Contraption { getActors().add(MutablePair.of(info, context)); }); + superglue.clear(); + nbt.getList("Superglue", 10).forEach(c -> { + CompoundNBT comp = (CompoundNBT) c; + superglue.add(Pair.of(NBTUtil.readBlockPos(comp.getCompound("Pos")), + Direction.byIndex(comp.getByte("Direction")))); + }); + storage.clear(); nbt.getList("Storage", 10).forEach(c -> { CompoundNBT comp = (CompoundNBT) c; @@ -440,6 +472,14 @@ public abstract class Contraption { actorsNBT.add(compound); } + ListNBT superglueNBT = new ListNBT(); + for (Pair glueEntry : superglue) { + CompoundNBT c = new CompoundNBT(); + c.put("Pos", NBTUtil.writeBlockPos(glueEntry.getKey())); + c.putByte("Direction", (byte) glueEntry.getValue().getIndex()); + superglueNBT.add(c); + } + ListNBT storageNBT = new ListNBT(); for (BlockPos pos : storage.keySet()) { CompoundNBT c = new CompoundNBT(); @@ -453,6 +493,7 @@ public abstract class Contraption { nbt.put("Blocks", blocksNBT); nbt.put("Actors", actorsNBT); + nbt.put("Superglue", superglueNBT); nbt.put("Storage", storageNBT); nbt.put("Anchor", NBTUtil.writeBlockPos(anchor)); nbt.putBoolean("Stalled", stalled); @@ -466,11 +507,7 @@ public abstract class Contraption { } public static boolean isFrozen() { - return AllConfigs.SERVER.control.freezePistonConstructs.get(); - } - - public void disassemble(World world, BlockPos offset, Vec3d rotation) { - disassemble(world, offset, rotation, (pos, state) -> false); + return AllConfigs.SERVER.control.freezeContraptions.get(); } public void removeBlocksFromWorld(IWorld world, BlockPos offset) { @@ -479,6 +516,8 @@ public abstract class Contraption { public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate customRemoval) { storage.values().forEach(MountedStorage::empty); + glueToRemove.forEach(SuperGlueEntity::remove); + for (boolean brittles : Iterate.trueAndFalse) { for (BlockInfo block : blocks.values()) { if (brittles != BlockMovementTraits.isBrittle(block.state)) @@ -496,7 +535,11 @@ public abstract class Contraption { } } - public void disassemble(World world, BlockPos offset, Vec3d rotation, + public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) { + addBlocksToWorld(world, offset, rotation, (pos, state) -> false); + } + + public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation, BiPredicate customPlacement) { stop(world); @@ -558,10 +601,21 @@ public abstract class Contraption { mountedStorage.fill(tileEntity); } } + } + } + for (Pair pair : superglue) { + BlockPos targetPos = transform.apply(pair.getKey()); + Direction targetFacing = transform.transformFacing(pair.getValue()); + + SuperGlueEntity entity = new SuperGlueEntity(world, targetPos, targetFacing); + if (entity.onValidSurface()) { + if (!world.isRemote) + world.addEntity(entity); } } + } public void initActors(World world) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index bf2655afc..6e4f01a95 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -427,7 +427,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (getContraption() != null) { BlockPos offset = new BlockPos(getPositionVec().add(.5, .5, .5)); Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1)); - getContraption().disassemble(world, offset, rotation); + getContraption().addBlocksToWorld(world, offset, rotation); preventMovedEntitiesFromGettingStuck(); } remove(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java index f685d9719..3277964a8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java @@ -162,14 +162,14 @@ public class StructureTransform { return state; } - protected Axis transformAxis(Axis axisIn) { + public Axis transformAxis(Axis axisIn) { Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axisIn); facing = transformFacing(facing); Axis axis = facing.getAxis(); return axis; } - protected Direction transformFacing(Direction facing) { + public Direction transformFacing(Direction facing) { for (int i = 0; i < rotation.ordinal(); i++) facing = facing.rotateAround(rotationAxis); return facing; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/GlueEffectPacket.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/GlueEffectPacket.java new file mode 100644 index 000000000..02dfe0b48 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/GlueEffectPacket.java @@ -0,0 +1,49 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.glue; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.packet.SimplePacketBase; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class GlueEffectPacket extends SimplePacketBase { + + private BlockPos pos; + private Direction direction; + private boolean fullBlock; + + public GlueEffectPacket(BlockPos pos, Direction direction, boolean fullBlock) { + this.pos = pos; + this.direction = direction; + this.fullBlock = fullBlock; + } + + public GlueEffectPacket(PacketBuffer buffer) { + pos = buffer.readBlockPos(); + direction = Direction.byIndex(buffer.readByte()); + fullBlock = buffer.readBoolean(); + } + + public void write(PacketBuffer buffer) { + buffer.writeBlockPos(pos); + buffer.writeByte(direction.getIndex()); + buffer.writeBoolean(fullBlock); + } + + public void handle(Supplier context) { + context.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { + Minecraft mc = Minecraft.getInstance(); + if (!mc.player.getPosition().withinDistance(pos, 100)) + return; + SuperGlueItem.spawnParticles(mc.world, pos, direction, fullBlock); + })); + context.get().setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java new file mode 100644 index 000000000..e21d2cb27 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java @@ -0,0 +1,390 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.glue; + +import javax.annotation.Nullable; + +import org.apache.commons.lang3.Validate; + +import com.simibubi.create.AllEntities; +import com.simibubi.create.AllItems; +import com.simibubi.create.AllPackets; +import com.simibubi.create.AllSoundEvents; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntitySize; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.MoverType; +import net.minecraft.entity.Pose; +import net.minecraft.entity.effect.LightningBoltEntity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.IPacket; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.DamageSource; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Hand; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; +import net.minecraftforge.fml.network.NetworkHooks; +import net.minecraftforge.fml.network.PacketDistributor; + +public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData { + + private int validationTimer; + protected BlockPos hangingPosition; + protected Direction facingDirection = Direction.SOUTH; + + public SuperGlueEntity(EntityType type, World world) { + super(type, world); + } + + public SuperGlueEntity(World world, BlockPos pos, Direction direction) { + this(AllEntities.SUPER_GLUE.type, world); + hangingPosition = pos; + facingDirection = direction; + updateFacingWithBoundingBox(); + } + + @Override + protected void registerData() {} + + public int getWidthPixels() { + return 12; + } + + public int getHeightPixels() { + return 12; + } + + public void onBroken(@Nullable Entity breaker) { + playSound(SoundEvents.ENTITY_SLIME_SQUISH_SMALL, 1.0F, 1.0F); + if (onValidSurface()) { + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), + new GlueEffectPacket(getHangingPosition(), getFacingDirection().getOpposite(), false)); + playSound(AllSoundEvents.SLIME_ADDED.get(), 0.5F, 0.5F); + } + } + + public void playPlaceSound() { + playSound(AllSoundEvents.SLIME_ADDED.get(), 0.5F, 0.75F); + } + + protected void updateFacingWithBoundingBox() { + Validate.notNull(getFacingDirection()); + if (getFacingDirection().getAxis().isHorizontal()) { + this.rotationPitch = 0.0F; + this.rotationYaw = getFacingDirection().getHorizontalIndex() * 90; + } else { + this.rotationPitch = -90 * getFacingDirection().getAxisDirection().getOffset(); + this.rotationYaw = 0.0F; + } + + this.prevRotationPitch = this.rotationPitch; + this.prevRotationYaw = this.rotationYaw; + this.updateBoundingBox(); + } + + protected void updateBoundingBox() { + if (this.getFacingDirection() != null) { + this.posX = + (double) this.hangingPosition.getX() + 0.5 - (double) this.getFacingDirection().getXOffset() * 0.5; + this.posY = + (double) this.hangingPosition.getY() + 0.5 - (double) this.getFacingDirection().getYOffset() * 0.5; + this.posZ = + (double) this.hangingPosition.getZ() + 0.5 - (double) this.getFacingDirection().getZOffset() * 0.5; + double d1 = (double) this.getWidthPixels(); + double d2 = (double) this.getHeightPixels(); + double d3 = (double) this.getWidthPixels(); + Axis axis = this.getFacingDirection().getAxis(); + double depth = 2 - 1 / 128f; + + switch (axis) { + case X: + d1 = depth; + break; + case Y: + d2 = depth; + break; + case Z: + d3 = depth; + } + + d1 = d1 / 32.0D; + d2 = d2 / 32.0D; + d3 = d3 / 32.0D; + this.setBoundingBox(new AxisAlignedBB(this.posX - d1, this.posY - d2, this.posZ - d3, this.posX + d1, + this.posY + d2, this.posZ + d3)); + } + } + + @Override + public void tick() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + if (this.validationTimer++ == 10 && !this.world.isRemote) { + this.validationTimer = 0; + if (isAlive() && !this.onValidSurface()) { + remove(); + onBroken(null); + } + } + + } + + public boolean onValidSurface() { + BlockPos pos = hangingPosition; + BlockPos pos2 = hangingPosition.offset(getFacingDirection().getOpposite()); + if (!world.isAreaLoaded(pos, 0) || !world.isAreaLoaded(pos2, 0)) + return true; + if (world.isAirBlock(pos) && world.isAirBlock(pos2)) + return false; + return world.getEntitiesInAABBexcluding(this, getBoundingBox(), e -> e instanceof SuperGlueEntity).isEmpty(); + } + + @Override + public boolean canBeCollidedWith() { + return true; + } + + @Override + public boolean hitByEntity(Entity entity) { + return entity instanceof PlayerEntity + ? attackEntityFrom(DamageSource.causePlayerDamage((PlayerEntity) entity), 0) + : false; + } + + @Override + public Direction getHorizontalFacing() { + return this.getFacingDirection(); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + if (this.isInvulnerableTo(source)) + return false; + if (isAlive() && !world.isRemote) { + remove(); + markVelocityChanged(); + onBroken(source.getTrueSource()); + } + + return true; + } + + @Override + public void move(MoverType typeIn, Vec3d pos) { + if (!world.isRemote && isAlive() && pos.lengthSquared() > 0.0D) { + remove(); + onBroken(null); + } + } + + @Override + public void addVelocity(double x, double y, double z) { + if (!world.isRemote && isAlive() && x * x + y * y + z * z > 0.0D) { + remove(); + onBroken(null); + } + } + + @Override + protected float getEyeHeight(Pose poseIn, EntitySize sizeIn) { + return 0.0F; + } + + @Override + public ItemStack getPickedResult(RayTraceResult target) { + return AllItems.SUPER_GLUE.asStack(); + } + + @Override + @OnlyIn(Dist.CLIENT) + public int getBrightnessForRender() { + BlockPos blockpos = hangingPosition; + BlockPos blockpos2 = blockpos.offset(this.getFacingDirection().getOpposite()); + + PlayerEntity player = Minecraft.getInstance().player; + boolean holdingGlue = AllItems.SUPER_GLUE.typeOf(player.getHeldItemMainhand()) + || AllItems.SUPER_GLUE.typeOf(player.getHeldItemOffhand()); + boolean visible = world.isAirBlock(blockpos) || world.isAirBlock(blockpos2); + + int minLight = holdingGlue && !visible ? 8 : 0; + int light = this.world.isBlockPresent(blockpos) ? this.world.getCombinedLight(blockpos, minLight) : 15; + int light2 = this.world.isBlockPresent(blockpos2) ? this.world.getCombinedLight(blockpos2, minLight) : 15; + + return Math.max(light, light2); + } + + @Override + public void applyEntityCollision(Entity entityIn) { + super.applyEntityCollision(entityIn); + } + + @Override + public boolean processInitialInteract(PlayerEntity player, Hand hand) { + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { + triggerPlaceBlock(player, hand); + }); + return true; + } + + @OnlyIn(Dist.CLIENT) + private void triggerPlaceBlock(PlayerEntity player, Hand hand) { + if (player instanceof ClientPlayerEntity && player.world instanceof ClientWorld) { + ClientPlayerEntity cPlayer = (ClientPlayerEntity) player; + Minecraft mc = Minecraft.getInstance(); + RayTraceResult ray = + cPlayer.pick(mc.playerController.getBlockReachDistance(), mc.getRenderPartialTicks(), false); + if (ray instanceof BlockRayTraceResult) { + for (Hand handIn : Hand.values()) { + ItemStack itemstack = cPlayer.getHeldItem(handIn); + int countBefore = itemstack.getCount(); + ActionResultType actionResultType = mc.playerController.func_217292_a(cPlayer, + (ClientWorld) cPlayer.world, handIn, (BlockRayTraceResult) ray); + if (actionResultType == ActionResultType.SUCCESS) { + cPlayer.swingArm(handIn); + if (!itemstack.isEmpty() + && (itemstack.getCount() != countBefore || mc.playerController.isInCreativeMode())) + mc.gameRenderer.itemRenderer.resetEquippedProgress(handIn); + return; + } + } + } + } + } + + @Override + public void writeAdditional(CompoundNBT compound) { + compound.putByte("Facing", (byte) this.getFacingDirection().getIndex()); + BlockPos blockpos = this.getHangingPosition(); + compound.putInt("TileX", blockpos.getX()); + compound.putInt("TileY", blockpos.getY()); + compound.putInt("TileZ", blockpos.getZ()); + } + + @Override + public void readAdditional(CompoundNBT compound) { + this.hangingPosition = + new BlockPos(compound.getInt("TileX"), compound.getInt("TileY"), compound.getInt("TileZ")); + this.facingDirection = Direction.byIndex(compound.getByte("Facing")); + updateFacingWithBoundingBox(); + } + + @Override + public ItemEntity entityDropItem(ItemStack stack, float offsetY) { + ItemEntity itementity = + new ItemEntity(this.world, this.posX + (double) ((float) this.getFacingDirection().getXOffset() * 0.15F), + this.posY + (double) offsetY, + this.posZ + (double) ((float) this.getFacingDirection().getZOffset() * 0.15F), stack); + itementity.setDefaultPickupDelay(); + this.world.addEntity(itementity); + return itementity; + } + + @Override + protected boolean shouldSetPosAfterLoading() { + return false; + } + + @Override + public void setPosition(double x, double y, double z) { + hangingPosition = new BlockPos(x, y, z); + updateBoundingBox(); + isAirBorne = true; + } + + @Override + public float getRotatedYaw(Rotation transformRotation) { + if (this.getFacingDirection().getAxis() != Direction.Axis.Y) { + switch (transformRotation) { + case CLOCKWISE_180: + this.facingDirection = this.getFacingDirection().getOpposite(); + break; + case COUNTERCLOCKWISE_90: + this.facingDirection = this.getFacingDirection().rotateYCCW(); + break; + case CLOCKWISE_90: + this.facingDirection = this.getFacingDirection().rotateY(); + default: + break; + } + } + + float f = MathHelper.wrapDegrees(this.rotationYaw); + switch (transformRotation) { + case CLOCKWISE_180: + return f + 180.0F; + case COUNTERCLOCKWISE_90: + return f + 90.0F; + case CLOCKWISE_90: + return f + 270.0F; + default: + return f; + } + } + + public BlockPos getHangingPosition() { + return this.hangingPosition; + } + + @Override + public float getMirroredYaw(Mirror transformMirror) { + return this.getRotatedYaw(transformMirror.toRotation(this.getFacingDirection())); + } + + public Direction getAttachedDirection(BlockPos pos) { + return !pos.equals(hangingPosition) ? getFacingDirection() : getFacingDirection().getOpposite(); + } + + @Override + public void onStruckByLightning(LightningBoltEntity lightningBolt) {} + + @Override + public void recalculateSize() {} + + public static EntityType.Builder build(EntityType.Builder builder) { + @SuppressWarnings("unchecked") + EntityType.Builder entityBuilder = (EntityType.Builder) builder; + return entityBuilder; + } + + @Override + public IPacket createSpawnPacket() { + return NetworkHooks.getEntitySpawningPacket(this); + } + + @Override + public void writeSpawnData(PacketBuffer buffer) { + CompoundNBT compound = new CompoundNBT(); + writeAdditional(compound); + buffer.writeCompoundTag(compound); + } + + @Override + public void readSpawnData(PacketBuffer additionalData) { + readAdditional(additionalData.readCompoundTag()); + } + + public Direction getFacingDirection() { + return facingDirection; + } +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueHandler.java new file mode 100644 index 000000000..239240eae --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueHandler.java @@ -0,0 +1,105 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.glue; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.simibubi.create.AllItems; +import com.simibubi.create.AllPackets; +import com.simibubi.create.foundation.utility.RayTraceWorld; + +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +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.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; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import net.minecraftforge.fml.network.PacketDistributor; + +@EventBusSubscriber +public class SuperGlueHandler { + + public static Map gatherGlue(IWorld world, BlockPos pos) { + List entities = world.getEntitiesWithinAABB(SuperGlueEntity.class, new AxisAlignedBB(pos)); + Map map = new HashMap<>(); + for (SuperGlueEntity entity : entities) + map.put(entity.getAttachedDirection(pos), entity); + return map; + } + + @SubscribeEvent + public static void glueListensForBlockPlacement(EntityPlaceEvent event) { + IWorld world = event.getWorld(); + Entity entity = event.getEntity(); + BlockPos pos = event.getPos(); + + if (entity == null || world == null || pos == null) + return; + if (event.isCanceled()) + return; + if (world.isRemote()) + return; + + Map gatheredGlue = gatherGlue(world, pos); + for (Direction direction : gatheredGlue.keySet()) + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity), + new GlueEffectPacket(pos, direction, true)); + + if (entity instanceof PlayerEntity) + glueInOffHandAppliesOnBlockPlace(event, pos, (PlayerEntity) entity); + } + + public static void glueInOffHandAppliesOnBlockPlace(EntityPlaceEvent event, BlockPos pos, PlayerEntity placer) { + ItemStack itemstack = placer.getHeldItemOffhand(); + if (!AllItems.SUPER_GLUE.typeOf(itemstack)) + return; + + double distance = placer.getAttribute(PlayerEntity.REACH_DISTANCE).getValue(); + Vec3d start = placer.getEyePosition(1); + Vec3d look = placer.getLook(1); + Vec3d end = start.add(look.x * distance, look.y * distance, look.z * distance); + World world = placer.world; + + RayTraceWorld rayTraceWorld = + new RayTraceWorld(world, (p, state) -> p.equals(pos) ? Blocks.AIR.getDefaultState() : state); + BlockRayTraceResult ray = rayTraceWorld.rayTraceBlocks(new RayTraceContext(start, end, + RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, placer)); + + Direction face = ray.getFace(); + if (ray == null || face == null || ray.getType() == Type.MISS) + return; + + if (!ray.getPos().offset(face).equals(pos)) { + event.setCanceled(true); + return; + } + + SuperGlueEntity entity = new SuperGlueEntity(world, ray.getPos(), face.getOpposite()); + CompoundNBT compoundnbt = itemstack.getTag(); + if (compoundnbt != null) + EntityType.applyItemNBT(world, placer, entity, compoundnbt); + + if (entity.onValidSurface()) { + if (!world.isRemote) { + entity.playPlaceSound(); + world.addEntity(entity); + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity), + new GlueEffectPacket(ray.getPos(), face, true)); + } + itemstack.damageItem(1, placer, SuperGlueItem::onBroken); + } + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueItem.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueItem.java new file mode 100644 index 000000000..d2668b9be --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueItem.java @@ -0,0 +1,104 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.glue; + +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; +import net.minecraft.item.Items; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.particles.ItemParticleData; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public class SuperGlueItem extends Item { + + public SuperGlueItem(Properties properties) { + super(properties); + } + + @Override + public boolean isDamageable() { + return true; + } + + @Override + public int getMaxDamage(ItemStack stack) { + return 99; + } + + @Override + public int getItemStackLimit(ItemStack stack) { + return 1; + } + + @Override + public ActionResultType onItemUse(ItemUseContext context) { + BlockPos blockpos = context.getPos(); + Direction direction = context.getFace(); + BlockPos blockpos1 = blockpos.offset(direction); + PlayerEntity playerentity = context.getPlayer(); + ItemStack itemstack = context.getItem(); + + if (playerentity != null && !this.canPlace(playerentity, direction, itemstack, blockpos1)) + return ActionResultType.FAIL; + + World world = context.getWorld(); + SuperGlueEntity entity = new SuperGlueEntity(world, blockpos1, direction); + CompoundNBT compoundnbt = itemstack.getTag(); + if (compoundnbt != null) + EntityType.applyItemNBT(world, playerentity, entity, compoundnbt); + + if (!entity.onValidSurface()) + return ActionResultType.FAIL; + + if (!world.isRemote) { + entity.playPlaceSound(); + world.addEntity(entity); + } + itemstack.damageItem(1, playerentity, SuperGlueItem::onBroken); + + return ActionResultType.SUCCESS; + } + + public static void onBroken(PlayerEntity player) { + + } + + protected boolean canPlace(PlayerEntity entity, Direction facing, ItemStack stack, BlockPos pos) { + return !World.isOutsideBuildHeight(pos) && entity.canPlayerEdit(pos, facing, stack); + } + + @OnlyIn(Dist.CLIENT) + public static void spawnParticles(World world, BlockPos pos, Direction direction, boolean fullBlock) { + Vec3d vec = new Vec3d(direction.getDirectionVec()); + Vec3d plane = VecHelper.planeByNormal(vec); + Vec3d facePos = VecHelper.getCenterOf(pos).add(vec.scale(.5f)); + + float distance = fullBlock ? 1f : .25f + .25f * (world.rand.nextFloat() - .5f); + plane = plane.scale(distance); + ItemStack stack = new ItemStack(Items.SLIME_BALL); + + for (int i = fullBlock ? 40 : 15; i > 0; i--) { + Vec3d offset = VecHelper.rotate(plane, 360 * world.rand.nextFloat(), direction.getAxis()); + Vec3d motion = offset.normalize().scale(1 / 16f); + if (fullBlock) + offset = new Vec3d(MathHelper.clamp(offset.x, -.5, .5), MathHelper.clamp(offset.y, -.5, .5), + MathHelper.clamp(offset.z, -.5, .5)); + Vec3d particlePos = facePos.add(offset); + world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), particlePos.x, particlePos.y, + particlePos.z, motion.x, motion.y, motion.z); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java new file mode 100644 index 000000000..2e595f9d0 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java @@ -0,0 +1,125 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.glue; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllItems; +import com.simibubi.create.Create; +import com.simibubi.create.config.AllConfigs; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.client.renderer.model.PositionTextureVertex; +import net.minecraft.client.renderer.model.TexturedQuad; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class SuperGlueRenderer extends EntityRenderer { + + private ResourceLocation regular = new ResourceLocation(Create.ID, "textures/entity/super_glue/slime.png"); + private ResourceLocation ghostly = new ResourceLocation(Create.ID, "textures/entity/super_glue/ghostly.png"); + + private TexturedQuad quad1; + private TexturedQuad quad2; + + public SuperGlueRenderer(EntityRendererManager renderManager) { + super(renderManager); + initQuads(); + } + + @Override + protected ResourceLocation getEntityTexture(SuperGlueEntity entity) { + return isVisible(entity) ? regular : ghostly; + } + + @Override + public void doRender(SuperGlueEntity entity, double x, double y, double z, float entityYaw, float partialTicks) { + Direction facing = entity.getFacingDirection(); + PlayerEntity player = Minecraft.getInstance().player; + + boolean visible = isVisible(entity); + boolean holdingGlue = AllItems.SUPER_GLUE.typeOf(player.getHeldItemMainhand()) + || AllItems.SUPER_GLUE.typeOf(player.getHeldItemOffhand()); + holdingGlue = holdingGlue && AllConfigs.CLIENT.showHiddenSuperGlue.get(); + + if (!visible && !holdingGlue) + return; + + GlStateManager.pushMatrix(); + GlStateManager.translated(x, y, z); + GlStateManager.rotated(AngleHelper.horizontalAngle(facing), 0, 1, 0); + GlStateManager.rotated(AngleHelper.verticalAngle(facing), 1, 0, 0); + + BufferBuilder buffer = Tessellator.getInstance().getBuffer(); + bindEntityTexture(entity); + + if (!visible) { + GlStateManager.color4f(1, 1, 1, 0.375f); + GlStateManager.enableBlend(); + GlStateManager.disableDepthTest(); + } + + quad1.draw(buffer, 1); + quad2.draw(buffer, 1); + + GlStateManager.disableBlend(); + GlStateManager.enableDepthTest(); + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.popMatrix(); + } + + private boolean isVisible(SuperGlueEntity entity) { + if (!entity.isAlive()) + return false; + BlockPos pos = entity.hangingPosition; + BlockPos pos2 = pos.offset(entity.getFacingDirection().getOpposite()); + return entity.world.isAirBlock(pos) != entity.world.isAirBlock(pos2); + } + + private void initQuads() { + Vec3d diff = new Vec3d(Direction.SOUTH.getDirectionVec()); + Vec3d extension = diff.normalize().scale(1 / 32f - 1 / 128f); + Vec3d plane = VecHelper.planeByNormal(diff); + Axis axis = Direction.getFacingFromVector(diff.x, diff.y, diff.z).getAxis(); + + Vec3d start = Vec3d.ZERO.subtract(extension); + Vec3d end = Vec3d.ZERO.add(extension); + + plane = plane.scale(1 / 2f); + Vec3d a1 = plane.add(start); + Vec3d b1 = plane.add(end); + plane = VecHelper.rotate(plane, -90, axis); + Vec3d a2 = plane.add(start); + Vec3d b2 = plane.add(end); + plane = VecHelper.rotate(plane, -90, axis); + Vec3d a3 = plane.add(start); + Vec3d b3 = plane.add(end); + plane = VecHelper.rotate(plane, -90, axis); + Vec3d a4 = plane.add(start); + Vec3d b4 = plane.add(end); + + PositionTextureVertex v11 = new PositionTextureVertex(a1, 1, 0); + PositionTextureVertex v12 = new PositionTextureVertex(a2, 1, 1); + PositionTextureVertex v13 = new PositionTextureVertex(a3, 0, 1); + PositionTextureVertex v14 = new PositionTextureVertex(a4, 0, 0); + + PositionTextureVertex v21 = new PositionTextureVertex(b1, 1, 0); + PositionTextureVertex v22 = new PositionTextureVertex(b2, 1, 1); + PositionTextureVertex v23 = new PositionTextureVertex(b3, 0, 1); + PositionTextureVertex v24 = new PositionTextureVertex(b4, 0, 0); + + quad1 = new TexturedQuad(new PositionTextureVertex[] { v14, v11, v12, v13 }, 0, 0, 16, 16, 16, 16); + quad2 = new TexturedQuad(new PositionTextureVertex[] { v21, v24, v23, v22 }, 0, 0, 16, 16, 16, 16); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java index 610577738..fd6697d7d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java @@ -89,8 +89,8 @@ public class MountedContraption extends Contraption { } @Override - public void disassemble(World world, BlockPos offset, Vec3d rotation) { - super.disassemble(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state)); + public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) { + super.addBlocksToWorld(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state)); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java index 0d115e2e7..33e754a46 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java @@ -170,8 +170,8 @@ public class PistonContraption extends Contraption { } @Override - public void disassemble(World world, BlockPos offset, Vec3d rotation) { - super.disassemble(world, offset, rotation, (pos, state) -> { + public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) { + super.addBlocksToWorld(world, offset, rotation, (pos, state) -> { BlockPos pistonPos = anchor.offset(orientation, -1); BlockState pistonState = world.getBlockState(pistonPos); TileEntity te = world.getTileEntity(pistonPos); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/ConnectedInputHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/ConnectedInputHandler.java index 7133fb0fd..672579ef3 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/ConnectedInputHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/ConnectedInputHandler.java @@ -6,6 +6,7 @@ import static com.simibubi.create.modules.contraptions.base.HorizontalKineticBlo import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -137,8 +138,8 @@ public class ConnectedInputHandler { if (controllerPos1.equals(controllerPos2)) { MechanicalCrafterTileEntity controller = CrafterHelper.getCrafter(world, controllerPos1); - Set positions = controller.input.data.stream().map(l -> controllerPos1.add(l)) - .collect(Collectors.toSet()); + Set positions = + controller.input.data.stream().map(l -> controllerPos1.add(l)).collect(Collectors.toSet()); List frontier = new LinkedList<>(); List splitGroup = new ArrayList<>(); @@ -198,8 +199,7 @@ public class ConnectedInputHandler { crafter1.input.data.forEach(offset -> { BlockPos connectedPos = crafter1.getPos().add(offset); - modifyAndUpdate(world, connectedPos, input -> { - }); + modifyAndUpdate(world, connectedPos, input -> {}); }); crafter2.input.data.forEach(offset -> { @@ -229,7 +229,7 @@ public class ConnectedInputHandler { public static class ConnectedInput { boolean isController; - List data = new ArrayList<>(); + List data = Collections.synchronizedList(new ArrayList<>()); public ConnectedInput() { isController = true; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java index 0a538eb5b..f9be57d87 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntity.java @@ -20,6 +20,7 @@ import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCra import com.simibubi.create.modules.contraptions.components.crafter.RecipeGridHandler.GroupedItems; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; +import net.minecraft.block.BlockState; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; @@ -357,8 +358,10 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { } public void eject() { - Vec3d ejectPos = VecHelper.getCenterOf(pos) - .add(new Vec3d(getBlockState().get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f)); + BlockState blockState = getBlockState(); + boolean present = AllBlocks.MECHANICAL_CRAFTER.typeOf(blockState); + Vec3d vec = present ? new Vec3d(blockState.get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f) : Vec3d.ZERO; + Vec3d ejectPos = VecHelper.getCenterOf(pos).add(vec); groupedItems.grid.forEach((pair, stack) -> dropItem(ejectPos, stack)); if (!inventory.getStackInSlot(0).isEmpty()) dropItem(ejectPos, inventory.getStackInSlot(0)); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/item/BeltConnectorItem.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/item/BeltConnectorItem.java index 2dbdf0aa7..5adcbd64d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/item/BeltConnectorItem.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/item/BeltConnectorItem.java @@ -71,7 +71,7 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther { if (!canConnect(world, firstPulley, pos)) return ActionResultType.FAIL; - if (!firstPulley.equals(pos)) { + if (firstPulley != null && !firstPulley.equals(pos)) { createBelts(world, firstPulley, pos); if (!context.getPlayer().isCreative()) diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java index 8f5f13f4b..d0b973cdc 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java @@ -166,7 +166,6 @@ public class SchematicHologram { drawBuffer(bufferBuilder); GlStateManager.popMatrix(); } - GlStateManager.disableAlphaTest(); GlStateManager.disableBlend(); } } diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index e39994cc4..3336eb56a 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -37,7 +37,6 @@ "item.create.sand_paper": "Sand Paper", "item.create.red_sand_paper": "Red Sand Paper", "item.create.super_glue": "Super Glue", - "item.create.antioxidant": "Antioxidant Spray", "item.create.brass_ingot": "Brass Ingot", "item.create.brass_sheet": "Brass Sheets", @@ -258,6 +257,10 @@ "block.create.creative_crate": "Schematicannon Creatifier", "block.create.cocoa_log": "Cocoa Jungle Log", + + "entity.create.contraption": "Moving Contraption", + "entity.create.stationary_contraption": "Stationary Contraption", + "entity.create.super_glue": "Superglue", "_comment": "-------------------------] UI & MESSAGES [------------------------------------------------", @@ -1136,6 +1139,13 @@ "tool.create.sand_paper.tooltip.summary": "A rough paper that can be used to _polish_ _materials_. Can be automatically applied using the Deployer.", "tool.create.sand_paper.tooltip.condition1": "When Used", "tool.create.sand_paper.tooltip.behaviour1": "Applies polish to items held in the _offhand_ or lying on the _floor_ when _looking_ _at_ _them_", + + "item.create.super_glue.tooltip": "SUPER GLUE", + "item.create.super_glue.tooltip.summary": "Glue a block to another, and they will forever be inseparable.", + "item.create.super_glue.tooltip.condition1": "When Used", + "item.create.super_glue.tooltip.behaviour1": "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": "When Held in Offhand", + "item.create.super_glue.tooltip.behaviour2": "_Automatically_ _attaches_ blocks placed from the main hand to the _side_ they were _placed_ _against._", "item.create.refined_radiance.tooltip": "REFINED RADIANCE", "item.create.refined_radiance.tooltip.summary": "A Chromatic material forged from _absorbed_ _light_.", diff --git a/src/main/resources/assets/create/textures/entity/super_glue/ghostly.png b/src/main/resources/assets/create/textures/entity/super_glue/ghostly.png new file mode 100644 index 0000000000000000000000000000000000000000..8a2efeeca5f116ac9515a6a5318f5c4095451377 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1en1B<7NV~B=h_qjQm#0Bo``lcXv zPP&8r;#_utSWP__M}a%bJ|A+i%3XLttnR_Y6sLPnQYHFlzLfsG`CsyH-Ge5+dvv%> zJ{s`cG3kBrdY9k1iPKYGW|VQ9`>b;R`$?0@nG1AI+sw(o?RLB{V3Nv|WtyU{g%fM` z9_eOKW_NT*l&E^tZ;reX9OW*evo_W2C>&qKG@%YfGR~XVeFXTC2Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0pUqRK~y+TWBmXB zKLaIz2}+XY5CPFCJj{{P-Kg!y8W+44l*$Bss+xF5iC$ngQ}JagRZR#gGrP&+}S8zFiFz3Se(^fS__+c9K{nsIdK;`6M8m-PSzEw{fLyS% z_Xs=;P`uz!YW)Ap+iy@F1K1lNKFC`jZ@}b0E(J4y0B!&%U@Q{!861q9!M1|{$X1I8 zL$J*t0Q1(N)yLtkKuJg-g)q$^|AN32w`GhVuYmYqZ(X^C-wUq6PGH4XcHaa$8RiWT z;03b(0oA{|^_k)FrrTgc;0AzFo1483!yhg-24!6xh6C_~^q4`%Rh>bKM~Xp%TZAD< zzk*TMPxU{B0U!V}gk6}G;pf}m4DW$S7Z%rkz*PGG9|Oa$_rDoH@|&vmWA_3%fWq9! azyJVoIQQM@e4aD_0000=AhJ+qE7YsAj%7ok>4E*ASyHA1`G@U8Zbb#<09t? P00000NkvXXu0mjf!DA!? delta 108 zcmV-y0F(cU1BnBWNl3#001m?e$8V@)0003VNkl Date: Mon, 27 Apr 2020 14:04:06 +0200 Subject: [PATCH 04/11] Better Schematics - Visual rework to Schematic items and their interface - Written Schematics can now be re-used in Schematic Tables - Schematic and Quill selection is now smoother and more precise - Schematics no longer re-render their preview every time they are re-positioned - Schematic tools now move, rotate or flip the schematic more smoothly - Schematic tools now render the new cuboid outlines rather than plain GL lines - Fixed Schematics not rendering TileEntities in their preview - Fixed inconsistent shifting when rotating Schematics with an "odd by even" size - Fixed typo in Mechanical Press tooltip --- .../simibubi/create/AllSpecialTextures.java | 2 + .../com/simibubi/create/ClientEvents.java | 2 - .../com/simibubi/create/CreateClient.java | 5 - .../gui/widgets/InterpolatedChasingAngle.java | 12 + .../gui/widgets/InterpolatedChasingValue.java | 16 +- .../foundation/utility/RaycastHelper.java | 6 +- .../foundation/utility/WrappedWorld.java | 37 +- .../utility/outliner/AABBOutline.java | 77 +++- .../utility/outliner/ChasingAABBOutline.java | 50 +++ .../foundation/utility/outliner/Outline.java | 17 +- .../utility/outliner/OutlineParticle.java | 18 +- .../utility/render/StructureRenderer.java | 111 ++++++ .../contraptions/ChassisRangeDisplay.java | 3 +- .../contraptions/ContraptionRenderer.java | 94 +---- .../modules/schematics/SchematicWorld.java | 29 +- .../block/SchematicTableContainer.java | 3 +- .../block/SchematicannonTileEntity.java | 6 +- .../client/SchematicAndQuillHandler.java | 264 +++++++------- .../client/SchematicEditScreen.java | 48 ++- .../schematics/client/SchematicHandler.java | 338 +++++++----------- .../schematics/client/SchematicHologram.java | 200 ----------- ...y.java => SchematicHotbarSlotOverlay.java} | 2 +- .../schematics/client/SchematicRenderer.java | 166 +++++++++ .../client/SchematicTransformation.java | 208 +++++++++++ .../schematics/client/tools/DeployTool.java | 94 +++-- .../schematics/client/tools/FlipTool.java | 83 ++++- .../client/tools/ISchematicTool.java | 1 + .../schematics/client/tools/MoveTool.java | 22 +- .../client/tools/MoveVerticalTool.java | 5 +- .../schematics/client/tools/RotateTool.java | 38 +- .../client/tools/SchematicToolBase.java | 145 ++++---- .../schematics/item/SchematicItem.java | 44 ++- .../packet/SchematicPlacePacket.java | 2 +- .../resources/assets/create/lang/en_us.json | 4 +- .../assets/create/textures/gui/background.png | Bin 179 -> 150 bytes .../assets/create/textures/gui/widgets.png | Bin 2795 -> 2992 bytes .../textures/item/blueprint_and_quill.png | Bin 368 -> 518 bytes .../create/textures/item/blueprint_empty.png | Bin 317 -> 373 bytes .../create/textures/item/blueprint_filled.png | Bin 340 -> 436 bytes .../create/textures/special/checkerboard.png | Bin 0 -> 156 bytes .../special/highlighted_checkerboard.png | Bin 0 -> 156 bytes 41 files changed, 1302 insertions(+), 850 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingAngle.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java delete mode 100644 src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java rename src/main/java/com/simibubi/create/modules/schematics/client/{BlueprintHotbarOverlay.java => SchematicHotbarSlotOverlay.java} (90%) create mode 100644 src/main/java/com/simibubi/create/modules/schematics/client/SchematicRenderer.java create mode 100644 src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java create mode 100644 src/main/resources/assets/create/textures/special/checkerboard.png create mode 100644 src/main/resources/assets/create/textures/special/highlighted_checkerboard.png diff --git a/src/main/java/com/simibubi/create/AllSpecialTextures.java b/src/main/java/com/simibubi/create/AllSpecialTextures.java index e8a3f15fa..bba4fc2a7 100644 --- a/src/main/java/com/simibubi/create/AllSpecialTextures.java +++ b/src/main/java/com/simibubi/create/AllSpecialTextures.java @@ -9,6 +9,8 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber; public enum AllSpecialTextures { BLANK("blank.png"), + CHECKERED("checkerboard.png"), + HIGHLIGHT_CHECKERED("highlighted_checkerboard.png"), SELECTION("selection.png"), ; diff --git a/src/main/java/com/simibubi/create/ClientEvents.java b/src/main/java/com/simibubi/create/ClientEvents.java index 8f2db88e6..aa113445c 100644 --- a/src/main/java/com/simibubi/create/ClientEvents.java +++ b/src/main/java/com/simibubi/create/ClientEvents.java @@ -67,8 +67,6 @@ public class ClientEvents { @SubscribeEvent public static void onRenderWorld(RenderWorldLastEvent event) { CreateClient.schematicHandler.render(); - CreateClient.schematicAndQuillHandler.render(); - CreateClient.schematicHologram.render(); KineticDebugger.renderSourceOutline(); ChassisRangeDisplay.renderOutlines(event.getPartialTicks()); TerrainZapperRenderHandler.render(); diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 6809029d2..d0ccbd321 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -16,7 +16,6 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Contrapt import com.simibubi.create.modules.schematics.ClientSchematicLoader; import com.simibubi.create.modules.schematics.client.SchematicAndQuillHandler; import com.simibubi.create.modules.schematics.client.SchematicHandler; -import com.simibubi.create.modules.schematics.client.SchematicHologram; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; @@ -40,10 +39,8 @@ public class CreateClient { public static ClientSchematicLoader schematicSender; public static SchematicHandler schematicHandler; - public static SchematicHologram schematicHologram; public static SchematicAndQuillHandler schematicAndQuillHandler; public static SuperByteBufferCache bufferCache; - public static int renderTicks; public static void addListeners(IEventBus modEventBus) { DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { @@ -58,7 +55,6 @@ public class CreateClient { public static void clientInit(FMLClientSetupEvent event) { schematicSender = new ClientSchematicLoader(); schematicHandler = new SchematicHandler(); - schematicHologram = new SchematicHologram(); schematicAndQuillHandler = new SchematicAndQuillHandler(); bufferCache = new SuperByteBufferCache(); @@ -81,7 +77,6 @@ public class CreateClient { schematicSender.tick(); schematicAndQuillHandler.tick(); schematicHandler.tick(); - schematicHologram.tick(); ChassisRangeDisplay.clientTick(); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingAngle.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingAngle.java new file mode 100644 index 000000000..3dc30905e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingAngle.java @@ -0,0 +1,12 @@ +package com.simibubi.create.foundation.gui.widgets; + +import com.simibubi.create.foundation.utility.AngleHelper; + +public class InterpolatedChasingAngle extends InterpolatedChasingValue { + + @Override + protected float getCurrentDiff() { + return AngleHelper.getShortestAngleDiff(value, getTarget()); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingValue.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingValue.java index e18b5f6d4..92a3efe88 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingValue.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/InterpolatedChasingValue.java @@ -7,11 +7,15 @@ public class InterpolatedChasingValue extends InterpolatedValue { float eps = 1 / 4096f; public void tick() { - float diff = target - value; + float diff = getCurrentDiff(); if (Math.abs(diff) < eps) return; set(value + (diff) * speed); } + + protected float getCurrentDiff() { + return getTarget() - value; + } public InterpolatedChasingValue withSpeed(float speed) { this.speed = speed; @@ -22,5 +26,15 @@ public class InterpolatedChasingValue extends InterpolatedValue { this.target = target; return this; } + + public InterpolatedChasingValue start(float value) { + lastValue = this.value = value; + target(value); + return this; + } + + public float getTarget() { + return target; + } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/RaycastHelper.java b/src/main/java/com/simibubi/create/foundation/utility/RaycastHelper.java index c35a68d1c..69c555ff0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/RaycastHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/RaycastHelper.java @@ -28,7 +28,7 @@ public class RaycastHelper { return rayTraceUntil(origin, target, predicate); } - private static Vec3d getTraceTarget(PlayerEntity playerIn, double range, Vec3d origin) { + public static Vec3d getTraceTarget(PlayerEntity playerIn, double range, Vec3d origin) { float f = playerIn.rotationPitch; float f1 = playerIn.rotationYaw; float f2 = MathHelper.cos(-f1 * 0.017453292F - (float) Math.PI); @@ -42,7 +42,7 @@ public class RaycastHelper { return vec3d1; } - private static Vec3d getTraceOrigin(PlayerEntity playerIn) { + public static Vec3d getTraceOrigin(PlayerEntity playerIn) { double d0 = playerIn.posX; double d1 = playerIn.posY + (double) playerIn.getEyeHeight(); double d2 = playerIn.posZ; @@ -50,7 +50,7 @@ public class RaycastHelper { return vec3d; } - private static PredicateTraceResult rayTraceUntil(Vec3d start, Vec3d end, Predicate predicate) { + public static PredicateTraceResult rayTraceUntil(Vec3d start, Vec3d end, Predicate predicate) { if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) return null; if (Double.isNaN(end.x) || Double.isNaN(end.y) || Double.isNaN(end.z)) diff --git a/src/main/java/com/simibubi/create/foundation/utility/WrappedWorld.java b/src/main/java/com/simibubi/create/foundation/utility/WrappedWorld.java index 3c7092e7d..d1aabd515 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/WrappedWorld.java +++ b/src/main/java/com/simibubi/create/foundation/utility/WrappedWorld.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.utility; import java.util.Collections; import java.util.List; +import java.util.function.Predicate; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -11,6 +12,7 @@ import net.minecraft.fluid.Fluid; import net.minecraft.item.crafting.RecipeManager; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.tags.NetworkTagManager; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; @@ -33,6 +35,26 @@ public class WrappedWorld extends World { return world; } + @Override + public BlockState getBlockState(BlockPos pos) { + return world.getBlockState(pos); + } + + @Override + public boolean hasBlockState(BlockPos p_217375_1_, Predicate p_217375_2_) { + return world.hasBlockState(p_217375_1_, p_217375_2_); + } + + @Override + public TileEntity getTileEntity(BlockPos pos) { + return world.getTileEntity(pos); + } + + @Override + public boolean setBlockState(BlockPos pos, BlockState newState, int flags) { + return world.setBlockState(pos, newState, flags); + } + @Override public int getLight(BlockPos pos) { return 15; @@ -59,8 +81,7 @@ public class WrappedWorld extends World { } @Override - public void playEvent(PlayerEntity player, int type, BlockPos pos, int data) { - } + public void playEvent(PlayerEntity player, int type, BlockPos pos, int data) {} @Override public List getPlayers() { @@ -69,13 +90,11 @@ public class WrappedWorld extends World { @Override public void playSound(PlayerEntity player, double x, double y, double z, SoundEvent soundIn, SoundCategory category, - float volume, float pitch) { - } + float volume, float pitch) {} @Override public void playMovingSound(PlayerEntity p_217384_1_, Entity p_217384_2_, SoundEvent p_217384_3_, - SoundCategory p_217384_4_, float p_217384_5_, float p_217384_6_) { - } + SoundCategory p_217384_4_, float p_217384_5_, float p_217384_6_) {} @Override public Entity getEntityByID(int id) { @@ -94,8 +113,7 @@ public class WrappedWorld extends World { } @Override - public void registerMapData(MapData mapDataIn) { - } + public void registerMapData(MapData mapDataIn) {} @Override public int getNextMapId() { @@ -103,8 +121,7 @@ public class WrappedWorld extends World { } @Override - public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { - } + public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {} @Override public Scoreboard getScoreboard() { diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java index da9ab87dd..f899ee4b3 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java @@ -1,16 +1,29 @@ package com.simibubi.create.foundation.utility.outliner; +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.foundation.utility.ColorHelper; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; public class AABBOutline extends Outline { - private AxisAlignedBB bb = new AxisAlignedBB(new BlockPos(25, 70, 90)).expand(0, 1, 0); + protected AxisAlignedBB bb; + protected AllSpecialTextures faceTexture; + protected AllSpecialTextures highlightedTexture; + protected Direction highlightedFace; + public boolean disableCull = false; + + public AABBOutline(AxisAlignedBB bb) { + this.bb = bb; + } @Override public void render(BufferBuilder buffer) { @@ -18,8 +31,25 @@ public class AABBOutline extends Outline { Vec3d color = ColorHelper.getRGB(0xFFFFFF); float alpha = 1f; + renderBB(bb, buffer, color, alpha, !disableCull); + + draw(); + } + + public void setTextures(AllSpecialTextures faceTexture, AllSpecialTextures highlightTexture) { + this.faceTexture = faceTexture; + this.highlightedTexture = highlightTexture; + } + + public void highlightFace(Direction face) { + this.highlightedFace = face; + } + + public void renderBB(AxisAlignedBB bb, BufferBuilder buffer, Vec3d color, float alpha, boolean doCulling) { + Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); + boolean inside = bb.contains(projectedView); + bb = bb.grow(inside ? -1 / 128d : 1 / 128d); - AllSpecialTextures.BLANK.bind(); Vec3d xyz = new Vec3d(bb.minX, bb.minY, bb.minZ); Vec3d Xyz = new Vec3d(bb.maxX, bb.minY, bb.minZ); Vec3d xYz = new Vec3d(bb.minX, bb.maxY, bb.minZ); @@ -29,7 +59,24 @@ public class AABBOutline extends Outline { Vec3d xYZ = new Vec3d(bb.minX, bb.maxY, bb.maxZ); Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ); + if (doCulling) { + GlStateManager.enableCull(); + if (inside) + GlStateManager.disableCull(); + } + + renderFace(Direction.NORTH, xYz, XYz, Xyz, xyz, buffer); + renderFace(Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, buffer); + renderFace(Direction.EAST, XYz, XYZ, XyZ, Xyz, buffer); + renderFace(Direction.WEST, xYZ, xYz, xyz, xyZ, buffer); + renderFace(Direction.UP, xYZ, XYZ, XYz, xYz, buffer); + renderFace(Direction.DOWN, xyz, Xyz, XyZ, xyZ, buffer); + + if (doCulling) + GlStateManager.enableCull(); + Vec3d start = xyz; + AllSpecialTextures.BLANK.bind(); renderAACuboidLine(start, Xyz, color, alpha, buffer); renderAACuboidLine(start, xYz, color, alpha, buffer); renderAACuboidLine(start, xyZ, color, alpha, buffer); @@ -49,7 +96,29 @@ public class AABBOutline extends Outline { renderAACuboidLine(start, xyZ, color, alpha, buffer); renderAACuboidLine(start, xYz, color, alpha, buffer); - draw(); + } + + protected void renderFace(Direction direction, Vec3d p1, Vec3d p2, Vec3d p3, Vec3d p4, BufferBuilder buffer) { + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_REPEAT); + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_REPEAT); + + if (direction == highlightedFace && highlightedTexture != null) + highlightedTexture.bind(); + else if (faceTexture != null) + faceTexture.bind(); + else + return; + + GlStateManager.depthMask(false); + Vec3d uDiff = p2.subtract(p1); + Vec3d vDiff = p4.subtract(p1); + Axis axis = direction.getAxis(); + float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); + float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); + + putQuadUV(p1, p2, p3, p4, 0, 0, maxU, maxV, new Vec3d(1, 1, 1), 1, buffer); + flush(); + GlStateManager.depthMask(true); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java new file mode 100644 index 000000000..5f6a69d59 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java @@ -0,0 +1,50 @@ +package com.simibubi.create.foundation.utility.outliner; + +import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class ChasingAABBOutline extends AABBOutline { + + AxisAlignedBB targetBB; + AxisAlignedBB prevBB; + + public ChasingAABBOutline(AxisAlignedBB bb) { + super(bb); + prevBB = bb.grow(0); + targetBB = bb.grow(0); + } + + public void target(AxisAlignedBB target) { + targetBB = target; + } + + public void tick() { + prevBB = bb; + bb = interpolateBBs(bb, targetBB, .5f); + } + + @Override + public void render(BufferBuilder buffer) { + begin(); + + Vec3d color = ColorHelper.getRGB(0xFFFFFF); + float alpha = 1f; + renderBB(interpolateBBs(prevBB, bb, Minecraft.getInstance().getRenderPartialTicks()), buffer, color, alpha, + true); + + draw(); + } + + private static AxisAlignedBB interpolateBBs(AxisAlignedBB current, AxisAlignedBB target, float pt) { + return new AxisAlignedBB(MathHelper.lerp(pt, current.minX, target.minX), + MathHelper.lerp(pt, current.minY, target.minY), MathHelper.lerp(pt, current.minZ, target.minZ), + MathHelper.lerp(pt, current.maxX, target.maxX), MathHelper.lerp(pt, current.maxY, target.maxY), + MathHelper.lerp(pt, current.maxZ, target.maxZ)); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java index a0fe1646e..02030782e 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java @@ -32,7 +32,7 @@ public abstract class Outline { begin(); } - protected void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, BufferBuilder buffer) { + public void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, BufferBuilder buffer) { Vec3d diff = end.subtract(start); if (diff.x + diff.y + diff.z < 0) { Vec3d temp = start; @@ -91,11 +91,16 @@ public abstract class Outline { putQuad(a1, a2, a3, a4, rgb, alpha, buffer); } - protected void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, BufferBuilder buffer) { - putVertex(v1, rgb, 0, 0, alpha, buffer); - putVertex(v2, rgb, 1, 0, alpha, buffer); - putVertex(v3, rgb, 1, 1, alpha, buffer); - putVertex(v4, rgb, 0, 1, alpha, buffer); + public void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, BufferBuilder buffer) { + putQuadUV(v1, v2, v3, v4, 0, 0, 1, 1, rgb, alpha, buffer); + } + + public void putQuadUV(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU, float minV, float maxU, + float maxV, Vec3d rgb, float alpha, BufferBuilder buffer) { + putVertex(v1, rgb, minU, minV, alpha, buffer); + putVertex(v2, rgb, maxU, minV, alpha, buffer); + putVertex(v3, rgb, maxU, maxV, alpha, buffer); + putVertex(v4, rgb, minU, maxV, alpha, buffer); } protected void putVertex(Vec3d pos, Vec3d rgb, float u, float v, float alpha, BufferBuilder buffer) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java index 80feeb1ca..83bc63d22 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java @@ -11,20 +11,20 @@ import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class OutlineParticle extends Particle { +public class OutlineParticle extends Particle { - private Outline outline; + protected O outline; - private OutlineParticle(Outline outline, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn) { + protected OutlineParticle(O outline, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn) { super(worldIn, xCoordIn, yCoordIn, zCoordIn); this.outline = outline; this.maxAge = 1024; } - public static OutlineParticle create(Outline outline) { + public static OutlineParticle create(O outline) { Minecraft mc = Minecraft.getInstance(); ClientPlayerEntity player = mc.player; - OutlineParticle effect = new OutlineParticle(outline, mc.world, player.posX, player.posY, player.posZ); + OutlineParticle effect = new OutlineParticle<>(outline, mc.world, player.posX, player.posY, player.posZ); mc.particles.addEffect(effect); return effect; } @@ -39,14 +39,12 @@ public class OutlineParticle extends Particle { GlStateManager.pushMatrix(); Vec3d view = entityIn.getProjectedView(); GlStateManager.translated(-view.x, -view.y, -view.z); - GlStateManager.depthMask(false); GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); GlStateManager.enableBlend(); - outline.render(buffer); + getOutline().render(buffer); GlStateManager.disableBlend(); - GlStateManager.depthMask(true); GlStateManager.popMatrix(); } @@ -55,4 +53,8 @@ public class OutlineParticle extends Particle { return IParticleRenderType.CUSTOM; } + public O getOutline() { + return outline; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java b/src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java new file mode 100644 index 000000000..48916d775 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java @@ -0,0 +1,111 @@ +package com.simibubi.create.foundation.utility.render; + +import java.util.Iterator; + +import com.mojang.blaze3d.platform.GLX; +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.Create; +import com.simibubi.create.config.AllConfigs; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.WrappedWorld; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.crash.ReportedException; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +public class StructureRenderer { + + protected static LightingWorld lightingWorld; + + public static void renderTileEntities(World world, Vec3d position, Vec3d rotation, + Iterable customRenderTEs) { + TileEntityRendererDispatcher dispatcher = TileEntityRendererDispatcher.instance; + float pt = Minecraft.getInstance().getRenderPartialTicks(); + World prevDispatcherWorld = dispatcher.world; + + if (lightingWorld == null) + lightingWorld = new LightingWorld(world); + lightingWorld.setWorld(world); + lightingWorld.setTransform(position, rotation); + dispatcher.setWorld(lightingWorld); + + for (Iterator iterator = customRenderTEs.iterator(); iterator.hasNext();) { + TileEntity tileEntity = iterator.next(); + if (dispatcher.getRenderer(tileEntity) == null) { + iterator.remove(); + continue; + } + + try { + + BlockPos pos = tileEntity.getPos(); + if (!tileEntity.hasFastRenderer()) { + RenderHelper.enableStandardItemLighting(); + int i = lightingWorld.getCombinedLight(pos, 0); + int j = i % 65536; + int k = i / 65536; + GLX.glMultiTexCoord2f(GLX.GL_TEXTURE1, (float) j, (float) k); + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + World prevTileWorld = tileEntity.getWorld(); + tileEntity.setWorld(lightingWorld); + GlStateManager.disableCull(); + dispatcher.render(tileEntity, pos.getX(), pos.getY(), pos.getZ(), pt, -1, true); + GlStateManager.enableCull(); + tileEntity.setWorld(prevTileWorld); + + } catch (ReportedException e) { + if (AllConfigs.CLIENT.explainRenderErrors.get()) { + Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString() + + " didn't want to render while moved.\n", e); + } else { + Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString() + + " didn't want to render while moved.\n"); + } + iterator.remove(); + continue; + } + } + + dispatcher.setWorld(prevDispatcherWorld); + } + + private static class LightingWorld extends WrappedWorld { + + private Vec3d offset; + private Vec3d rotation; + + public LightingWorld(World world) { + super(world); + } + + void setWorld(World world) { + this.world = world; + } + + void setTransform(Vec3d offset, Vec3d rotation) { + this.offset = offset; + this.rotation = rotation; + } + + @Override + public int getCombinedLight(BlockPos pos, int minLight) { + return super.getCombinedLight(transformPos(pos), minLight); + } + + private BlockPos transformPos(BlockPos pos) { + Vec3d vec = VecHelper.getCenterOf(pos); + vec = VecHelper.rotate(vec, rotation.x, rotation.y, rotation.z); + vec = vec.add(offset).subtract(VecHelper.getCenterOf(BlockPos.ZERO)); + return new BlockPos(vec); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java index 6714c05fc..66c967577 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java @@ -14,6 +14,7 @@ import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.foundation.utility.outliner.BlockClusterOutline; +import com.simibubi.create.foundation.utility.outliner.Outline; import com.simibubi.create.foundation.utility.outliner.OutlineParticle; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; @@ -32,7 +33,7 @@ public class ChassisRangeDisplay { private static class Entry { BlockClusterOutline outline; - OutlineParticle particle; + OutlineParticle particle; ChassisTileEntity te; int timer; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionRenderer.java index 9a03e703d..31f452a5e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionRenderer.java @@ -1,22 +1,16 @@ package com.simibubi.create.modules.contraptions.components.contraptions; -import java.util.Iterator; import java.util.Random; import java.util.function.Consumer; import org.apache.commons.lang3.tuple.Pair; import org.lwjgl.opengl.GL11; -import com.mojang.blaze3d.platform.GLX; -import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.Create; import com.simibubi.create.CreateClient; -import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.utility.PlacementSimulationWorld; import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment; -import com.simibubi.create.foundation.utility.VecHelper; -import com.simibubi.create.foundation.utility.WrappedWorld; +import com.simibubi.create.foundation.utility.render.StructureRenderer; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; @@ -24,12 +18,8 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BlockModelRenderer; import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.model.IBakedModel; -import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.crash.ReportedException; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos.MutableBlockPos; import net.minecraft.util.math.Vec3d; @@ -42,7 +32,6 @@ public class ContraptionRenderer { public static final Compartment CONTRAPTION = new Compartment<>(); protected static PlacementSimulationWorld renderWorld; - protected static LightingWorld lightingWorld; public static void render(World world, Contraption c, Consumer transform, BufferBuilder buffer) { SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c)); @@ -52,54 +41,7 @@ public class ContraptionRenderer { } public static void renderTEsWithGL(World world, Contraption c, Vec3d position, Vec3d rotation) { - TileEntityRendererDispatcher dispatcher = TileEntityRendererDispatcher.instance; - float pt = Minecraft.getInstance().getRenderPartialTicks(); - World prevDispatcherWorld = dispatcher.world; - - if (lightingWorld == null) - lightingWorld = new LightingWorld(world); - lightingWorld.setWorld(world); - lightingWorld.setTransform(position, rotation); - dispatcher.setWorld(lightingWorld); - - for (Iterator iterator = c.customRenderTEs.iterator(); iterator.hasNext();) { - TileEntity tileEntity = iterator.next(); - if (dispatcher.getRenderer(tileEntity) == null) { - iterator.remove(); - continue; - } - - try { - - BlockPos pos = tileEntity.getPos(); - if (!tileEntity.hasFastRenderer()) { - RenderHelper.enableStandardItemLighting(); - int i = lightingWorld.getCombinedLight(pos, 0); - int j = i % 65536; - int k = i / 65536; - GLX.glMultiTexCoord2f(GLX.GL_TEXTURE1, (float) j, (float) k); - GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); - } - - World prevTileWorld = tileEntity.getWorld(); - tileEntity.setWorld(lightingWorld); - dispatcher.render(tileEntity, pos.getX(), pos.getY(), pos.getZ(), pt, -1, true); - tileEntity.setWorld(prevTileWorld); - - } catch (ReportedException e) { - if (AllConfigs.CLIENT.explainRenderErrors.get()) { - Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString() - + " didn't want to render while moved.\n", e); - } else { - Create.logger.error("TileEntity " + tileEntity.getType().getRegistryName().toString() - + " didn't want to render while moved.\n"); - } - iterator.remove(); - continue; - } - } - - dispatcher.setWorld(prevDispatcherWorld); + StructureRenderer.renderTileEntities(world, position, rotation, c.customRenderTEs); } private static SuperByteBuffer renderContraption(Contraption c) { @@ -173,36 +115,4 @@ public class ContraptionRenderer { return ((int) sky) << 20 | ((int) block) << 4; } - private static class LightingWorld extends WrappedWorld { - - private Vec3d offset; - private Vec3d rotation; - - public LightingWorld(World world) { - super(world); - } - - void setWorld(World world) { - this.world = world; - } - - void setTransform(Vec3d offset, Vec3d rotation) { - this.offset = offset; - this.rotation = rotation; - } - - @Override - public int getCombinedLight(BlockPos pos, int minLight) { - return super.getCombinedLight(transformPos(pos), minLight); - } - - private BlockPos transformPos(BlockPos pos) { - Vec3d vec = VecHelper.getCenterOf(pos); - vec = VecHelper.rotate(vec, rotation.x, rotation.y, rotation.z); - vec = vec.add(offset).subtract(VecHelper.getCenterOf(BlockPos.ZERO)); - return new BlockPos(vec); - } - - } - } diff --git a/src/main/java/com/simibubi/create/modules/schematics/SchematicWorld.java b/src/main/java/com/simibubi/create/modules/schematics/SchematicWorld.java index d780187e2..cdc1024ec 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/SchematicWorld.java +++ b/src/main/java/com/simibubi/create/modules/schematics/SchematicWorld.java @@ -1,6 +1,7 @@ package com.simibubi.create.modules.schematics; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -29,13 +30,16 @@ import net.minecraft.world.biome.Biomes; public class SchematicWorld extends WrappedWorld { private Map blocks; + private Map tileEntities; private Cuboid bounds; public BlockPos anchor; + public boolean renderMode; - public SchematicWorld(Map blocks, Cuboid bounds, BlockPos anchor, World original) { + public SchematicWorld(BlockPos anchor, World original) { super(original); - this.blocks = blocks; - this.setBounds(bounds); + this.blocks = new HashMap<>(); + this.tileEntities = new HashMap<>(); + this.bounds = new Cuboid(); this.anchor = anchor; } @@ -45,6 +49,19 @@ public class SchematicWorld extends WrappedWorld { @Override public TileEntity getTileEntity(BlockPos pos) { + if (isOutsideBuildHeight(pos)) + return null; + if (tileEntities.containsKey(pos)) + return tileEntities.get(pos); + if (!blocks.containsKey(pos.subtract(anchor))) + return null; + + BlockState blockState = getBlockState(pos); + if (blockState.hasTileEntity()) { + TileEntity tileEntity = blockState.createTileEntity(this); + tileEntities.put(pos, tileEntity); + return tileEntity; + } return null; } @@ -52,7 +69,7 @@ public class SchematicWorld extends WrappedWorld { public BlockState getBlockState(BlockPos globalPos) { BlockPos pos = globalPos.subtract(anchor); - if (pos.getY() - bounds.y == -1) { + if (pos.getY() - bounds.y == -1 && !renderMode) { return Blocks.GRASS_BLOCK.getDefaultState(); } @@ -171,4 +188,8 @@ public class SchematicWorld extends WrappedWorld { this.bounds = bounds; } + public Iterable getTileEntities() { + return tileEntities.values(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableContainer.java b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableContainer.java index 1157ab797..40b71cab4 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableContainer.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableContainer.java @@ -44,7 +44,8 @@ public class SchematicTableContainer extends Container { inputSlot = new SlotItemHandler(te.inventory, 0, -9, 40) { @Override public boolean isItemValid(ItemStack stack) { - return AllItems.EMPTY_BLUEPRINT.typeOf(stack) || AllItems.BLUEPRINT_AND_QUILL.typeOf(stack); + return AllItems.EMPTY_BLUEPRINT.typeOf(stack) || AllItems.BLUEPRINT_AND_QUILL.typeOf(stack) + || AllItems.BLUEPRINT.typeOf(stack); } }; diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonTileEntity.java b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonTileEntity.java index ad3fbc63d..081ddf8e8 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonTileEntity.java @@ -1,6 +1,5 @@ package com.simibubi.create.modules.schematics.block; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -12,7 +11,6 @@ import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.CSchematics; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; -import com.simibubi.create.foundation.type.Cuboid; import com.simibubi.create.modules.schematics.MaterialChecklist; import com.simibubi.create.modules.schematics.SchematicWorld; import com.simibubi.create.modules.schematics.item.SchematicItem; @@ -466,7 +464,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC } // Load blocks into reader - Template activeTemplate = SchematicItem.getSchematic(blueprint); + Template activeTemplate = SchematicItem.loadSchematic(blueprint); BlockPos anchor = NBTUtil.readBlockPos(blueprint.getTag().getCompound("Anchor")); if (activeTemplate.getSize().equals(BlockPos.ZERO)) { @@ -484,7 +482,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC } schematicAnchor = anchor; - blockReader = new SchematicWorld(new HashMap<>(), new Cuboid(), schematicAnchor, world); + blockReader = new SchematicWorld(schematicAnchor, world); activeTemplate.addBlocksToWorld(blockReader, schematicAnchor, SchematicItem.getSettings(blueprint)); schematicLoaded = true; state = State.PAUSED; diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicAndQuillHandler.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicAndQuillHandler.java index 54e45628d..c0cec4880 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicAndQuillHandler.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicAndQuillHandler.java @@ -8,7 +8,6 @@ import java.nio.file.StandardOpenOption; import org.apache.commons.io.IOUtils; -import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; import com.simibubi.create.AllSpecialTextures; @@ -18,13 +17,13 @@ import com.simibubi.create.foundation.utility.FilesHelper; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.RaycastHelper; import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult; -import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.outliner.ChasingAABBOutline; +import com.simibubi.create.foundation.utility.outliner.OutlineParticle; import net.minecraft.block.Blocks; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemUseContext; import net.minecraft.nbt.CompoundNBT; @@ -32,6 +31,7 @@ import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.util.Direction; import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Hand; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.MathHelper; @@ -49,14 +49,7 @@ public class SchematicAndQuillHandler { private Direction selectedFace; private int range = 10; - private boolean isActive() { - return isPresent() && AllItems.BLUEPRINT_AND_QUILL.typeOf(Minecraft.getInstance().player.getHeldItemMainhand()); - } - - private boolean isPresent() { - return Minecraft.getInstance() != null && Minecraft.getInstance().world != null - && Minecraft.getInstance().currentScreen == null; - } + private OutlineParticle particle; public boolean mouseScrolled(double delta) { if (!isActive()) @@ -65,27 +58,32 @@ public class SchematicAndQuillHandler { return false; if (secondPos == null) range = (int) MathHelper.clamp(range + delta, 1, 100); - if (selectedFace != null) { - MutableBoundingBox bb = new MutableBoundingBox(firstPos, secondPos); - Vec3i vec = selectedFace.getDirectionVec(); + if (selectedFace == null) + return true; - int x = (int) (vec.getX() * delta); - int y = (int) (vec.getY() * delta); - int z = (int) (vec.getZ() * delta); + AxisAlignedBB bb = new AxisAlignedBB(firstPos, secondPos); + Vec3i vec = selectedFace.getDirectionVec(); + Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); + if (bb.contains(projectedView)) + delta *= -1; - AxisDirection axisDirection = selectedFace.getAxisDirection(); - if (axisDirection == AxisDirection.NEGATIVE) - bb.offset(-x, -y, -z); + int x = (int) (vec.getX() * delta); + int y = (int) (vec.getY() * delta); + int z = (int) (vec.getZ() * delta); - bb.maxX = Math.max(bb.maxX - x * axisDirection.getOffset(), bb.minX); - bb.maxY = Math.max(bb.maxY - y * axisDirection.getOffset(), bb.minY); - bb.maxZ = Math.max(bb.maxZ - z * axisDirection.getOffset(), bb.minZ); + AxisDirection axisDirection = selectedFace.getAxisDirection(); + if (axisDirection == AxisDirection.NEGATIVE) + bb = bb.offset(-x, -y, -z); - firstPos = new BlockPos(bb.minX, bb.minY, bb.minZ); - secondPos = new BlockPos(bb.maxX, bb.maxY, bb.maxZ); - Lang.sendStatus(Minecraft.getInstance().player, "schematicAndQuill.dimensions", bb.getXSize(), - bb.getYSize(), bb.getZSize()); - } + double maxX = Math.max(bb.maxX - x * axisDirection.getOffset(), bb.minX); + double maxY = Math.max(bb.maxY - y * axisDirection.getOffset(), bb.minY); + double maxZ = Math.max(bb.maxZ - z * axisDirection.getOffset(), bb.minZ); + bb = new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, maxX, maxY, maxZ); + + firstPos = new BlockPos(bb.minX, bb.minY, bb.minZ); + secondPos = new BlockPos(bb.maxX, bb.maxY, bb.maxZ); + Lang.sendStatus(Minecraft.getInstance().player, "schematicAndQuill.dimensions", (int) bb.getXSize() + 1, + (int) bb.getYSize() + 1, (int) bb.getZSize() + 1); return true; } @@ -106,8 +104,7 @@ public class SchematicAndQuillHandler { } if (secondPos != null) { - TextInputPromptScreen guiScreenIn = new TextInputPromptScreen(this::saveSchematic, s -> { - }); + TextInputPromptScreen guiScreenIn = new TextInputPromptScreen(this::saveSchematic, s -> {}); guiScreenIn.setTitle(Lang.translate("schematicAndQuill.prompt")); guiScreenIn.setButtonTextConfirm(Lang.translate("action.saveToFile")); guiScreenIn.setButtonTextAbort(Lang.translate("action.discard")); @@ -130,6 +127,100 @@ public class SchematicAndQuillHandler { Lang.sendStatus(player, "schematicAndQuill.firstPos"); } + public void tick() { + if (!isActive()) { + if (particle != null) { + particle.setExpired(); + particle = null; + } + return; + } + + ClientPlayerEntity player = Minecraft.getInstance().player; + + if (AllKeys.ACTIVATE_TOOL.isPressed()) { + float pt = Minecraft.getInstance().getRenderPartialTicks(); + Vec3d targetVec = player.getEyePosition(pt).add(player.getLookVec().scale(range)); + setCursor(new BlockPos(targetVec)); + + } else { + BlockRayTraceResult trace = RaycastHelper.rayTraceRange(player.world, player, 75); + if (trace != null && trace.getType() == Type.BLOCK) { + + BlockPos hit = trace.getPos(); + boolean replaceable = player.world.getBlockState(hit) + .isReplaceable(new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, trace))); + if (trace.getFace().getAxis().isVertical() && !replaceable) + hit = hit.offset(trace.getFace()); + setCursor(hit); + } else + setCursor(null); + } + + if (particle == null) + return; + + ChasingAABBOutline outline = particle.getOutline(); + if (particle.isAlive()) + outline.tick(); + + if (secondPos == null) { + selectedFace = null; + outline.highlightFace(null); + return; + } + + AxisAlignedBB bb = new AxisAlignedBB(firstPos, secondPos).expand(1, 1, 1).grow(.45f); + Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); + boolean inside = bb.contains(projectedView); + + PredicateTraceResult result = + RaycastHelper.rayTraceUntil(player, 70, pos -> inside ^ bb.contains(VecHelper.getCenterOf(pos))); + selectedFace = result.missed() ? null : inside ? result.getFacing().getOpposite() : result.getFacing(); + outline.highlightFace(AllKeys.ACTIVATE_TOOL.isPressed() ? selectedFace : null); + } + + private void setCursor(BlockPos pos) { + selectedPos = pos; + AxisAlignedBB bb = getCurrentSelectionBox(); + + if (particle != null && !particle.isAlive()) + particle = null; + if (bb == null) { + if (particle != null) + particle.setExpired(); + return; + } + + if (particle == null) { + ChasingAABBOutline outline = new ChasingAABBOutline(bb); + outline.setTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED); + particle = OutlineParticle.create(outline); + } + + ChasingAABBOutline outline = particle.getOutline(); + outline.target(bb); + } + + private AxisAlignedBB getCurrentSelectionBox() { + if (secondPos == null) { + if (firstPos == null) + return selectedPos == null ? null : new AxisAlignedBB(selectedPos); + return selectedPos == null ? new AxisAlignedBB(firstPos) + : new AxisAlignedBB(firstPos, selectedPos).expand(1, 1, 1); + } + return new AxisAlignedBB(firstPos, secondPos).expand(1, 1, 1); + } + + private boolean isActive() { + return isPresent() && AllItems.BLUEPRINT_AND_QUILL.typeOf(Minecraft.getInstance().player.getHeldItemMainhand()); + } + + private boolean isPresent() { + return Minecraft.getInstance() != null && Minecraft.getInstance().world != null + && Minecraft.getInstance().currentScreen == null; + } + public void saveSchematic(String string) { Template t = new Template(); MutableBoundingBox bb = new MutableBoundingBox(firstPos, secondPos); @@ -160,115 +251,4 @@ public class SchematicAndQuillHandler { Lang.sendStatus(Minecraft.getInstance().player, "schematicAndQuill.saved", filepath); } - public void render() { - if (!isActive()) - return; - - TessellatorHelper.prepareForDrawing(); - GlStateManager.lineWidth(2); - GlStateManager.color4f(1, 1, 1, 1); - GlStateManager.disableTexture(); - - if (secondPos == null) { - // 1st Step - if (firstPos != null && selectedPos == null) { - MutableBoundingBox bb = new MutableBoundingBox(firstPos, firstPos.add(1, 1, 1)); - BlockPos min = new BlockPos(bb.minX, bb.minY, bb.minZ); - BlockPos max = new BlockPos(bb.maxX, bb.maxY, bb.maxZ); - drawBox(min, max, true); - } - - if (firstPos != null && selectedPos != null) { - MutableBoundingBox bb = new MutableBoundingBox(firstPos, selectedPos); - BlockPos min = new BlockPos(bb.minX, bb.minY, bb.minZ); - BlockPos max = new BlockPos(bb.maxX + 1, bb.maxY + 1, bb.maxZ + 1); - drawBox(min, max, true); - } - - if (firstPos == null && selectedPos != null) { - MutableBoundingBox bb = new MutableBoundingBox(selectedPos, selectedPos.add(1, 1, 1)); - BlockPos min = new BlockPos(bb.minX, bb.minY, bb.minZ); - BlockPos max = new BlockPos(bb.maxX, bb.maxY, bb.maxZ); - drawBox(min, max, true); - } - } else { - // 2nd Step - MutableBoundingBox bb = new MutableBoundingBox(firstPos, secondPos); - BlockPos min = new BlockPos(bb.minX, bb.minY, bb.minZ); - BlockPos max = new BlockPos(bb.maxX + 1, bb.maxY + 1, bb.maxZ + 1); - drawBox(min, max, false); - - if (selectedFace != null) { - Vec3d vec = new Vec3d(selectedFace.getDirectionVec()); - Vec3d center = new Vec3d(min.add(max)).scale(1 / 2f); - Vec3d radii = new Vec3d(max.subtract(min)).scale(1 / 2f); - - Vec3d onFaceOffset = new Vec3d(1 - Math.abs(vec.x), 1 - Math.abs(vec.y), 1 - Math.abs(vec.z)) - .mul(radii); - Vec3d faceMin = center.add(vec.mul(radii).add(onFaceOffset)); - Vec3d faceMax = center.add(vec.mul(radii).subtract(onFaceOffset)); - - GlStateManager.enableTexture(); - TessellatorHelper.begin(); - AllSpecialTextures.SELECTION.bind(); - TessellatorHelper.doubleFace(Tessellator.getInstance().getBuffer(), new BlockPos(faceMin), - new BlockPos(faceMax.subtract(faceMin)), 1 / 16f * selectedFace.getAxisDirection().getOffset(), - false, false, false); - TessellatorHelper.draw(); - GlStateManager.disableTexture(); - - } - - } - - GlStateManager.lineWidth(1); - GlStateManager.enableTexture(); - TessellatorHelper.cleanUpAfterDrawing(); - } - - protected static void drawBox(BlockPos min, BlockPos max, boolean blue) { - float red = blue ? .8f : 1; - float green = blue ? .9f : 1; - WorldRenderer.drawBoundingBox(min.getX() - 1 / 16d, min.getY() + 1 / 16d, min.getZ() - 1 / 16d, - max.getX() + 1 / 16d, max.getY() + 1 / 16d, max.getZ() + 1 / 16d, red, green, 1, 1); - } - - public void tick() { - if (!isActive()) - return; - ClientPlayerEntity player = Minecraft.getInstance().player; - - selectedPos = null; - if (AllKeys.ACTIVATE_TOOL.isPressed()) { - selectedPos = new BlockPos(player.getEyePosition(Minecraft.getInstance().getRenderPartialTicks()) - .add(player.getLookVec().scale(range))); - } else { - BlockRayTraceResult trace = RaycastHelper.rayTraceRange(player.world, player, 75); - if (trace != null && trace.getType() == Type.BLOCK) { - - BlockPos hit = new BlockPos(trace.getHitVec()); - boolean replaceable = player.world.getBlockState(hit) - .isReplaceable(new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, trace))); - if (trace.getFace().getAxis().isVertical() && !replaceable) - hit = hit.offset(trace.getFace()); - - selectedPos = hit; - } else { - selectedPos = null; - } - } - - if (secondPos == null) { - selectedFace = null; - return; - } - - MutableBoundingBox bb = new MutableBoundingBox(firstPos, secondPos); - bb.maxX++; - bb.maxY++; - bb.maxZ++; - - PredicateTraceResult result = RaycastHelper.rayTraceUntil(player, 70, pos -> bb.isVecInside(pos)); - selectedFace = result.missed() ? null : result.getFacing(); - } } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicEditScreen.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicEditScreen.java index eb99c1fd4..71affc6bd 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicEditScreen.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicEditScreen.java @@ -15,9 +15,11 @@ import com.simibubi.create.foundation.utility.Lang; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTUtil; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.feature.template.PlacementSettings; public class SchematicEditScreen extends AbstractSimiScreen { @@ -25,10 +27,10 @@ public class SchematicEditScreen extends AbstractSimiScreen { private TextFieldWidget yInput; private TextFieldWidget zInput; - private final List rotationOptions = Lang.translatedOptions("schematic.rotation", "none", "cw90", "cw180", - "cw270"); - private final List mirrorOptions = Lang.translatedOptions("schematic.mirror", "none", "leftRight", - "frontBack"); + private final List rotationOptions = + Lang.translatedOptions("schematic.rotation", "none", "cw90", "cw180", "cw270"); + private final List mirrorOptions = + Lang.translatedOptions("schematic.mirror", "none", "leftRight", "frontBack"); private final String positionLabel = Lang.translate("schematic.position"); private final String rotationLabel = Lang.translate("schematic.rotation"); private final String mirrorLabel = Lang.translate("schematic.mirror"); @@ -48,10 +50,11 @@ public class SchematicEditScreen extends AbstractSimiScreen { yInput = new TextFieldWidget(font, x + 115, y + 32, 32, 10, ""); zInput = new TextFieldWidget(font, x + 155, y + 32, 32, 10, ""); - if (handler.deployed) { - xInput.setText("" + handler.anchor.getX()); - yInput.setText("" + handler.anchor.getY()); - zInput.setText("" + handler.anchor.getZ()); + BlockPos anchor = handler.getTransformation().getAnchor(); + if (handler.isDeployed()) { + xInput.setText("" + anchor.getX()); + yInput.setText("" + anchor.getY()); + zInput.setText("" + anchor.getZ()); } else { BlockPos alt = minecraft.player.getPosition(); xInput.setText("" + alt.getX()); @@ -77,13 +80,14 @@ public class SchematicEditScreen extends AbstractSimiScreen { }); } + PlacementSettings settings = handler.getTransformation().toSettings(); Label labelR = new Label(x + 99, y + 52, "").withShadow(); rotationArea = new SelectionScrollInput(x + 96, y + 49, 94, 14).forOptions(rotationOptions).titled("Rotation") - .setState(handler.cachedSettings.getRotation().ordinal()).writingTo(labelR); + .setState(settings.getRotation().ordinal()).writingTo(labelR); Label labelM = new Label(x + 99, y + 72, "").withShadow(); mirrorArea = new SelectionScrollInput(x + 96, y + 69, 94, 14).forOptions(mirrorOptions).titled("Mirror") - .setState(handler.cachedSettings.getMirror().ordinal()).writingTo(labelM); + .setState(settings.getMirror().ordinal()).writingTo(labelM); Collections.addAll(widgets, xInput, yInput, zInput); Collections.addAll(widgets, labelR, labelM, rotationArea, mirrorArea); @@ -127,8 +131,8 @@ public class SchematicEditScreen extends AbstractSimiScreen { int y = guiTop; ScreenResources.SCHEMATIC.draw(this, x, y); - font.drawStringWithShadow(handler.cachedSchematicName, - x + 103 - font.getStringWidth(handler.cachedSchematicName) / 2, y + 10, 0xDDEEFF); + font.drawStringWithShadow(handler.getCurrentSchematicName(), + x + 103 - font.getStringWidth(handler.getCurrentSchematicName()) / 2, y + 10, 0xDDEEFF); font.drawString(positionLabel, x + 10, y + 32, ScreenResources.FONT_COLOR); font.drawString(rotationLabel, x + 10, y + 52, ScreenResources.FONT_COLOR); @@ -152,10 +156,22 @@ public class SchematicEditScreen extends AbstractSimiScreen { validCoords = false; } - if (validCoords) - handler.moveTo(newLocation); - handler.setRotation(Rotation.values()[rotationArea.getState()]); - handler.setMirror(Mirror.values()[mirrorArea.getState()]); + PlacementSettings settings = new PlacementSettings(); + settings.setRotation(Rotation.values()[rotationArea.getState()]); + settings.setMirror(Mirror.values()[mirrorArea.getState()]); + + if (validCoords && newLocation != null) { + ItemStack item = handler.getActiveSchematicItem(); + if (item != null) { + item.getTag().putBoolean("Deployed", true); + item.getTag().put("Anchor", NBTUtil.writeBlockPos(newLocation)); + } + + handler.getTransformation().init(newLocation, settings, handler.getBounds()); + handler.markDirty(); + handler.deploy(); + } + } } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHandler.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHandler.java index 6a406a721..16b88fcde 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHandler.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHandler.java @@ -1,19 +1,16 @@ package com.simibubi.create.modules.schematics.client; -import java.util.Arrays; -import java.util.HashMap; import java.util.List; import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; import com.simibubi.create.AllPackets; -import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.gui.ToolSelectionScreen; import com.simibubi.create.foundation.packet.NbtPacket; -import com.simibubi.create.foundation.type.Cuboid; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.foundation.utility.outliner.AABBOutline; import com.simibubi.create.modules.schematics.SchematicWorld; import com.simibubi.create.modules.schematics.client.tools.Tools; import com.simibubi.create.modules.schematics.item.SchematicItem; @@ -26,79 +23,62 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; -import net.minecraft.util.Direction.Axis; -import net.minecraft.util.Mirror; -import net.minecraft.util.Rotation; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.StringTextComponent; import net.minecraft.world.gen.feature.template.PlacementSettings; import net.minecraft.world.gen.feature.template.Template; public class SchematicHandler { - public Template cachedSchematic; - public String cachedSchematicName; - public PlacementSettings cachedSettings; + private String displayedSchematic; + private SchematicTransformation transformation; + private AxisAlignedBB bounds; // local space + private AABBOutline outline; + private boolean deployed; + private boolean active; + private Tools currentTool; - public BlockPos anchor; - public BlockPos size; - public boolean active; - public boolean deployed; - public int slot; - public ItemStack item; + private static final int SYNC_DELAY = 10; + private int syncCooldown; + private int activeHotbarSlot; + private ItemStack activeSchematicItem; - private final List mirrors = Arrays.asList("none", "leftRight", "frontBack"); - private final List rotations = Arrays.asList("none", "cw90", "cw180", "cw270"); - - public Tools currentTool; - public ToolSelectionScreen selectionScreen; - - public static final int SYNC_DELAY = 20; - public int syncCooldown; - - private BlueprintHotbarOverlay overlay; + private SchematicRenderer renderer; + private SchematicHotbarSlotOverlay overlay; + private ToolSelectionScreen selectionScreen; public SchematicHandler() { + overlay = new SchematicHotbarSlotOverlay(); + renderer = new SchematicRenderer(); currentTool = Tools.Deploy; - overlay = new BlueprintHotbarOverlay(); selectionScreen = new ToolSelectionScreen(ImmutableList.of(Tools.Deploy), this::equip); + transformation = new SchematicTransformation(); } public void tick() { ClientPlayerEntity player = Minecraft.getInstance().player; + if (activeSchematicItem != null && transformation != null) + transformation.tick(); + ItemStack stack = findBlueprintInHand(player); if (stack == null) { active = false; syncCooldown = 0; - if (item != null && itemLost(player)) { - slot = 0; - item = null; - CreateClient.schematicHologram.setActive(false); + if (activeSchematicItem != null && itemLost(player)) { + activeHotbarSlot = 0; + activeSchematicItem = null; + renderer.setActive(false); } return; } - // Newly equipped - if (!active || !stack.getTag().getString("File").equals(cachedSchematicName)) { - loadSettings(stack); - cachedSchematicName = stack.getTag().getString("File"); - active = true; - if (deployed) { - Tools toolBefore = currentTool; - selectionScreen = new ToolSelectionScreen(Tools.getTools(player.isCreative()), this::equip); - if (toolBefore != null) { - selectionScreen.setSelectedElement(toolBefore); - equip(toolBefore); - } - } else - selectionScreen = new ToolSelectionScreen(ImmutableList.of(Tools.Deploy), this::equip); - sync(); - } - + if (!active || !stack.getTag().getString("File").equals(displayedSchematic)) + init(player, stack); if (!active) return; + renderer.tick(); if (syncCooldown > 0) syncCooldown--; if (syncCooldown == 1) @@ -108,22 +88,62 @@ public class SchematicHandler { currentTool.getTool().updateSelection(); } - public void render() { - if (!active) - return; - if (Minecraft.getInstance().player.isSneaking()) + private void init(ClientPlayerEntity player, ItemStack stack) { + loadSettings(stack); + displayedSchematic = stack.getTag().getString("File"); + active = true; + if (deployed) { + setupRenderer(); + Tools toolBefore = currentTool; + selectionScreen = new ToolSelectionScreen(Tools.getTools(player.isCreative()), this::equip); + if (toolBefore != null) { + selectionScreen.setSelectedElement(toolBefore); + equip(toolBefore); + } + } else + selectionScreen = new ToolSelectionScreen(ImmutableList.of(Tools.Deploy), this::equip); + } + + private void setupRenderer() { + Template schematic = SchematicItem.loadSchematic(activeSchematicItem); + if (schematic.getSize().equals(BlockPos.ZERO)) return; + SchematicWorld w = new SchematicWorld(BlockPos.ZERO, Minecraft.getInstance().world); + schematic.addBlocksToWorld(w, BlockPos.ZERO, new PlacementSettings()); + renderer.startHologram(w); + } + + public void render() { + boolean present = activeSchematicItem != null; + if (!active && !present) + return; + if (active) { + TessellatorHelper.prepareForDrawing(); + currentTool.getTool().renderTool(); + TessellatorHelper.cleanUpAfterDrawing(); + } + + GlStateManager.pushMatrix(); TessellatorHelper.prepareForDrawing(); - currentTool.getTool().renderTool(); + transformation.applyGLTransformations(); + renderer.render(); + GlStateManager.disableCull(); + + if (active) + currentTool.getTool().renderToolLocal(); + + GlStateManager.enableCull(); + GlStateManager.depthMask(true); TessellatorHelper.cleanUpAfterDrawing(); + GlStateManager.popMatrix(); } public void renderOverlay() { if (!active) return; - if (item != null) - overlay.renderOn(slot); + if (activeSchematicItem != null) + overlay.renderOn(activeHotbarSlot); currentTool.getTool().renderOverlay(); selectionScreen.renderPassive(Minecraft.getInstance().getRenderPartialTicks()); @@ -148,7 +168,6 @@ public class SchematicHandler { if (pressed && !selectionScreen.focused) selectionScreen.focused = true; - if (!pressed && selectionScreen.focused) { selectionScreen.focused = false; selectionScreen.onClose(); @@ -156,18 +175,15 @@ public class SchematicHandler { } public boolean mouseScrolled(double delta) { - if (!active) - return false; - if (Minecraft.getInstance().player.isSneaking()) + if (!active || Minecraft.getInstance().player.isSneaking()) return false; + if (selectionScreen.focused) { selectionScreen.cycle((int) delta); return true; } - if (AllKeys.ACTIVATE_TOOL.isPressed()) { + if (AllKeys.ACTIVATE_TOOL.isPressed()) return currentTool.getTool().handleMouseWheel(delta); - } - return false; } @@ -178,16 +194,16 @@ public class SchematicHandler { if (!stack.hasTag()) return null; - item = stack; - slot = player.inventory.currentItem; + activeSchematicItem = stack; + activeHotbarSlot = player.inventory.currentItem; return stack; } private boolean itemLost(PlayerEntity player) { for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) { - if (!player.inventory.getStackInSlot(i).isItemEqual(item)) + if (!player.inventory.getStackInSlot(i).isItemEqual(activeSchematicItem)) continue; - if (!ItemStack.areItemStackTagsEqual(player.inventory.getStackInSlot(i), item)) + if (!ItemStack.areItemStackTagsEqual(player.inventory.getStackInSlot(i), activeSchematicItem)) continue; return false; } @@ -196,25 +212,20 @@ public class SchematicHandler { public void markDirty() { syncCooldown = SYNC_DELAY; - CreateClient.schematicHologram.setActive(false); } public void sync() { - message(Lang.translate("schematics.synchronizing")); - AllPackets.channel.sendToServer(new NbtPacket(item, slot)); + if (activeSchematicItem == null) + return; - if (deployed) { - Template schematic = SchematicItem.getSchematic(item); + PlacementSettings settings = transformation.toSettings(); + CompoundNBT tag = activeSchematicItem.getTag(); + tag.putBoolean("Deployed", deployed); + tag.put("Anchor", NBTUtil.writeBlockPos(transformation.getAnchor())); + tag.putString("Rotation", settings.getRotation().name()); + tag.putString("Mirror", settings.getMirror().name()); - if (schematic.getSize().equals(BlockPos.ZERO)) - return; - - SchematicWorld w = new SchematicWorld(new HashMap<>(), new Cuboid(), anchor, Minecraft.getInstance().world); - PlacementSettings settings = cachedSettings.copy(); - settings.setBoundingBox(null); - schematic.addBlocksToWorld(w, anchor, settings); - CreateClient.schematicHologram.startHologram(w); - } + AllPackets.channel.sendToServer(new NbtPacket(activeSchematicItem, activeHotbarSlot)); } public void equip(Tools tool) { @@ -224,149 +235,66 @@ public class SchematicHandler { public void loadSettings(ItemStack blueprint) { CompoundNBT tag = blueprint.getTag(); - cachedSettings = new PlacementSettings(); - cachedSettings.setRotation(Rotation.valueOf(tag.getString("Rotation"))); - cachedSettings.setMirror(Mirror.valueOf(tag.getString("Mirror"))); + BlockPos anchor = BlockPos.ZERO; + PlacementSettings settings = SchematicItem.getSettings(blueprint); + transformation = new SchematicTransformation(); deployed = tag.getBoolean("Deployed"); if (deployed) anchor = NBTUtil.readBlockPos(tag.getCompound("Anchor")); + BlockPos size = NBTUtil.readBlockPos(tag.getCompound("Bounds")); - size = NBTUtil.readBlockPos(tag.getCompound("Bounds")); + bounds = new AxisAlignedBB(BlockPos.ZERO, size); + outline = new AABBOutline(bounds); + outline.disableCull = true; + transformation.init(anchor, settings, bounds); } - public void flip(Axis axis) { - - Rotation r = cachedSettings.getRotation(); - boolean rotationAt90s = r == Rotation.CLOCKWISE_90 || r == Rotation.COUNTERCLOCKWISE_90; - Mirror mirror = axis == Axis.Z ^ rotationAt90s ? Mirror.FRONT_BACK : Mirror.LEFT_RIGHT; - - BlockPos coordModifier = new BlockPos((r == Rotation.NONE || r == Rotation.COUNTERCLOCKWISE_90) ? 1 : -1, 0, - (r == Rotation.NONE || r == Rotation.CLOCKWISE_90) ? 1 : -1); - BlockPos anchorOffset = axis == Axis.Z - ? new BlockPos(((rotationAt90s ? size.getZ() : size.getX()) - 1) * coordModifier.getX(), 0, 0) - : new BlockPos(0, 0, ((!rotationAt90s ? size.getZ() : size.getX()) - 1) * coordModifier.getZ()); - - Mirror m = cachedSettings.getMirror(); - - if (m == Mirror.NONE) { - cachedSettings.setMirror(mirror); - anchor = anchor.add(anchorOffset); - message(Lang.translate("schematic.mirror") + ": " - + Lang.translate("schematic.mirror." + mirrors.get(cachedSettings.getMirror().ordinal()))); - - } else if (m == mirror) { - cachedSettings.setMirror(Mirror.NONE); - anchor = anchor.subtract(anchorOffset); - message(Lang.translate("schematic.mirror") + ": " - + Lang.translate("schematic.mirror." + mirrors.get(cachedSettings.getMirror().ordinal()))); - - } else if (m != mirror) { - cachedSettings.setMirror(Mirror.NONE); - anchor = anchor.add(anchorOffset); - cachedSettings.setRotation(r.add(Rotation.CLOCKWISE_180)); - message(Lang.translate("schematic.mirror") + ": " - + Lang.translate("schematic.mirror." + mirrors.get(cachedSettings.getMirror().ordinal())) + ", " - + Lang.translate("schematic.rotation") + ": " - + Lang.translate("schematic.rotation." + rotations.get(cachedSettings.getRotation().ordinal()))); + public void deploy() { + if (!deployed) { + List tools = Tools.getTools(Minecraft.getInstance().player.isCreative()); + selectionScreen = new ToolSelectionScreen(tools, this::equip); } - - item.getTag().put("Anchor", NBTUtil.writeBlockPos(anchor)); - item.getTag().putString("Mirror", cachedSettings.getMirror().name()); - item.getTag().putString("Rotation", r.name()); - - markDirty(); - } - - public void message(String msg) { - Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(msg), true); - } - - public void rotate(Rotation rotation) { - Rotation r = cachedSettings.getRotation(); - BlockPos center = centerOfSchematic(); - cachedSettings.setRotation(r.add(rotation)); - BlockPos diff = center.subtract(anchor); - BlockPos move = diff.subtract(diff.rotate(rotation)); - anchor = anchor.add(move); - - item.getTag().put("Anchor", NBTUtil.writeBlockPos(anchor)); - item.getTag().putString("Rotation", cachedSettings.getRotation().name()); - - message(Lang.translate("schematic.rotation") + ": " - + Lang.translate("schematic.rotation." + rotations.get(cachedSettings.getRotation().ordinal()))); - - markDirty(); - } - - public void setMirror(Mirror mirror) { - cachedSettings.setMirror(mirror); - item.getTag().putString("Mirror", cachedSettings.getMirror().name()); - markDirty(); - } - - public void setRotation(Rotation rotation) { - cachedSettings.setRotation(rotation); - item.getTag().putString("Rotation", cachedSettings.getRotation().name()); - markDirty(); - } - - public void moveTo(BlockPos anchor) { - if (!deployed) - selectionScreen = new ToolSelectionScreen(Tools.getTools(Minecraft.getInstance().player.isCreative()), - this::equip); - deployed = true; - this.anchor = anchor; - item.getTag().putBoolean("Deployed", true); - item.getTag().put("Anchor", NBTUtil.writeBlockPos(anchor)); - markDirty(); + setupRenderer(); + } + + public String getCurrentSchematicName() { + return displayedSchematic != null ? displayedSchematic : "-"; } public void printInstantly() { - AllPackets.channel.sendToServer(new SchematicPlacePacket(item.copy())); - CompoundNBT nbt = item.getTag(); + AllPackets.channel.sendToServer(new SchematicPlacePacket(activeSchematicItem.copy())); + CompoundNBT nbt = activeSchematicItem.getTag(); nbt.putBoolean("Deployed", false); - item.setTag(nbt); - CreateClient.schematicHologram.setActive(false); + activeSchematicItem.setTag(nbt); + renderer.setActive(false); active = false; + markDirty(); } - public BlockPos getTransformedSize() { - BlockPos flipped = size; - if (cachedSettings.getMirror() == Mirror.FRONT_BACK) - flipped = new BlockPos(-flipped.getX(), flipped.getY(), flipped.getZ()); - if (cachedSettings.getMirror() == Mirror.LEFT_RIGHT) - flipped = new BlockPos(flipped.getX(), flipped.getY(), -flipped.getZ()); - - BlockPos rotate = flipped.rotate(cachedSettings.getRotation()); - return rotate; + public AABBOutline getOutline() { + return outline; } - public BlockPos getTransformedAnchor() { - BlockPos anchor = this.anchor; - Rotation r = cachedSettings.getRotation(); - - BlockPos flipOffset = BlockPos.ZERO; - if (cachedSettings.getMirror() == Mirror.FRONT_BACK) - flipOffset = new BlockPos(1, 0, 0); - if (cachedSettings.getMirror() == Mirror.LEFT_RIGHT) - flipOffset = new BlockPos(0, 0, 1); - - flipOffset = flipOffset.rotate(r); - anchor = anchor.add(flipOffset); - - if (r == Rotation.CLOCKWISE_90 || r == Rotation.CLOCKWISE_180) - anchor = anchor.add(1, 0, 0); - if (r == Rotation.COUNTERCLOCKWISE_90 || r == Rotation.CLOCKWISE_180) - anchor = anchor.add(0, 0, 1); - return anchor; + public boolean isActive() { + return active; } - public BlockPos centerOfSchematic() { - BlockPos size = getTransformedSize(); - BlockPos center = new BlockPos(size.getX() / 2, 0, size.getZ() / 2); - return anchor.add(center); + public AxisAlignedBB getBounds() { + return bounds; + } + + public SchematicTransformation getTransformation() { + return transformation; + } + + public boolean isDeployed() { + return deployed; + } + + public ItemStack getActiveSchematicItem() { + return activeSchematicItem; } } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java deleted file mode 100644 index d0b973cdc..000000000 --- a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHologram.java +++ /dev/null @@ -1,200 +0,0 @@ -package com.simibubi.create.modules.schematics.client; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; - -import org.lwjgl.opengl.GL11; - -import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.foundation.type.Cuboid; -import com.simibubi.create.modules.schematics.SchematicWorld; - -import net.minecraft.block.BedBlock; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ActiveRenderInfo; -import net.minecraft.client.renderer.BlockRendererDispatcher; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.RegionRenderCacheBuilder; -import net.minecraft.client.renderer.texture.AtlasTexture; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.client.renderer.vertex.VertexFormat; -import net.minecraft.client.renderer.vertex.VertexFormatElement; -import net.minecraft.client.renderer.vertex.VertexFormatElement.Usage; -import net.minecraft.entity.Entity; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.gen.feature.template.PlacementSettings; -import net.minecraft.world.gen.feature.template.Template; -import net.minecraftforge.client.ForgeHooksClient; -import net.minecraftforge.client.model.data.EmptyModelData; - -public class SchematicHologram { - - private final RegionRenderCacheBuilder bufferCache = new RegionRenderCacheBuilder(); - private final boolean[] usedBlockRenderLayers = new boolean[BlockRenderLayer.values().length]; - private final boolean[] startedBufferBuilders = new boolean[BlockRenderLayer.values().length]; - private boolean active; - private boolean changed; - private SchematicWorld schematic; - private BlockPos anchor; - - public SchematicHologram() { - changed = false; - } - - public void startHologram(Template schematic, BlockPos anchor) { - SchematicWorld world = new SchematicWorld(new HashMap<>(), new Cuboid(BlockPos.ZERO, BlockPos.ZERO), anchor, - Minecraft.getInstance().world); - schematic.addBlocksToWorld(world, anchor, new PlacementSettings()); - startHologram(world); - } - - public void startHologram(SchematicWorld world) { - this.anchor = world.anchor; - this.schematic = world; - this.active = true; - this.changed = true; - } - - public void setActive(boolean active) { - this.active = active; - } - - public void update() { - changed = true; - } - - public void tick() { - if (!active) - return; - Minecraft minecraft = Minecraft.getInstance(); - if (minecraft.world == null) - return; - if (minecraft.player == null) - return; - if (changed) { - redraw(minecraft); - changed = false; - } - } - - private void redraw(Minecraft minecraft) { - Arrays.fill(usedBlockRenderLayers, false); - Arrays.fill(startedBufferBuilders, false); - - final SchematicWorld blockAccess = schematic; - final BlockRendererDispatcher blockRendererDispatcher = minecraft.getBlockRendererDispatcher(); - - List blockstates = new LinkedList<>(); - - for (BlockPos localPos : BlockPos.getAllInBoxMutable(blockAccess.getBounds().getOrigin(), - blockAccess.getBounds().getOrigin().add(blockAccess.getBounds().getSize()))) { - BlockPos pos = localPos.add(anchor); - BlockState state = blockAccess.getBlockState(pos); - for (BlockRenderLayer blockRenderLayer : BlockRenderLayer.values()) { - if (!state.getBlock().canRenderInLayer(state, blockRenderLayer)) { - continue; - } - ForgeHooksClient.setRenderLayer(blockRenderLayer); - final int blockRenderLayerId = blockRenderLayer.ordinal(); - final BufferBuilder bufferBuilder = bufferCache.getBuilder(blockRenderLayerId); - if (!startedBufferBuilders[blockRenderLayerId]) { - startedBufferBuilders[blockRenderLayerId] = true; - // Copied from RenderChunk - { - bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); - } - } - // OptiFine Shaders compatibility - // if (Config.isShaders()) SVertexBuilder.pushEntity(state, pos, - // blockAccess, bufferBuilder); - - // Block transformations - if (state.getBlock() instanceof BedBlock) { - state = Blocks.QUARTZ_SLAB.getDefaultState(); - } - - usedBlockRenderLayers[blockRenderLayerId] |= blockRendererDispatcher.renderBlock(state, pos, - blockAccess, bufferBuilder, minecraft.world.rand, EmptyModelData.INSTANCE); - blockstates.add(state); - // if (Config.isShaders()) - // SVertexBuilder.popEntity(bufferBuilder); - } - ForgeHooksClient.setRenderLayer(null); - } - - // finishDrawing - for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) { - if (!startedBufferBuilders[blockRenderLayerId]) { - continue; - } - bufferCache.getBuilder(blockRenderLayerId).finishDrawing(); - } - } - - public void render() { - if (active) { - final Entity entity = Minecraft.getInstance().getRenderViewEntity(); - - if (entity == null) { - return; - } - - ActiveRenderInfo renderInfo = Minecraft.getInstance().gameRenderer.getActiveRenderInfo(); - Vec3d view = renderInfo.getProjectedView(); - double renderPosX = view.x; - double renderPosY = view.y; - double renderPosZ = view.z; - - GlStateManager.enableAlphaTest(); - GlStateManager.enableBlend(); - Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); - - for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) { - if (!usedBlockRenderLayers[blockRenderLayerId]) { - continue; - } - final BufferBuilder bufferBuilder = bufferCache.getBuilder(blockRenderLayerId); - GlStateManager.pushMatrix(); - GlStateManager.translated(-renderPosX, -renderPosY, -renderPosZ); - drawBuffer(bufferBuilder); - GlStateManager.popMatrix(); - } - GlStateManager.disableBlend(); - } - } - - // Coppied from the Tesselator's vboUploader - Draw everything but don't - // reset the buffer - private static void drawBuffer(final BufferBuilder bufferBuilder) { - if (bufferBuilder.getVertexCount() > 0) { - - VertexFormat vertexformat = bufferBuilder.getVertexFormat(); - int size = vertexformat.getSize(); - ByteBuffer bytebuffer = bufferBuilder.getByteBuffer(); - List list = vertexformat.getElements(); - - for (int index = 0; index < list.size(); ++index) { - VertexFormatElement vertexformatelement = list.get(index); - Usage usage = vertexformatelement.getUsage(); - bytebuffer.position(vertexformat.getOffset(index)); - usage.preDraw(vertexformat, index, size, bytebuffer); - } - - GlStateManager.drawArrays(bufferBuilder.getDrawMode(), 0, bufferBuilder.getVertexCount()); - - for (int index = 0; index < list.size(); ++index) { - VertexFormatElement vertexformatelement = list.get(index); - Usage usage = vertexformatelement.getUsage(); - usage.postDraw(vertexformat, index, size, bytebuffer); - } - } - } - -} diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/BlueprintHotbarOverlay.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHotbarSlotOverlay.java similarity index 90% rename from src/main/java/com/simibubi/create/modules/schematics/client/BlueprintHotbarOverlay.java rename to src/main/java/com/simibubi/create/modules/schematics/client/SchematicHotbarSlotOverlay.java index 125d09bd1..ccd84926a 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/BlueprintHotbarOverlay.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicHotbarSlotOverlay.java @@ -7,7 +7,7 @@ import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.AbstractGui; -public class BlueprintHotbarOverlay extends AbstractGui { +public class SchematicHotbarSlotOverlay extends AbstractGui { public void renderOn(int slot) { MainWindow mainWindow = Minecraft.getInstance().mainWindow; diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicRenderer.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicRenderer.java new file mode 100644 index 000000000..04c81c186 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicRenderer.java @@ -0,0 +1,166 @@ +package com.simibubi.create.modules.schematics.client; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllSpecialTextures; +import com.simibubi.create.foundation.utility.outliner.AABBOutline; +import com.simibubi.create.foundation.utility.render.StructureRenderer; +import com.simibubi.create.modules.schematics.SchematicWorld; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.RegionRenderCacheBuilder; +import net.minecraft.client.renderer.texture.AtlasTexture; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.client.renderer.vertex.VertexFormatElement.Usage; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.data.EmptyModelData; + +public class SchematicRenderer { + + private final RegionRenderCacheBuilder bufferCache = new RegionRenderCacheBuilder(); + private final boolean[] usedBlockRenderLayers = new boolean[BlockRenderLayer.values().length]; + private final boolean[] startedBufferBuilders = new boolean[BlockRenderLayer.values().length]; + private boolean active; + private boolean changed; + private SchematicWorld schematic; + private AABBOutline outline; + private BlockPos anchor; + + public SchematicRenderer() { + changed = false; + } + + public void startHologram(SchematicWorld world) { + this.anchor = world.anchor; + this.schematic = world; + this.active = true; + this.changed = true; + } + + public void setActive(boolean active) { + this.active = active; + } + + public void update() { + changed = true; + } + + public void tick() { + if (!active) + return; + Minecraft mc = Minecraft.getInstance(); + if (mc.world == null || mc.player == null || !changed) + return; + + redraw(mc); + changed = false; + } + + public void render() { + if (!active) + return; + + GlStateManager.disableCull(); + GlStateManager.enableAlphaTest(); + GlStateManager.depthMask(true); + Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); + + for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) + if (usedBlockRenderLayers[blockRenderLayerId]) + drawBuffer(bufferCache.getBuilder(blockRenderLayerId)); + + GlStateManager.pushMatrix(); + Vec3d position = new Vec3d(anchor); + Vec3d rotation = Vec3d.ZERO; + StructureRenderer.renderTileEntities(schematic, position, rotation, schematic.getTileEntities()); + GlStateManager.popMatrix(); + } + + private void redraw(Minecraft minecraft) { + Arrays.fill(usedBlockRenderLayers, false); + Arrays.fill(startedBufferBuilders, false); + + SchematicWorld blockAccess = schematic; + blockAccess.renderMode = true; + BlockRendererDispatcher blockRendererDispatcher = minecraft.getBlockRendererDispatcher(); + List blockstates = new LinkedList<>(); + BlockPos min = blockAccess.getBounds().getOrigin(); + BlockPos max = min.add(blockAccess.getBounds().getSize()); + outline = new AABBOutline(new AxisAlignedBB(min, max)); + outline.setTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED); + + for (BlockPos localPos : BlockPos.getAllInBoxMutable(min, max)) { + BlockPos pos = localPos.add(anchor); + BlockState state = blockAccess.getBlockState(pos); + + for (BlockRenderLayer blockRenderLayer : BlockRenderLayer.values()) { + if (!state.getBlock().canRenderInLayer(state, blockRenderLayer)) + continue; + ForgeHooksClient.setRenderLayer(blockRenderLayer); + + final int blockRenderLayerId = blockRenderLayer.ordinal(); + final BufferBuilder bufferBuilder = bufferCache.getBuilder(blockRenderLayerId); + if (!startedBufferBuilders[blockRenderLayerId]) { + startedBufferBuilders[blockRenderLayerId] = true; + bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + } + + usedBlockRenderLayers[blockRenderLayerId] |= blockRendererDispatcher.renderBlock(state, pos, + blockAccess, bufferBuilder, minecraft.world.rand, EmptyModelData.INSTANCE); + blockstates.add(state); + } + ForgeHooksClient.setRenderLayer(null); + } + + // finishDrawing + blockAccess.renderMode = false; + for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) { + if (!startedBufferBuilders[blockRenderLayerId]) + continue; + bufferCache.getBuilder(blockRenderLayerId).finishDrawing(); + } + } + + // Coppied from the Tesselator's vboUploader - Draw everything but don't + // reset the buffer + private static void drawBuffer(final BufferBuilder bufferBuilder) { + if (bufferBuilder.getVertexCount() <= 0) + return; + + VertexFormat vertexformat = bufferBuilder.getVertexFormat(); + int size = vertexformat.getSize(); + ByteBuffer bytebuffer = bufferBuilder.getByteBuffer(); + List list = vertexformat.getElements(); + + for (int index = 0; index < list.size(); ++index) { + VertexFormatElement vertexformatelement = list.get(index); + Usage usage = vertexformatelement.getUsage(); + bytebuffer.position(vertexformat.getOffset(index)); + usage.preDraw(vertexformat, index, size, bytebuffer); + } + + GlStateManager.drawArrays(bufferBuilder.getDrawMode(), 0, bufferBuilder.getVertexCount()); + + for (int index = 0; index < list.size(); ++index) { + VertexFormatElement vertexformatelement = list.get(index); + Usage usage = vertexformatelement.getUsage(); + usage.postDraw(vertexformat, index, size, bytebuffer); + } + } + +} diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java new file mode 100644 index 000000000..008b4c8ee --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java @@ -0,0 +1,208 @@ +package com.simibubi.create.modules.schematics.client; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingAngle; +import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.gen.feature.template.PlacementSettings; + +public class SchematicTransformation { + + private InterpolatedChasingValue x, y, z, scaleFrontBack, scaleLeftRight; + private InterpolatedChasingAngle rotation; + private double xOrigin; + private double zOrigin; + + public SchematicTransformation() { + x = new InterpolatedChasingValue(); + y = new InterpolatedChasingValue(); + z = new InterpolatedChasingValue(); + scaleFrontBack = new InterpolatedChasingValue(); + scaleLeftRight = new InterpolatedChasingValue(); + rotation = new InterpolatedChasingAngle(); + } + + public void init(BlockPos anchor, PlacementSettings settings, AxisAlignedBB bounds) { + int leftRight = settings.getMirror() == Mirror.LEFT_RIGHT ? -1 : 1; + int frontBack = settings.getMirror() == Mirror.FRONT_BACK ? -1 : 1; + scaleFrontBack.start(frontBack); + scaleLeftRight.start(leftRight); + xOrigin = bounds.getXSize() / 2f; + zOrigin = bounds.getZSize() / 2f; + + int r = -(settings.getRotation().ordinal() * 90); + rotation.start(r); + + Vec3d vec = fromAnchor(anchor); + x.start((float) vec.x); + y.start((float) vec.y); + z.start((float) vec.z); + } + + public void applyGLTransformations() { + float pt = Minecraft.getInstance().getRenderPartialTicks(); + + // Translation + GlStateManager.translated(x.get(pt), y.get(pt), z.get(pt)); + + Vec3d rotationOffset = getRotationOffset(true); + + // Rotation & Mirror + GlStateManager.translated(xOrigin + rotationOffset.x, 0, zOrigin + rotationOffset.z); + GlStateManager.rotated(rotation.get(pt), 0, 1, 0); + GlStateManager.translated(-rotationOffset.x, 0, -rotationOffset.z); + GlStateManager.scaled(scaleFrontBack.get(pt), 1, scaleLeftRight.get(pt)); + GlStateManager.translated(-xOrigin, 0, -zOrigin); + + } + + public Vec3d getRotationOffset(boolean ignoreMirrors) { + Vec3d rotationOffset = Vec3d.ZERO; + if ((int) (zOrigin * 2) % 2 != (int) (xOrigin * 2) % 2) { + boolean xGreaterZ = xOrigin > zOrigin; + float xIn = (xGreaterZ ? 0 : .5f); + float zIn = (!xGreaterZ ? 0 : .5f); + if (!ignoreMirrors) { + xIn *= getMirrorModifier(Axis.X); + zIn *= getMirrorModifier(Axis.Z); + } + rotationOffset = new Vec3d(xIn, 0, zIn); + } + return rotationOffset; + } + + public Vec3d toLocalSpace(Vec3d vec) { + float pt = Minecraft.getInstance().getRenderPartialTicks(); + Vec3d rotationOffset = getRotationOffset(true); + + vec = vec.subtract(x.get(pt), y.get(pt), z.get(pt)); + vec = vec.subtract(xOrigin + rotationOffset.x, 0, zOrigin + rotationOffset.z); + vec = VecHelper.rotate(vec, -rotation.get(pt), Axis.Y); + vec = vec.add(rotationOffset.x, 0, rotationOffset.z); + vec = vec.mul(scaleFrontBack.get(pt), 1, scaleLeftRight.get(pt)); + vec = vec.add(xOrigin, 0, zOrigin); + + return vec; + } + + public PlacementSettings toSettings() { + PlacementSettings settings = new PlacementSettings(); + + int i = (int) rotation.getTarget(); + + boolean mirrorlr = scaleLeftRight.getTarget() < 0; + boolean mirrorfb = scaleFrontBack.getTarget() < 0; + if (mirrorlr && mirrorfb) { + mirrorlr = mirrorfb = false; + i += 180; + } + i = i % 360; + if (i < 0) + i += 360; + + Rotation rotation = Rotation.NONE; + switch (i) { + case 90: + rotation = Rotation.COUNTERCLOCKWISE_90; + break; + case 180: + rotation = Rotation.CLOCKWISE_180; + break; + case 270: + rotation = Rotation.CLOCKWISE_90; + break; + default: + } + + settings.setRotation(rotation); + if (mirrorfb) + settings.setMirror(Mirror.FRONT_BACK); + if (mirrorlr) + settings.setMirror(Mirror.LEFT_RIGHT); + + return settings; + } + + public BlockPos getAnchor() { + Vec3d vec = Vec3d.ZERO.add(.5, 0, .5); + Vec3d rotationOffset = getRotationOffset(false); + vec = vec.subtract(xOrigin, 0, zOrigin); + vec = vec.subtract(rotationOffset.x, 0, rotationOffset.z); + vec = vec.mul(scaleFrontBack.getTarget(), 1, scaleLeftRight.getTarget()); + vec = VecHelper.rotate(vec, rotation.getTarget(), Axis.Y); + vec = vec.add(xOrigin, 0, zOrigin); + + vec = vec.add(x.getTarget(), y.getTarget(), z.getTarget()); + return new BlockPos(vec.x, vec.y, vec.z); + } + + public Vec3d fromAnchor(BlockPos pos) { + Vec3d vec = Vec3d.ZERO.add(.5, 0, .5); + Vec3d rotationOffset = getRotationOffset(false); + vec = vec.subtract(xOrigin, 0, zOrigin); + vec = vec.subtract(rotationOffset.x, 0, rotationOffset.z); + vec = vec.mul(scaleFrontBack.getTarget(), 1, scaleLeftRight.getTarget()); + vec = VecHelper.rotate(vec, rotation.getTarget(), Axis.Y); + vec = vec.add(xOrigin, 0, zOrigin); + + return new Vec3d(pos.subtract(new BlockPos(vec.x, vec.y, vec.z))); + } + + public int getRotationTarget() { + return (int) rotation.getTarget(); + } + + public int getMirrorModifier(Axis axis) { + if (axis == Axis.Z) + return (int) scaleLeftRight.getTarget(); + return (int) scaleFrontBack.getTarget(); + } + + public float getCurrentRotation() { + float pt = Minecraft.getInstance().getRenderPartialTicks(); + return rotation.get(pt); + } + + public void tick() { + x.tick(); + y.tick(); + z.tick(); + scaleLeftRight.tick(); + scaleFrontBack.tick(); + rotation.tick(); + } + + public void flip(Axis axis) { + if (axis == Axis.X) + scaleLeftRight.target(scaleLeftRight.getTarget() * -1); + if (axis == Axis.Z) + scaleFrontBack.target(scaleFrontBack.getTarget() * -1); + } + + public void rotate90(boolean clockwise) { + rotation.target(rotation.getTarget() + (clockwise ? -90 : 90)); + } + + public void move(float xIn, float yIn, float zIn) { + moveTo(x.getTarget() + xIn, y.getTarget() + yIn, z.getTarget() + zIn); + } + + public void moveTo(BlockPos pos) { + moveTo(pos.getX(), pos.getY(), pos.getZ()); + } + + public void moveTo(float xIn, float yIn, float zIn) { + x.target(xIn); + y.target(yIn); + z.target(zIn); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java index 306e79f02..417a0cf5e 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java @@ -2,11 +2,17 @@ package com.simibubi.create.modules.schematics.client.tools; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllKeys; +import com.simibubi.create.AllSpecialTextures; +import com.simibubi.create.modules.schematics.client.SchematicTransformation; -import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTUtil; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.Vec3d; public class DeployTool extends PlacementToolBase { @@ -15,68 +21,78 @@ public class DeployTool extends PlacementToolBase { super.init(); selectionRange = -1; } - + @Override public void updateSelection() { - if (schematicHandler.active && selectionRange == -1) { - selectionRange = (int) schematicHandler.size.manhattanDistance(BlockPos.ZERO) / 2; + if (schematicHandler.isActive() && selectionRange == -1) { + selectionRange = (int) (schematicHandler.getBounds().getCenter().length() / 2); selectionRange = MathHelper.clamp(selectionRange, 1, 100); } selectIgnoreBlocks = AllKeys.ACTIVATE_TOOL.isPressed(); - super.updateSelection(); } - + @Override public void renderTool() { super.renderTool(); - - if (selectedPos == null) + + if (selectedPos == null) return; - - BlockPos size = schematicHandler.getTransformedSize(); - BlockPos min = selectedPos.add(Math.round(size.getX() * -.5f), 0, Math.round(size.getZ() * -.5f)); - BlockPos max = min.add(size.getX(), size.getY(), size.getZ()); - - if (schematicHandler.deployed) { - MutableBoundingBox bb = new MutableBoundingBox(min, min.add(schematicHandler.getTransformedSize())); - min = new BlockPos(bb.minX, bb.minY, bb.minZ); - max = new BlockPos(bb.maxX, bb.maxY, bb.maxZ); - } - - GlStateManager.lineWidth(2); - GlStateManager.color4f(.5f, .8f, 1, 1); - GlStateManager.disableTexture(); - - WorldRenderer.drawBoundingBox(min.getX() - 1 / 8d, min.getY() + 1 / 16d, min.getZ() - 1 / 8d, - max.getX() + 1 / 8d, max.getY() + 1 / 8d, max.getZ() + 1 / 8d, .8f, .9f, 1, 1); - - GlStateManager.lineWidth(1); - GlStateManager.enableTexture(); - + + GlStateManager.pushMatrix(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.enableBlend(); + float pt = Minecraft.getInstance().getRenderPartialTicks(); + double x = MathHelper.lerp(pt, lastChasingSelectedPos.x, chasingSelectedPos.x); + double y = MathHelper.lerp(pt, lastChasingSelectedPos.y, chasingSelectedPos.y); + double z = MathHelper.lerp(pt, lastChasingSelectedPos.z, chasingSelectedPos.z); + + SchematicTransformation transformation = schematicHandler.getTransformation(); + Vec3d center = schematicHandler.getBounds().getCenter(); + Vec3d offset = transformation.getRotationOffset(true); + + if (schematicHandler.getBounds().getXSize() % 2 == 1 || schematicHandler.getBounds().getZSize() % 2 == 1) + GlStateManager.translated(.5f, 0, .5f); + GlStateManager.translated(x, y, z); + GlStateManager.rotated(transformation.getCurrentRotation(), 0, 1, 0); + GlStateManager.translated(-offset.x, 0, -offset.z); + GlStateManager.translated(-(center.x), 0, -(center.z)); + + schematicHandler.getOutline().setTextures(AllSpecialTextures.CHECKERED, null); + schematicHandler.getOutline().render(Tessellator.getInstance().getBuffer()); + schematicHandler.getOutline().setTextures(null, null); + GlStateManager.popMatrix(); } - + @Override public boolean handleMouseWheel(double delta) { - + if (selectIgnoreBlocks) { selectionRange += delta; selectionRange = MathHelper.clamp(selectionRange, 1, 100); return true; } - + return super.handleMouseWheel(delta); } - + @Override public boolean handleRightClick() { if (selectedPos == null) return super.handleRightClick(); - - BlockPos size = schematicHandler.getTransformedSize(); - schematicHandler.moveTo(selectedPos.add(Math.round(size.getX() * -.5f), 0, Math.round(size.getZ() * -.5f))); - + Vec3d center = schematicHandler.getBounds().getCenter(); + BlockPos target = selectedPos.add(-((int) center.x), 0, -((int) center.z)); + + ItemStack item = schematicHandler.getActiveSchematicItem(); + if (item != null) { + item.getTag().putBoolean("Deployed", true); + item.getTag().put("Anchor", NBTUtil.writeBlockPos(target)); + } + + schematicHandler.getTransformation().moveTo(target); + schematicHandler.markDirty(); + schematicHandler.deploy(); return true; } - + } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java index c404d4b58..2e9cba5ab 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java @@ -1,11 +1,28 @@ package com.simibubi.create.modules.schematics.client.tools; +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllSpecialTextures; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.outliner.AABBOutline; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; + public class FlipTool extends PlacementToolBase { @Override public void init() { super.init(); - renderSelectedFace = true; + renderSelectedFace = false; } @Override @@ -23,17 +40,69 @@ public class FlipTool extends PlacementToolBase { @Override public void updateSelection() { super.updateSelection(); - - if (!schematicSelected) - return; - - renderSelectedFace = selectedFace.getAxis().isHorizontal(); } private void mirror() { if (schematicSelected && selectedFace.getAxis().isHorizontal()) { - schematicHandler.flip(selectedFace.getAxis()); + schematicHandler.getTransformation().flip(selectedFace.getAxis()); + schematicHandler.markDirty(); } } + @Override + public void renderToolLocal() { + super.renderToolLocal(); + + if (!schematicSelected || !selectedFace.getAxis().isHorizontal()) + return; + + GlStateManager.pushMatrix(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.enableBlend(); + + Direction facing = selectedFace.rotateY(); + Axis axis = facing.getAxis(); + Vec3d color = ColorHelper.getRGB(0x4d80e4); + AxisAlignedBB bounds = schematicHandler.getBounds(); + + Vec3d plane = VecHelper.planeByNormal(new Vec3d(facing.getDirectionVec())); + plane = plane.mul(bounds.getXSize() / 2f + 1, bounds.getYSize() / 2f + 1, bounds.getZSize() / 2f + 1); + Vec3d center = bounds.getCenter(); + + Vec3d v1 = plane.add(center); + plane = plane.mul(-1, 1, -1); + Vec3d v2 = plane.add(center); + plane = plane.mul(1, -1, 1); + Vec3d v3 = plane.add(center); + plane = plane.mul(-1, 1, -1); + Vec3d v4 = plane.add(center); + + BufferBuilder buffer = Tessellator.getInstance().getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + AABBOutline outline = schematicHandler.getOutline(); + AllSpecialTextures.BLANK.bind(); + outline.renderAACuboidLine(v1, v2, color, 1, buffer); + outline.renderAACuboidLine(v2, v3, color, 1, buffer); + outline.renderAACuboidLine(v3, v4, color, 1, buffer); + outline.renderAACuboidLine(v4, v1, color, 1, buffer); + + Tessellator.getInstance().draw(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_REPEAT); + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_REPEAT); + GlStateManager.depthMask(false); + Vec3d uDiff = v2.subtract(v1); + Vec3d vDiff = v4.subtract(v1); + float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); + float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); + + GlStateManager.enableCull(); + AllSpecialTextures.HIGHLIGHT_CHECKERED.bind(); + outline.putQuadUV(v1, v2, v3, v4, 0, 0, maxU, maxV, color, 1, buffer); + outline.putQuadUV(v2, v1, v4, v3, 0, 0, maxU, maxV, color, 1, buffer); + Tessellator.getInstance().draw(); + GlStateManager.popMatrix(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/ISchematicTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/ISchematicTool.java index dc86fa1c6..5c892b78b 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/ISchematicTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/ISchematicTool.java @@ -10,6 +10,7 @@ public interface ISchematicTool { public void renderTool(); public void renderOverlay(); + public void renderToolLocal(); } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveTool.java index 80500ba89..116f2f81f 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveTool.java @@ -1,5 +1,11 @@ package com.simibubi.create.modules.schematics.client.tools; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.schematics.client.SchematicTransformation; + +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; + public class MoveTool extends PlacementToolBase { @Override @@ -17,13 +23,19 @@ public class MoveTool extends PlacementToolBase { renderSelectedFace = selectedFace.getAxis().isHorizontal(); } - + @Override public boolean handleMouseWheel(double delta) { - if (schematicSelected && selectedFace.getAxis().isHorizontal()) { - schematicHandler.moveTo(delta < 0 ? schematicHandler.anchor.add(selectedFace.getDirectionVec()) - : schematicHandler.anchor.subtract(selectedFace.getDirectionVec())); - } + if (!schematicSelected || !selectedFace.getAxis().isHorizontal()) + return true; + + SchematicTransformation transformation = schematicHandler.getTransformation(); + Vec3d vec = new Vec3d(selectedFace.getDirectionVec()).scale(-Math.signum(delta)); + vec = vec.mul(transformation.getMirrorModifier(Axis.X), 1, transformation.getMirrorModifier(Axis.Z)); + vec = VecHelper.rotate(vec, transformation.getRotationTarget(), Axis.Y); + transformation.move((float) vec.x, 0, (float) vec.z); + schematicHandler.markDirty(); + return true; } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveVerticalTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveVerticalTool.java index 3910a0a22..a0d583018 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveVerticalTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/MoveVerticalTool.java @@ -4,8 +4,9 @@ public class MoveVerticalTool extends PlacementToolBase { @Override public boolean handleMouseWheel(double delta) { - if (schematicHandler.deployed) { - schematicHandler.moveTo(schematicHandler.anchor.add(0, delta, 0)); + if (schematicHandler.isDeployed()) { + schematicHandler.getTransformation().move(0, (float) Math.signum(delta), 0); + schematicHandler.markDirty(); } return true; } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java index 171f132f0..91d2fc51f 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java @@ -1,13 +1,47 @@ package com.simibubi.create.modules.schematics.client.tools; -import net.minecraft.util.Rotation; +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; public class RotateTool extends PlacementToolBase { @Override public boolean handleMouseWheel(double delta) { - schematicHandler.rotate(delta > 0 ? Rotation.CLOCKWISE_90 : Rotation.COUNTERCLOCKWISE_90); + schematicHandler.getTransformation().rotate90(delta > 0); + schematicHandler.markDirty(); return true; } + @Override + public void renderToolLocal() { + super.renderToolLocal(); + + GlStateManager.pushMatrix(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.enableBlend(); + + Vec3d color = ColorHelper.getRGB(0x4d80e4); + AxisAlignedBB bounds = schematicHandler.getBounds(); + double height = bounds.getYSize() + Math.max(20, bounds.getYSize()); + + Vec3d center = bounds.getCenter().add(schematicHandler.getTransformation().getRotationOffset(false)); + Vec3d start = center.subtract(0, height / 2, 0); + Vec3d end = center.add(0, height / 2, 0); + + BufferBuilder buffer = Tessellator.getInstance().getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + schematicHandler.getOutline().renderAACuboidLine(start, end, color, 1, buffer); + Tessellator.getInstance().draw(); + GlStateManager.popMatrix(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/SchematicToolBase.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/SchematicToolBase.java index 9c7d150c5..80ff83752 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/SchematicToolBase.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/SchematicToolBase.java @@ -1,22 +1,27 @@ package com.simibubi.create.modules.schematics.client.tools; +import java.util.Arrays; +import java.util.List; + import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllKeys; +import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.utility.RaycastHelper; import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.outliner.AABBOutline; import com.simibubi.create.modules.schematics.client.SchematicHandler; +import com.simibubi.create.modules.schematics.client.SchematicTransformation; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; -import net.minecraft.client.renderer.WorldRenderer; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.item.ItemUseContext; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.Direction; -import net.minecraft.util.Hand; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.MutableBoundingBox; import net.minecraft.util.math.RayTraceResult.Type; import net.minecraft.util.math.Vec3d; @@ -24,13 +29,18 @@ public abstract class SchematicToolBase implements ISchematicTool { protected SchematicHandler schematicHandler; - public BlockPos selectedPos; - public boolean selectIgnoreBlocks; - public int selectionRange; + protected BlockPos selectedPos; + protected Vec3d chasingSelectedPos; + protected Vec3d lastChasingSelectedPos; - public boolean schematicSelected; - public boolean renderSelectedFace; - public Direction selectedFace; + protected boolean selectIgnoreBlocks; + protected int selectionRange; + protected boolean schematicSelected; + protected boolean renderSelectedFace; + protected Direction selectedFace; + + protected final List mirrors = Arrays.asList("none", "leftRight", "frontBack"); + protected final List rotations = Arrays.asList("none", "cw90", "cw180", "cw270"); @Override public void init() { @@ -38,86 +48,95 @@ public abstract class SchematicToolBase implements ISchematicTool { selectedPos = null; selectedFace = null; schematicSelected = false; + chasingSelectedPos = Vec3d.ZERO; + lastChasingSelectedPos = Vec3d.ZERO; } @Override public void updateSelection() { + updateTargetPos(); + + if (selectedPos == null) + return; + lastChasingSelectedPos = chasingSelectedPos; + Vec3d target = new Vec3d(selectedPos); + if (target.distanceTo(chasingSelectedPos) < 1 / 512f) { + chasingSelectedPos = target; + return; + } + + chasingSelectedPos = chasingSelectedPos.add(target.subtract(chasingSelectedPos).scale(1 / 2f)); + } + + public void updateTargetPos() { ClientPlayerEntity player = Minecraft.getInstance().player; // Select Blueprint - if (schematicHandler.deployed) { - BlockPos min = schematicHandler.getTransformedAnchor(); - MutableBoundingBox bb = new MutableBoundingBox(min, min.add(schematicHandler.getTransformedSize())); - PredicateTraceResult result = RaycastHelper.rayTraceUntil(player, 70, - pos -> bb.isVecInside(pos)); + if (schematicHandler.isDeployed()) { + SchematicTransformation transformation = schematicHandler.getTransformation(); + AxisAlignedBB localBounds = schematicHandler.getBounds(); + + Vec3d traceOrigin = RaycastHelper.getTraceOrigin(player); + Vec3d start = transformation.toLocalSpace(traceOrigin); + Vec3d end = transformation.toLocalSpace(RaycastHelper.getTraceTarget(player, 70, traceOrigin)); + PredicateTraceResult result = + RaycastHelper.rayTraceUntil(start, end, pos -> localBounds.contains(VecHelper.getCenterOf(pos))); + schematicSelected = !result.missed(); selectedFace = schematicSelected ? result.getFacing() : null; } + boolean snap = this.selectedPos == null; + // Select location at distance if (selectIgnoreBlocks) { - selectedPos = new BlockPos(player.getEyePosition(Minecraft.getInstance().getRenderPartialTicks()) - .add(player.getLookVec().scale(selectionRange))); + float pt = Minecraft.getInstance().getRenderPartialTicks(); + selectedPos = new BlockPos(player.getEyePosition(pt).add(player.getLookVec().scale(selectionRange))); + if (snap) + lastChasingSelectedPos = chasingSelectedPos = new Vec3d(selectedPos); return; } // Select targeted Block + selectedPos = null; BlockRayTraceResult trace = RaycastHelper.rayTraceRange(player.world, player, 75); - if (trace != null && trace.getType() == Type.BLOCK) { + if (trace == null || trace.getType() != Type.BLOCK) + return; - BlockPos hit = new BlockPos(trace.getHitVec()); - boolean replaceable = player.world.getBlockState(hit) - .isReplaceable(new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, trace))); - if (trace.getFace().getAxis().isVertical() && !replaceable) - hit = hit.offset(trace.getFace()); - - selectedPos = hit; - } else { - selectedPos = null; - } + BlockPos hit = new BlockPos(trace.getHitVec()); + boolean replaceable = player.world.getBlockState(hit).getMaterial().isReplaceable(); + if (trace.getFace().getAxis().isVertical() && !replaceable) + hit = hit.offset(trace.getFace()); + selectedPos = hit; + if (snap) + lastChasingSelectedPos = chasingSelectedPos = new Vec3d(selectedPos); } @Override - public void renderTool() { - - if (schematicHandler.deployed) { - GlStateManager.lineWidth(2); - GlStateManager.color4f(1, 1, 1, 1); - GlStateManager.disableTexture(); - - BlockPos min = schematicHandler.getTransformedAnchor(); - MutableBoundingBox bb = new MutableBoundingBox(min, min.add(schematicHandler.getTransformedSize())); - min = new BlockPos(bb.minX, bb.minY, bb.minZ); - BlockPos max = new BlockPos(bb.maxX, bb.maxY, bb.maxZ); - - WorldRenderer.drawBoundingBox(min.getX() - 1 / 8d, min.getY() + 1 / 16d, min.getZ() - 1 / 8d, - max.getX() + 1 / 8d, max.getY() + 1 / 8d, max.getZ() + 1 / 8d, 1, 1, 1, 1); - - if (schematicSelected && renderSelectedFace && AllKeys.ACTIVATE_TOOL.isPressed()) { - Vec3d vec = new Vec3d(selectedFace.getDirectionVec()); - Vec3d center = new Vec3d(min.add(max)).scale(1 / 2f); - Vec3d radii = new Vec3d(max.subtract(min)).scale(1 / 2f); - - Vec3d onFaceOffset = new Vec3d(1 - Math.abs(vec.x), 1 - Math.abs(vec.y), 1 - Math.abs(vec.z)) - .mul(radii); - Vec3d faceMin = center.add(vec.mul(radii).add(onFaceOffset)).add(vec.scale(1/8f)); - Vec3d faceMax = center.add(vec.mul(radii).subtract(onFaceOffset)).add(vec.scale(1/8f)); - - GlStateManager.lineWidth(6); - WorldRenderer.drawBoundingBox(faceMin.getX(), faceMin.getY() + 1 / 16d, faceMin.getZ(), faceMax.getX(), - faceMax.getY() + 1 / 8d, faceMax.getZ(), .6f, .7f, 1, 1); - } - - GlStateManager.lineWidth(1); - GlStateManager.enableTexture(); + public void renderToolLocal() { + if (!schematicHandler.isDeployed()) + return; + AABBOutline outline = schematicHandler.getOutline(); + if (renderSelectedFace) { + schematicHandler.getOutline().setTextures(null, + AllKeys.ctrlDown() ? AllSpecialTextures.HIGHLIGHT_CHECKERED : AllSpecialTextures.CHECKERED); + outline.highlightFace(selectedFace); } + RenderHelper.disableStandardItemLighting(); + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + outline.render(Tessellator.getInstance().getBuffer()); + GlStateManager.popMatrix(); + outline.setTextures(null, null); + } @Override - public void renderOverlay() { + public void renderTool() {} - } + @Override + public void renderOverlay() {} } diff --git a/src/main/java/com/simibubi/create/modules/schematics/item/SchematicItem.java b/src/main/java/com/simibubi/create/modules/schematics/item/SchematicItem.java index fe23c977e..c53bc74fa 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/item/SchematicItem.java +++ b/src/main/java/com/simibubi/create/modules/schematics/item/SchematicItem.java @@ -75,22 +75,20 @@ public class SchematicItem extends Item { public static void writeSize(ItemStack blueprint) { CompoundNBT tag = blueprint.getTag(); - Template t = getSchematic(blueprint); + Template t = loadSchematic(blueprint); tag.put("Bounds", NBTUtil.writeBlockPos(t.getSize())); blueprint.setTag(tag); } public static PlacementSettings getSettings(ItemStack blueprint) { CompoundNBT tag = blueprint.getTag(); - PlacementSettings settings = new PlacementSettings(); settings.setRotation(Rotation.valueOf(tag.getString("Rotation"))); settings.setMirror(Mirror.valueOf(tag.getString("Mirror"))); - return settings; } - public static Template getSchematic(ItemStack blueprint) { + public static Template loadSchematic(ItemStack blueprint) { Template t = new Template(); String owner = blueprint.getTag().getString("Owner"); String schematic = blueprint.getTag().getString("File"); @@ -120,14 +118,25 @@ public class SchematicItem extends Item { @Override public ActionResultType onItemUse(ItemUseContext context) { - if (context.isPlacerSneaking() && context.getHand() == Hand.MAIN_HAND) { - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { - displayBlueprintScreen(); - }); - return ActionResultType.SUCCESS; - } + if (!onItemUse(context.getPlayer(), context.getHand())) + return super.onItemUse(context); + return ActionResultType.SUCCESS; + } - return super.onItemUse(context); + @Override + 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)); + } + + private boolean onItemUse(PlayerEntity player, Hand hand) { + if (!player.isSneaking() || hand != Hand.MAIN_HAND) + return false; + if (!player.getHeldItem(hand).hasTag()) + return false; + DistExecutor.runWhenOn(Dist.CLIENT, () -> this::displayBlueprintScreen); + return true; } @OnlyIn(value = Dist.CLIENT) @@ -135,17 +144,4 @@ public class SchematicItem extends Item { ScreenOpener.open(new SchematicEditScreen()); } - @Override - public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { - if (playerIn.isSneaking() && handIn == Hand.MAIN_HAND) { - if (playerIn.getHeldItem(handIn).hasTag()) - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { - displayBlueprintScreen(); - }); - return new ActionResult(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn)); - } - - return super.onItemRightClick(worldIn, playerIn, handIn); - } - } diff --git a/src/main/java/com/simibubi/create/modules/schematics/packet/SchematicPlacePacket.java b/src/main/java/com/simibubi/create/modules/schematics/packet/SchematicPlacePacket.java index c58b5212d..82db762ef 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/packet/SchematicPlacePacket.java +++ b/src/main/java/com/simibubi/create/modules/schematics/packet/SchematicPlacePacket.java @@ -31,7 +31,7 @@ public class SchematicPlacePacket extends SimplePacketBase { public void handle(Supplier context) { context.get().enqueueWork(() -> { ServerPlayerEntity player = context.get().getSender(); - Template t = SchematicItem.getSchematic(stack); + Template t = SchematicItem.loadSchematic(stack); t.addBlocksToWorld(player.getServerWorld(), NBTUtil.readBlockPos(stack.getTag().getCompound("Anchor")), SchematicItem.getSettings(stack)); }); diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 3336eb56a..b8b7668f5 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -881,8 +881,8 @@ "block.create.mechanical_press.tooltip.behaviour1": "_Starts_ to compress items dropped below it.", "block.create.mechanical_press.tooltip.condition2": "When Above a Mechanical Belt", "block.create.mechanical_press.tooltip.behaviour2": "_Automatically_ compresses bypassing items on the Belt.", - "block.create.mechanical_mixer.tooltip.condition3": "When above Basin", - "block.create.mechanical_mixer.tooltip.behaviour3": "Starts to _compact_ _items_ in the basin whenever all necessary ingredients are present.", + "block.create.mechanical_press.tooltip.condition3": "When above Basin", + "block.create.mechanical_press.tooltip.behaviour3": "Starts to _compact_ _items_ in the basin whenever all necessary ingredients are present.", "block.create.basin.tooltip": "BASIN", "block.create.basin.tooltip.summary": "A handy _item_ _container_ used in processing with the _Mechanical_ _Mixer_ and the _Mechanical_ _Press_. Supports _Redstone_ _Comparators_.", diff --git a/src/main/resources/assets/create/textures/gui/background.png b/src/main/resources/assets/create/textures/gui/background.png index de5cde99c1d332042bf2e8cd04f2526ee8a06e32..e51ac31894d4afc471b974dfd8ceae2457361b8e 100644 GIT binary patch delta 98 zcmdnYIE`_F3KwH>kh>GZx^prwCn`$&?q*=%+s%0V#}zXM1_o_U7sn6_|70HRo41i@#Yc;mI6kIgTe~DWM4fTtXnV delta 129 zcmbQnxS4T+%0xqn@;wX;e0vzD?kVzQU|^6aag8Vm&QB{TPb^AhC`ioAE78kKEm1Jh zGt@KgRr#9^RAcDr;uvD#pUiPO{=LX8Kbw;c?tI#w^3o4DG+5ks9ARI{)?qU7NrsJr h_X8pIK<5l=2B{gI0ifaT516C3fsR)XSAbWs-3RH-sniN?jXb>I1pcohy z1Gs@8OAN@O35#W`(10VdX@cy;u*3*q$uijKkG9k4%>17p@4WZD``vr)`QE+fzH7&i z*{dV;5C8!6LkZ^=}!ieD_~Xd{-gT=VA0iN0k9Rk z<~s*3G5{L2pB6-`&gvxqYIcVX?01dun|j+pa_w2)BDNS_&(kHsHy2hUT(wd!!TGw5 zIu&LiULAJ3k&$1#>+ZqEr$tvQOE$44ijuY#Z`$H)x9Vt-ySvVf%?Iv>H#j;tLNaZ4 zlNv}ChP-MXdEBoKPT$D1VXjwlbA=;0!)iSzM3SdG%<%f)={GfO-7LzysBdFQ`oDC@4bD9OSzH0neC2pL6d37Tn}2^ z87wr0Hn+AqluKwAunWeD)@Iq*?F)?x`Es^K+Bb~v3i{z{YLF&4n|kXbx0UT) zTSl}|MRet!Gux|SnFPLNn?3k(V|HZ|=gw5WS2EpdACm^}{0y3>{wzkoDK=v!%#I|z zBqz!2TH-BNq6{TP@TSj-chc;g#+dk#_lChpu+13s*T0Z5iB=HZ;y!c{Ke8Al zUFVF|W42UYD|>e@R$lxfNv0V2Sad4oI$M=$*;}>NDm!Dw3*WS3fLk_om40Pbpj_NU zQ0_@x4b3}hI*nl`aAFwJ`F`tkoyDYIe6+0aE?hxPXcGFA$AZ>WJ=fz7cG!<%@U1qa zGpNdxd4)*~a*LK%`ii@nTl!RRdLx9-D!kk|x)W)5Y+q)kjdHQ1MQm>yFF|k9L zhxU#R6l&?76oK0e_{$4p^pHv+m7Z20xp|b6aXYa|h$g{b_MKL#FI(UarX|dfkx-A~ z?mMu$$I#h}0Rj6>fpp_&^CG8CD5x2&67~L(->pb3pXed{V7pm3Ucw-v z7wMY&WQrRTyq#hW*36qcpOU%5TY`+x8qEEvsMq^z8VtX{2!UIDM&1|`wVUQ!S4T_> z zv6C$DL2OeF$~=^>BgrpIr8jqnpxXO{+cS!s3ENS5#Q`CkXju8I!@{^gI6ldO z4UjHW50uQ!lm{vgzlJtwpUs8ECtQ_}mhU;CVR2$(`;kQRxe7j^%623=j%(07^NKed z?j1&CkCA8=of+x_(aW}R`ML>RqL^(*7$S7~7WQkV7jt1@>AB`X?Y%odUV%Q;zuO7A z2xX>(i!%J8!#pywe9v**rVP2>C3H?nlZx?skF)rSugjn^l`gFxvtZY5*H14_ z4Uv+%5myTdj%Ap=aYK35!Q-qGBOP#qb);+*Zwv4MX7?X5)oMpHTIgtJZZgY zWHSfzWPgdTnTRzp6Y77NQzm_eiXnUmN1RfM*KKs3`$Y>1Lvs$Z`3)UX?kYu=ZF z?G&9{d+^DEe0T2@EjZO0TOtL1eq+HpjYB@N=Ru1xrX$3rQAuAE+p%0)>hiFU(Vr!K ztu4BVf4H-(nvijwcCDIX);nYt#tw3;b9-$Sp1P!&YN`*y z#CPlb=&N@S!VyHbIN5X3UB%y7NRDHy*k&F8iX{|i9t5Bf4sg0FbI$~TfK|Xa835Yn zfNK74jg=UnAct-WSu@s8Chpn}aGnGFwL1^VNrt^TbM2W=PxC{bZT8%t1&kj}kq}w) zjLVT1c-CrKxKCHf7%=86I3sbt3oX101vHjwJz8iJ$n`1&!ormVL=bcO(y{C+yv9Y zZTA#&P?v7?(4-a0uLOA%Y7L3c=q^<0p$&&8nS-K zzI5`13D6rpgZo*S;f%{rR3i#dum5ZLJbFhyGZlfjTrgkGn6)(iBg!9C*bE{WMZW+G z+i9^fv5+1%ksnT@`_U#QCSte)ue0+wy5Gll1E_c34=kGv|BD*^(*pjTu}*gt-mp&h z9&29q0zely0PNNKAKKw}(f;rGo96k0xBd?bwIbdreV1X&O-4^}E5B@T$nMyIQd|E^ F{{RP?^eX@W literal 2795 zcmeHJdpH!@7T+@llR>hx zsj29x007hu?BC-F07Slp0JxGIPMmub{6&iP+~*9QbQ?^|1z5jC~ed-Zt@?o!qZ@q@t z819^zai%NcNOQ+YtJ)vj%JX)-$!zfLb#tr9oO_#bA7*hAT~eSU4ZPNO)78zZ%=*x_ zy!N2aVuuiSo0cM*=A!Ene?5Z~Rt*~}qMSfKCug1CInmLwzM-#ImP z-!SpMP$gT&-KJ2?KRqlzKRa0MwB#;6H`#f+{F6JTWayBzL*n}2El$d5anxHB#B1LN zB8J;30>Ne=hG9`2Fq>H9MY*lL0y;p0Y&0FqG>)b~PzV?n9;ZaEM}ggM1@{k6%8#|-bPb^@ zh~EV+7jgDdJL8qermsj=Z<1KDR3oS7lDqhorhWlWs>BuYIQHU9Bq?@A=bnYqYwCKU zl}A{3_~RLbty!JBR`Rpp;Nbg;_l~g@xR~Cm{=H3!vRVt`vY&vm`ZpQ(MXm$vT5_O$j1I!((YXL1i4WyNSP}T zH7e*Lk(|LbSF^KSoF+5boLQPY#-hd}K2W-7h?Z%+*XEA5=lNskVg5}?4yI;idwD~G z)xyF+Fg}7K7 z=MHv>pZ;v<30h$o&yBQZR9a5Skp0b1!lIHMzBoy;G*PpYC^RC3)X0$#Kx4z$O+F!-ui^z-G!0;EdF2*UXvA?daN$&lyT!xyA&s) z0V7BD!@279a59Afl#e-{8nF#(OFWmyW0dKrgK>eadR5O&Txh3bHg=qw4E%NhRWtiZ3(s};Rjen%~NC(oD3;2S;notvY zQP%Deco2N{^Pz+uJYH7g6QQ7)Wmm!~T?k35&hT$DKT4fMh4U6=zYX}qc5=5bGmm4N(hNw@TQ>_oDrZto$jA)a_at&){Xd@SNtD}+r9W~Rq z(vJhr#IlD}{1C)Gi5DCvvUe;WIy@r8vDE2vu8hz=7eq4dxHVtBc}_a3mo%`$SNkH2 z26Stj?G>J0S~`RZK-}JX5M&6QFaCbW-Q8tOBB@^s!=62Br3X=rj*ezNG9ZhTkmRB= zLv*DfwD%PU+FVSwW`XB(X{37n{9&p1k5HI;C1&+Q2vfvlh#i9(MTR{9jO#%_iY7qo z{wYv%0IMS2zozzE_ES!gDilD9+N@vlroPp;I-IL6lb!zCkk*Zxe6AV-)R`%cmi0`m z`eX}5phEyw1VFZ=KrC}w>${Y*4AEaqu7-flLMw{}DMKCAstz<-w}VOME!uKHg~F9D zu|KMkxj?xZJ1!F3TJCt1kcyI6!p@66Z;UP}P9R9!Q2z6{UjK4A_!e z-QM0FdXGw7x(H0o&0RJWU?U^V^=>H8w*&ORJ9QLG9TGl{hrIVf-wBr2c73ep*3&Yv zV$fqaE;B@)CltUpd;=5yZZtPWZRX-xBS%Ek;?xmj3CMV~IK?bvPtU>WbM{~)VQKEu zL-bh#rzCqHAQODp4C;nd=wod;2}tNXJ}}VeM19;fP-OikjqK*;#=M4o;;>I9JTA`! z9SOPq0lD+sM!nnHW83W!!_c5hUn*Cy7E+bO!v^rM7LJGRU{U2GF^#Y z9tLqRY%EbvL&HUWxn!b%PL4tVRKJ{ntKWF|4rls%9;l6Z=@P@&DzBj`!E$jh@YUyk z0nr<45J&Xpj@*zxQ5T9W?%uicA%B+2VzJmi<>pUMPqSIFt>*#xQZnFY|2I9~S^BFm zW})=*VjD)avTjuJ8bCz}kiXa$f4Y(W@9=&21f>esL}=}}p0VQTB>$j-1AE=~JaNV* F{~P@hm8t*$ diff --git a/src/main/resources/assets/create/textures/item/blueprint_and_quill.png b/src/main/resources/assets/create/textures/item/blueprint_and_quill.png index dd13e81665dc9b5c48a9b8ff019af80018acebc2..dc2f06e0aa921e8de1a74b040418bd1b4d12dfd0 100644 GIT binary patch delta 469 zcmV;`0V@9R0)_;TBnkm@Qb$4nuFf3kks%v@!2kdb!2!6DYwZ940h>ugK~y+Tt&+b> zLQxdQ&#T0KiqKQBpdosb@Ia%bh8l%81RB)TmN+=sZs8x`EH#8%Z8j9{(V~n-w*y^zDeZ*K+IdcZifx>D*<9`|5HStg`LBJOwT>O00000 LNkvXXu0mjfs4&qz delta 320 zcmV-G0l)r+1n>foB#|)~f5HF&4#EKyC`y0;000U#9G-OMM0yGD2lXzpKZke@L-bLtLYVpwGxJ52S|4fvkU^}N)n?!VNZKoO^_|3K zVQmZ+n|Q!Xm^LYjHlpYtqs1mmg0n1>jlWPpdp%7+?8lYA6s#BjXcow?JnsW=9dXyn SOcV_O0000>SJtJX|bb4AKaqFJAqCp&2Uxxn%x^7yl1m`uhLY z(?4LkYWl7J+Aa(k@Hobo=)eGG2uveMnqdHB2(re(3K$pwK_aM;1rRq+00000NkvXX Hu0mjf6rqDJ delta 252 zcmV5cPbuUQH8!tdw5Md`BK?{*E*N0000CVzZmPG1TL9!SA!ZXrP3_&pfHjgsmlrW!sIpmV9g*y3$tq(Oss7g82>ObuuH2laQ_u;0J{LDSw)GL;oYnI zU;{y#K>+3=Sa{sI_nDz5pn+jyW*@_CjvaM~SOGa{{)QL-L1B7)0PlME8Jqnva_^6#F%9n5T!v%0-vA(0W~=R4YHhzgsXe|foSS_k>Cr1aF) zdT&5xVQz=J)j`^>Kb0^B0$_WzItTzvkktVI#6<|9#q#U`%IPNfFGNEI05EIw@7Dl$ zm&+r%9l&XPFc1WQ-UE}tWKP%UbL;?=Lge&1DggT`rXt7&0O1b7qOm31j= qiy@Ymu7fG@J&fu#8tTMp3gH7eBbhkYw>dlj0000YbIfu vU?9QZ#m*aGruRX_E17k1qXiF7LIMMW@=o@DN!7nW_A_|8`njxgN@xNA0Rt#Z literal 0 HcmV?d00001 From d2c1122786aabf44028e37309d83ce8b2bf3501f Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Mon, 27 Apr 2020 14:09:47 +0200 Subject: [PATCH 05/11] Create in korean - added ko_kr localization by qkrehf2 --- .../resources/assets/create/lang/ko_kr.json | 1165 +++++++++++++++++ 1 file changed, 1165 insertions(+) create mode 100644 src/main/resources/assets/create/lang/ko_kr.json diff --git a/src/main/resources/assets/create/lang/ko_kr.json b/src/main/resources/assets/create/lang/ko_kr.json new file mode 100644 index 000000000..cf3f094b0 --- /dev/null +++ b/src/main/resources/assets/create/lang/ko_kr.json @@ -0,0 +1,1165 @@ + +// Korean translated by qkrehf2. +// If you noticed any problems with translation, please email to qkrehf2ggwp@gmail.com +// Please email me when you want to modify translations. :D + +// 이 번역은 qkrehf2가 번역했습니다. +// 번역에 문제가 있다면, qkrehf2ggwp@gmail.com으로 메일 보내주세요. +// 이 번역본을 수정하거나 다른 용도로 쓰고 싶다면, 역시 저에게 메일 주세요. 감사합니다. + + { + + "_comment": "-------------------------] GAME ELEMENTS [------------------------------------------------", + + "item.create.symmetry_wand": "대칭의 지팡이", + "item.create.placement_handgun": "휴대용 블럭발사기", + "item.create.terrain_zapper": "휴대용 세계편집기", + "item.create.tree_fertilizer": "나무 비료", + "item.create.empty_blueprint": "빈 청사진", + "item.create.andesite_alloy": "안산암 합금", + "item.create.chromatic_compound": "색채 혼합물", + "item.create.shadow_steel": "그림자 강철", + "item.create.blueprint_and_quill": "청사진과 깃펜", + "item.create.blueprint": "청사진", + "item.create.belt_connector": "기계식 벨트", + "item.create.goggles": "엔지니어의 고글", + "item.create.filter": "필터 틀", + "item.create.property_filter": "속성 필터 틀", + "item.create.rose_quartz": "장밋빛 석영", + "item.create.polished_rose_quartz": "윤나는 장밋빛 석영", + "item.create.refined_radiance": "정제된 광채", + "item.create.iron_sheet": "철 판", + "item.create.gold_sheet": "금 판", + "item.create.lapis_plate": "청금석 판", + "item.create.obsidian_dust": "흑요석 가루", + "item.create.propeller": "프로펠러", + "item.create.whisk": "혼합기", + "item.create.brass_hand": "황동 손", + "item.create.slot_cover": "작업대 슬롯 덮개", + "item.create.zinc_handle": "아연 도구 손잡이", + "item.create.flour": "밀가루", + "item.create.dough": "반죽", + "item.create.wrench": "렌치", + "item.create.deforester": "산림파괴자", + "item.create.crushed_iron": "분쇄된 철", + "item.create.crushed_gold": "분쇄된 금", + "item.create.sand_paper": "사포", + "item.create.red_sand_paper": "붉은 사포", + + "item.create.brass_ingot": "황동 주괴", + "item.create.brass_sheet": "황동 판", + "item.create.brass_nugget": "황동 조각", + "item.create.crushed_brass": "분쇄된 황동", + "item.create.zinc_ingot": "아연 주괴", + "item.create.zinc_nugget": "아연 조각", + "item.create.crushed_zinc": "분쇄된 아연", + "item.create.copper_sheet": "구리 판", + "item.create.copper_ingot": "구리 주괴", + "item.create.copper_nugget": "구리 조각", + "item.create.crushed_copper": "분쇄된 구리", + + "item.create.electron_tube": "전지 튜브", + "item.create.integrated_circuit": "집적 회로", + + "item.create.blazing_pickaxe": "타오르는 곡괭이", + "item.create.blazing_shovel": "타오르는 삽", + "item.create.blazing_axe": "타오르는 도끼", + "item.create.blazing_sword": "타오르는 대검", + + "item.create.shadow_steel_pickaxe": "그림자 강철 곡괭이", + "item.create.shadow_steel_mattock": "그림자 강철 야전삽", + "item.create.shadow_steel_sword": "그림자 강철 검", + + "item.create.rose_quartz_pickaxe": "화려한 석영 곡괭이", + "item.create.rose_quartz_shovel": "화려한 석영 삽", + "item.create.rose_quartz_axe": "화려한 석영 도끼", + "item.create.rose_quartz_sword": "화려한 석영 검", + + "block.create.copper_ore": "구리 광석", + "block.create.copper_block": "구리 블럭", + "block.create.copper_shingles": "구리 판자", + "block.create.zinc_ore": "아연 광석", + "block.create.zinc_block": "아연 블럭", + "block.create.brass_block": "황동 블럭", + + "block.create.andesite_casing": "안산암 케이스", + "block.create.brass_casing": "황동 케이스", + "block.create.copper_casing": "구리 케이스", + + "block.create.cogwheel": "톱나버퀴", + "block.create.large_cogwheel": "큰 톱니바퀴", + "block.create.turntable": "돌림판", + "block.create.gearbox": "기어박스", + "block.create.gearshift": "기어쉬프트", + "block.create.clutch": "클러치", + "block.create.shaft": "축", + "block.create.encased_belt": "덮힌 벨트", + "block.create.encased_shaft": "덮힌 축", + "block.create.encased_fan": "덮힌 환풍기", + "block.create.adjustable_pulley": "덮힌 벨트 변속기", + "block.create.nozzle": "노즐", + "block.create.hand_crank": "핸드 크랭크", + "block.create.cuckoo_clock": "뻐꾸기 시계", + "block.create.creative_motor": "모터", + "block.create.belt": "컨베이어 벨트", + "block.create.millstone": "맷돌", + "block.create.crushing_wheel": "분쇄 휠", + "block.create.drill": "드릴", + "block.create.portable_storage_interface": "이동식 저장소 인터페이스", + "block.create.harvester": "수확기", + "block.create.saw": "톱", + "block.create.water_wheel": "물레방아", + "block.create.mechanical_press": "압착기", + "block.create.mechanical_mixer": "믹서", + "block.create.deployer": "배포기", + "block.create.basin": "대야", + "block.create.mechanical_crafter": "기계식 조합기", + "block.create.flywheel": "플라이휠", + "block.create.furnace_engine": "화로 엔진", + "block.create.speed_gauge": "속도 계측기", + "block.create.stress_gauge": "피로도 계측기", + "block.create.cart_assembler": "카트 조립기", + "block.create.analog_lever": "아날로그 레버", + "block.create.rotation_speed_controller": "회전 속도 컨트롤러", + + "block.create.sticky_mechanical_piston": "끈끈이 기계식 피스톤", + "block.create.mechanical_piston": "기계식 피스톤", + "block.create.mechanical_piston_head": "기계식 피스톤 머리", + "block.create.piston_pole": "피스톤 연장 축", + "block.create.mechanical_bearing": "베어링", + "block.create.clockwork_bearing": "시계 베어링", + "block.create.rope_pulley": "밧줄 도르래", + "block.create.rope": "밧줄", + "block.create.pulley_magnet": "도르래 자석", + "block.create.translation_chassis": "직선 섀시", + "block.create.rotation_chassis": "원형 섀시", + + "block.create.contact": "동형 감지기", + "block.create.redstone_bridge": "레드스톤 링크", + "block.create.stockswitch": "수량 스위치", + "block.create.flexcrate": "가변 창고", + "block.create.extractor": "추출기", + "block.create.belt_funnel": "깔대기", + "block.create.linked_extractor": "무선 추출기", + "block.create.transposer": "트랜스포저", + "block.create.linked_transposer": "무선 트랜스포저", + "block.create.pulse_repeater": "펄스 리피터", + "block.create.flexpulsepeater": "가변 펄스 리피터", + "block.create.redstone_latch": "레드스톤 걸쇠", + "block.create.toggle_latch": "레드스톤 토글 걸쇠", + "block.create.flexpeater": "가변 리피터", + "block.create.entity_detector": "벨트 감지기", + "block.create.belt_tunnel": "컨베이어 벨트 터널", + "block.create.sequenced_gearshift": "순서 기어쉬프트", + + "block.create.tiled_glass": "타일 유리", + "block.create.framed_glass": "큰 유리", + "block.create.vertical_framed_glass": "수직 유리", + "block.create.horizontal_framed_glass": "수평 유리", + "block.create.oak_glass": "참나무 유리창", + "block.create.spruce_glass": "가문비나무 유리창", + "block.create.birch_glass": "자작나무 유리창", + "block.create.jungle_glass": "정글나무 유리창", + "block.create.dark_oak_glass": "짙은 참나무 유리창", + "block.create.acacia_glass": "아카시아 유리창", + "block.create.iron_glass": "화려한 금속창", + + "block.create.tiled_glass_pane": "타일 유리판", + "block.create.framed_glass_pane": "큰 유리판", + "block.create.vertical_framed_glass_pane": "수직 유리판", + "block.create.horizontal_framed_glass_pane": "수평 유리판", + "block.create.oak_glass_pane": "참나무 유리판", + "block.create.spruce_glass_pane": "가문비나무 유리판", + "block.create.birch_glass_pane": "자작나무 유리판", + "block.create.jungle_glass_pane": "정글나무 유리판", + "block.create.dark_oak_glass_pane": "짙은 참나무 유리판", + "block.create.acacia_glass_pane": "아카시아나무 유리판 ", + "block.create.iron_glass_pane": "화려한 금속 유리판", + + "block.create.window_in_a_block": "유리판이 낀 블럭", + "block.create.andesite_bricks": "안산안 벽돌", + "block.create.andesite_layers": "층이있는 안산암", + "block.create.diorite_bricks": "섬록암 벽돌", + "block.create.diorite_layers": "층이 있는 섬록암", + "block.create.granite_bricks": "화강암 벽돌", + "block.create.granite_layers": "층이 있는 화강암", + + "block.create.gabbro": "반려암", + "block.create.gabbro_stairs": "반려암 계단", + "block.create.gabbro_slab": "반려암 반 블록", + "block.create.gabbro_wall": "반려암 담장", + "block.create.polished_gabbro": "윤나는 반려암", + "block.create.gabbro_bricks": "반려암 벽돌", + "block.create.gabbro_bricks_stairs": "반려암 벽돌 계단", + "block.create.gabbro_bricks_wall": "반려암 벽돌 담장", + "block.create.paved_gabbro_bricks": "포장된 반려암 벽돌", + "block.create.paved_gabbro_bricks_slab": "포장된 반려암 벽돌 반 블록", + "block.create.indented_gabbro": "반려암 겹 타일", + "block.create.indented_gabbro_slab": "반려암 겹 반 블록", + "block.create.slightly_mossy_gabbro_bricks": "이끼 낀 반려암 벽돌", + "block.create.mossy_gabbro_bricks": "이끼로 뒤덮힌 반려암 벽돌", + "block.create.gabbro_layers": "층이 있는 반려암", + + "block.create.weathered_limestone": "풍화된 석회암", + "block.create.weathered_limestone_stairs": "풍화된 석회암 계단", + "block.create.weathered_limestone_wall": "풍화된 석회암 담장", + "block.create.weathered_limestone_slab": "풍화된 석회암 반 블록", + "block.create.polished_weathered_limestone": "윤나는 풍화된 석회암", + "block.create.polished_weathered_limestone_slab": "윤나는 풍화된 석회암 반 블록", + "block.create.weathered_limestone_bricks": "풍화된 석회암 벽돌", + "block.create.weathered_limestone_bricks_stairs": "풍화된 석회암 벽돌 계단", + "block.create.weathered_limestone_bricks_wall": "풍화된 석회암 벽돌 담장", + "block.create.weathered_limestone_bricks_slab": "풍화된 석회암 벽돌 반 블록", + "block.create.weathered_limestone_pillar": "풍화된 석회암 기둥", + "block.create.weathered_limestone_layers": "층이 있는 석회암", + + "block.create.dolomite_pillar": "백운암 기둥", + "block.create.dolomite": "백운암", + "block.create.dolomite_stairs": "백운암 계단", + "block.create.dolomite_wall": "백운암 담장", + "block.create.dolomite_slab": "백운암 반 블록", + "block.create.dolomite_bricks": "백운암 벽돌", + "block.create.dolomite_bricks_wall": "백운암 벽돌 담장", + "block.create.dolomite_bricks_stairs": "백운암 벽돌 계단", + "block.create.dolomite_bricks_slab": "백운암 벽돌 반 블록", + "block.create.polished_dolomite": "윤나는 백운암", + "block.create.dolomite_layers": "층이 있는 백운암", + + "block.create.limesand": "석회모래", + "block.create.limestone": "석회암", + "block.create.limestone_stairs": "석회암 계단", + "block.create.limestone_slab": "석회암 반 블록", + "block.create.limestone_wall": "석회암 담장", + "block.create.limestone_bricks": "석회암 벽돌", + "block.create.limestone_bricks_stairs": "석회암 벽돌 계단", + "block.create.limestone_bricks_slab": "석회암 벽돌 반 블록", + "block.create.limestone_bricks_wall": "석회암 벽돌 담장", + "block.create.polished_limestone": "윤나는 석회암", + "block.create.polished_limestone_slab": "윤나는 석회암 반 블록", + "block.create.limestone_pillar": "석회암 기둥", + "block.create.limestone_layers": "층이 있는 석회암", + + "block.create.natural_scoria": "자연 스코리아", + "block.create.scoria": "스코리아", + "block.create.scoria_stairs": "스코리아 계단", + "block.create.scoria_slab": "스코리아 반 블록", + "block.create.scoria_wall": "스코리아 담장", + "block.create.scoria_bricks": "스코리아 벽돌", + "block.create.polished_scoria": "윤나는 스코리아", + "block.create.polished_scoria_slab": "윤나는 스코리아 반 블록", + "block.create.scoria_pillar": "스코리아 기둥", + "block.create.scoria_layers": "층이 있는 스코리아", + + "block.create.dark_scoria": "짙은 스코리아", + "block.create.polished_dark_scoria": "윤나는 짙은 스코리아", + "block.create.dark_scoria_tiles": "짙은 스코리아 타일", + "block.create.dark_scoria_tiles_stairs": "짙은 스코리아 타일 계단", + "block.create.dark_scoria_tiles_slab": "짙은 스코리아 타일 반 블록", + "block.create.dark_scoria_bricks": "짙은 스코리아 벽돌", + "block.create.dark_scoria_bricks_stairs": "짙은 스코리아 벽돌 계단", + "block.create.dark_scoria_bricks_slab": "짙은 스코리아 벽돌 반 블록", + "block.create.dark_scoria_bricks_wall": "짙은 스코리아 벽돌 담장", + + "block.create.schematicannon": "청사진 대포", + "block.create.schematic_table": "청사진 테이블", + "block.create.creative_crate": "청사진 대포 지원기", + + "block.create.cocoa_log": "코코아 정글 나무 원목", + + "_comment": "-------------------------] UI & MESSAGES [------------------------------------------------", + + "death.attack.create.crush": "%1$s이(가) 분쇄 휠에 의해 가공되었습니다", + "death.attack.create.fan_fire": "%1$s이(가) 뜨거운 바람으로 타버렸습니다", + "death.attack.create.fan_lava": "%1$s이(가) 용암 바람으로 타버렸습니다", + "death.attack.create.drill": "%1$s이(가) 드릴에 관통당했습니다", + "death.attack.create.saw": "%1$s이(가) 톱날에 반으로 갈라져 죽었습니다", + "create.block.deployer.damage_source_name": "순수한 배포기", + "death.attack.create.curse_polish": "%1$s이(가) 저주받은 아이템을 닦다가 죽었습니다", + "death.attack.create.cuckoo_clock_explosion": "%1$s이(가) 조작된 뻐꾸기 시계에 의해 폭파당했습니다", + + "create.recipe.crushing": "분쇄", + "create.recipe.milling": "맷돌질", + "create.recipe.splashing": "세척", + "create.recipe.splashing.fan": "물과 환풍기", + "create.recipe.smokingViaFan": "훈연", + "create.recipe.smokingViaFan.fan": "불과 환풍기", + "create.recipe.blastingViaFan": "제련", + "create.recipe.blastingViaFan.fan": "용암과 환풍기", + "create.recipe.pressing": "압착", + "create.recipe.mixing": "혼합", + "create.recipe.packing": "압축", + "create.recipe.sawing": "제재", + "create.recipe.mechanical_crafting": "기계 조합", + "create.recipe.block_cutting": "블럭 절단", + "create.recipe.blockzapperUpgrade": "휴대용 블럭발사기 업그레이드", + "create.recipe.sandpaper_polishing": "사포 연마", + "create.recipe.mystery_conversion": "?", + "create.recipe.processing.catalyst": "촉매", + "create.recipe.processing.chance": "%1$s%% 확률", + "create.recipe.processing.chanceToReturn": "%1$s%% 확률로 반환", + + "create.generic.range": "범위", + "create.generic.radius": "반지름", + "create.generic.width": "폭", + "create.generic.height": "높이", + "create.generic.length": "길이", + "create.generic.speed": "속도", + "create.generic.delay": "딜레이", + "create.generic.unit.ticks": "틱", + "create.generic.unit.seconds": "초", + "create.generic.unit.minutes": "분", + "create.generic.unit.rpm": "RPM", + "create.generic.unit.stress": "su", + "create.generic.unit.degrees": "°", + + "create.action.scroll": "스크롤하세요", + "create.action.confirm": "확인", + "create.action.abort": "중단", + "create.action.saveToFile": "저장", + "create.action.discard": "삭제", + + "create.keyinfo.toolmenu": "메뉴 세부정보 보기", + "create.keyinfo.scrollup": "Simulate Mousewheel Up (inworld)", + "create.keyinfo.scrolldown": "Simulate Mousewheel Down (inworld)", + + "create.gui.scrollInput.defaultTitle": "옵션을 선택하세요:", + "create.gui.scrollInput.scrollToModify": "스크롤로 수정하기", + "create.gui.scrollInput.scrollToAdjustAmount": "스크롤로 수량 조절하기", + "create.gui.scrollInput.scrollToSelect": "스크롤로 선택", + "create.gui.scrollInput.shiftScrollsFaster": "쉬프트-스크롤로 빨리 수정하기", + + "create.gui.toolmenu.focusKey": "[%1$s]를 눌러 세부정보 보기", + "create.gui.toolmenu.cycle": "스크롤로 순환", + + "create.gui.symmetryWand.mirrorType": "반사", + "create.gui.symmetryWand.orientation": "방위", + "create.symmetry.mirror.plane": "거울 모드", + "create.symmetry.mirror.doublePlane": "사각형 모드", + "create.symmetry.mirror.triplePlane": "팔각형 모드", + "create.orientation.orthogonal": "수직으로", + "create.orientation.diagonal": "대각선으로", + "create.orientation.horizontal": "수평으로", + "create.orientation.alongZ": "Z좌표를 따라", + "create.orientation.alongX": "X좌표를 따라", + + "create.gui.blockzapper.title": "휴대용 블럭발사기", + "create.gui.blockzapper.replaceMode": "대체 모드", + "create.gui.blockzapper.searchDiagonal": "대각선을 따라", + "create.gui.blockzapper.searchFuzzy": "물질 경계 무시", + "create.gui.blockzapper.range": "범위", + "create.gui.blockzapper.needsUpgradedAmplifier": "업그레이드가 필요합니다", + "create.gui.blockzapper.patternSection": "패턴 설정", + "create.gui.blockzapper.pattern.solid": "원형", + "create.gui.blockzapper.pattern.checkered": "체스판", + "create.gui.blockzapper.pattern.inversecheckered": "반전된 체스판", + "create.gui.blockzapper.pattern.chance25": "램덤으로 25% 채우기", + "create.gui.blockzapper.pattern.chance50": "램덤으로 50% 채우기", + "create.gui.blockzapper.pattern.chance75": "랜덤으로 75% 채우기", + + "create.gui.terrainzapper.title": "휴대용 세계편집기", + "create.gui.terrainzapper.placement": "설치방식", + "create.gui.terrainzapper.placement.merged": "선택한 블럭에", + "create.gui.terrainzapper.placement.attached": "선택한 블럭 옆에", + "create.gui.terrainzapper.placement.inserted": "선택한 블럭 안에", + "create.gui.terrainzapper.brush": "브러쉬", + "create.gui.terrainzapper.brush.cuboid": "정육면체", + "create.gui.terrainzapper.brush.sphere": "구", + "create.gui.terrainzapper.brush.cylinder": "원통", + "create.gui.terrainzapper.tool": "도구", + "create.gui.terrainzapper.tool.fill": "채우기", + "create.gui.terrainzapper.tool.place": "설치", + "create.gui.terrainzapper.tool.replace": "대체", + "create.gui.terrainzapper.tool.clear": "지우기", + "create.gui.terrainzapper.tool.overlay": "덮어씌우기", + "create.gui.terrainzapper.tool.flatten": "평탄화", + "create.terrainzapper.shiftRightClickToSet": "쉬프트-우클릭으로 모양 설정하기", + + "create.blockzapper.usingBlock": "현재 블럭: %1$s", + "create.blockzapper.componentUpgrades": "부품 업그레이드:", + "create.blockzapper.component.body": "몸통", + "create.blockzapper.component.amplifier": "증폭기", + "create.blockzapper.component.accelerator": "가속기", + "create.blockzapper.component.retriever": "회수기", + "create.blockzapper.component.scope": "스코프", + "create.blockzapper.componentTier.none": "없음", + "create.blockzapper.componentTier.brass": "황동", + "create.blockzapper.componentTier.chromatic": "혼돈의 결정체", + "create.blockzapper.leftClickToSet": "좌클릭으로 블럭 설정하기", + "create.blockzapper.empty": "블럭이 없습니다!", + + "create.contraptions.movement_mode": "이동 설정", + "create.contraptions.movement_mode.move_place": "멈췄을때 항상 블럭 설치하기", + "create.contraptions.movement_mode.move_place_returned": "멈췄을떄 최초 위치에서만 블럭 설치하기", + "create.contraptions.movement_mode.move_never_place": "멈춰도 블럭 설치하지 않기", + "create.contraptions.movement_mode.rotate_place": "멈췄을때 항상 블럭 설치하기", + "create.contraptions.movement_mode.rotate_place_returned": "멈췄을떄 최초 각도에서만 블럭 설치하기", + "create.contraptions.movement_mode.rotate_never_place": "멈춰도 블럭 설치하지 않기", + + "create.logistics.filter": "필터", + "create.logistics.firstFrequency": "주파수. #1", + "create.logistics.secondFrequency": "주파수. #2", + + "create.gui.goggles.generator_stats": "발전 상태:", + "create.gui.goggles.kinetic_stats": "가동 상태:", + "create.gui.goggles.at_current_speed": "현재 속도", + "create.gui.goggles.base_value": "기본 수치", + + "create.gui.gauge.info_header": "게이지 정보:", + "create.gui.speed_gauge.title": "회전 속도", + "create.gui.stress_gauge.title": "네트워크 부하", + "create.gui.stress_gauge.capacity": "용량", + "create.gui.stress_gauge.overstressed": "과부하됨", + "create.gui.stress_gauge.no_rotation": "회전없음", + + "create.gui.contraptions.not_fast_enough": "이 %1$s은(는) 작동하기에 _회전 속도_가 _부족합니다_", + "create.gui.contraptions.network_overstressed": "이 장치는 _과부하_되었습니다. _높은 피로도_ 용량을 가진 발전기를 추가로 설치하거나 장치 _속도_를 _늦추세요_.", + + "create.gui.flexcrate.title": "가변 창고 ", + "create.gui.flexcrate.storageSpace": "저장 공간", + + "create.gui.stockswitch.title": "수량 스위치", + "create.gui.stockswitch.lowerLimit": "최소 신호 유지수량", + "create.gui.stockswitch.upperLimit": "최초 신호 발동수량", + "create.gui.stockswitch.startAt": "다음 수량에 신호 주기", + "create.gui.stockswitch.startAbove": "다음 수량이상일떄 신호 주기", + "create.gui.stockswitch.stopAt": "다음 수량에 신호 멈추기", + "create.gui.stockswitch.stopBelow": "다음 수량이하일때 신호 멈추기", + + "create.gui.sequenced_gearshift.title": "순서 기어쉬프트", + "create.gui.sequenced_gearshift.instruction": "설명", + "create.gui.sequenced_gearshift.instruction.turn_angle": "회전", + "create.gui.sequenced_gearshift.instruction.turn_angle.angle": "각도", + "create.gui.sequenced_gearshift.instruction.turn_distance": "피스톤", + "create.gui.sequenced_gearshift.instruction.turn_distance.distance": "거리", + "create.gui.sequenced_gearshift.instruction.wait": "정지", + "create.gui.sequenced_gearshift.instruction.wait.duration": "지속시간", + "create.gui.sequenced_gearshift.instruction.end": "마침", + "create.gui.sequenced_gearshift.speed": "속도, 방향", + "create.gui.sequenced_gearshift.speed.forward": "입력된 속도, 그대로 회전", + "create.gui.sequenced_gearshift.speed.forward_fast": "입력된 속도의 2배, 그대로 회전", + "create.gui.sequenced_gearshift.speed.back": "입력된 속도, 반대로 회전", + "create.gui.sequenced_gearshift.speed.back_fast": "입력된 속도의 2배, 반대로 회전", + + "create.schematicAndQuill.dimensions": "청사진 크기: %1$sx%2$sx%3$s", + "create.schematicAndQuill.firstPos": "첫번쨰 위치 지정됨.", + "create.schematicAndQuill.secondPos": "두번째 위치 지정됨.", + "create.schematicAndQuill.noTarget": "[Ctrl]을 눌러 공기 블럭을 선택하기.", + "create.schematicAndQuill.abort": "위치 제거됨.", + "create.schematicAndQuill.prompt": "청사진의 제목을 작성하기:", + "create.schematicAndQuill.fallbackName": "내 청사진", + "create.schematicAndQuill.saved": "%1$s로 저장됨", + + "create.schematic.invalid": "[!] 없는 아이템 - 청사진 테이블을 이용하세요", + "create.schematic.position": "위치", + "create.schematic.rotation": "회전", + "create.schematic.rotation.none": "없음", + "create.schematic.rotation.cw90": "90도 시계방향 회전", + "create.schematic.rotation.cw180": "180도 시계방향 회전", + "create.schematic.rotation.cw270": "270도 시계방향 회전", + "create.schematic.mirror": "거울", + "create.schematic.mirror.none": "없음", + "create.schematic.mirror.frontBack": "전-후", + "create.schematic.mirror.leftRight": "좌-우", + + "create.schematic.tool.deploy": "전개", + "create.schematic.tool.move": "X/Z좌표 이동", + "create.schematic.tool.movey": "Y좌표 이동", + "create.schematic.tool.rotate": "회전", + "create.schematic.tool.print": "설치", + "create.schematic.tool.flip": "뒤집기", + + "create.schematic.tool.deploy.description.0": "구조물을 해당 위치로 고정합니다.", + "create.schematic.tool.deploy.description.1": "땅에다 우클릭으로 설치합니다.", + "create.schematic.tool.deploy.description.2": "[Ctrl]을 눌러 플레이어-청사진의 거리를 설정합니다.", + "create.schematic.tool.deploy.description.3": "[Ctrl]-스크롤로 거리를 조정합니다.", + "create.schematic.tool.move.description.0": "청사진을 수평 이동시킵니다.", + "create.schematic.tool.move.description.1": "청사진을 보고 [CTRL]-스크롤로 밉니다.", + "create.schematic.tool.move.description.2": "", + "create.schematic.tool.move.description.3": "", + "create.schematic.tool.movey.description.0": "청사진을 수직 이동시킵니다.", + "create.schematic.tool.movey.description.1": "청사진을 보고 [CTRL]-스크롤로 밉니다.", + "create.schematic.tool.movey.description.2": "", + "create.schematic.tool.movey.description.3": "", + "create.schematic.tool.rotate.description.0": "청사진을 돌립니다.", + "create.schematic.tool.rotate.description.1": "[CTRL]-스크롤로 90도 돌립니다.", + "create.schematic.tool.rotate.description.2": "", + "create.schematic.tool.rotate.description.3": "", + "create.schematic.tool.print.description.0": "구조물을 즉시 설치합니다.", + "create.schematic.tool.print.description.1": "[우클릭]으로 현재 지점에 설치를 허가합니다.", + "create.schematic.tool.print.description.2": "이 도구는 크리에이티브 모드 전용입니다.", + "create.schematic.tool.print.description.3": "", + "create.schematic.tool.flip.description.0": "당신이 보는 면으로 청사진을 뒤집습니다.", + "create.schematic.tool.flip.description.1": "청사진을 보고 [CTRL]-스크롤로 뒤집습니다.", + "create.schematic.tool.flip.description.2": "", + "create.schematic.tool.flip.description.3": "", + + "create.schematics.synchronizing": "동기화 중...", + "create.schematics.uploadTooLarge": "청사진이 너무 큽니다!.", + "create.schematics.maxAllowedSize": "최대 청사진 파일 크기는:", + + "create.gui.schematicTable.title": "청사진 테이블", + "create.gui.schematicTable.availableSchematics": "이용가능한 청사진", + "create.gui.schematicTable.noSchematics": "저장된 청사진 없음", + "create.gui.schematicTable.uploading": "업로딩 중...", + "create.gui.schematicTable.finished": "업로드 완료!", + + "create.gui.schematicannon.title": "청사진 대포", + "create.gui.schematicannon.settingsTitle": "설치 설정", + "create.gui.schematicannon.listPrinter": "재료 목록 프린터", + "create.gui.schematicannon.gunpowderLevel": "화약 용량 %1$s%%", + "create.gui.schematicannon.shotsRemaining": "남은 발포 수 : %1$s", + "create.gui.schematicannon.shotsRemainingWithBackup": "화약 여분: %1$s", + "create.gui.schematicannon.optionEnabled": "현재 활성화 됨", + "create.gui.schematicannon.optionDisabled": "현재 비활성화 됨", + "create.gui.schematicannon.option.dontReplaceSolid": "온전한 블럭을 대체하지 않음", + "create.gui.schematicannon.option.replaceWithSolid": "온전한 블럭을 재료로 대체함", + "create.gui.schematicannon.option.replaceWithAny": "온전한 블럭을 아무 재료로 대체함", + "create.gui.schematicannon.option.replaceWithEmpty": "온전한 블럭을 공기로 채움", + "create.gui.schematicannon.option.skipMissing": "부족한 블럭을 무시하고 진행", + "create.gui.schematicannon.option.skipTileEntities": "타일 엔티티를 보호", + + "create.gui.schematicannon.option.skipMissing.description": "만약 대포가 설치에 필요한 블럭을 찾지 못할 경우,건너뛰고 다음 블럭 설치를 진행합니다.", + "create.gui.schematicannon.option.skipTileEntities.description": "대포가 상세정보가 든 상자같은 타일 엔티티 설치를 무시합니다.", + "create.gui.schematicannon.option.dontReplaceSolid.description": "대포가 작업구역의 온전한 블럭을 대체하지 않습니다.", + "create.gui.schematicannon.option.replaceWithSolid.description": "대포가 작업구역의 온전한 블럭을 대포가 가진 재료로 대체합니다.", + "create.gui.schematicannon.option.replaceWithAny.description": "대포가 작업구역의 온전한 블럭을 대포가 가진 어떠한 재료로든 대체합니다.", + "create.gui.schematicannon.option.replaceWithEmpty.description": "대포가 작업구역의 블럭들을 제거하고 공기로 채웁니다.", + + "create.schematicannon.status.idle": "휴식", + "create.schematicannon.status.ready": "준비됨", + "create.schematicannon.status.running": "가동 중", + "create.schematicannon.status.finished": "완료", + "create.schematicannon.status.paused": "멈춤", + "create.schematicannon.status.stopped": "중단됨", + "create.schematicannon.status.noGunpowder": "화약이 부족함", + "create.schematicannon.status.targetNotLoaded": "블럭이 준비되지 않음", + "create.schematicannon.status.targetOutsideRange": "목표가 너무 멀리 떨어져 있습니다.", + "create.schematicannon.status.searching": "검색 중", + "create.schematicannon.status.skipping": "건너뛰는 중", + "create.schematicannon.status.missingBlock": "부족한 블럭:", + "create.schematicannon.status.placing": "설치 중", + "create.schematicannon.status.clearing": "블럭을 제거하는 중", + "create.schematicannon.status.schematicInvalid": "청사진 없음", + "create.schematicannon.status.schematicNotPlaced": "청사진이 전개되지 않음", + "create.schematicannon.status.schematicExpired": "청사진 파일이 제거됨", + + "create.gui.filter.blacklist": "블랙리스트", + "create.gui.filter.blacklist.description": "위 목록에 맞지않는 아이템이면 통과합니다. 빈 블랙리스트는 모두 통과시킵니다.", + "create.gui.filter.whitelist": "화이트리스트", + "create.gui.filter.whitelist.description": "위 목록에 맞는 아이템이면 통과합니다. 빈 화이트리스트는 모두 통과시키지 않습니다.", + "create.gui.filter.respect_data": "상세정보 일치", + "create.gui.filter.respect_data.description": "위 목록 아이템의 내구도, 마법부여, 그리고 다른 NBT와 일치할 때 통과시킵니다.", + "create.gui.filter.ignore_data": "상세정보 무시", + "create.gui.filter.ignore_data.description": "상세정보와 상관없이 아이템 종류만 일치한다면 통과시킵니다.", + + "create.item_attributes.placeable": "설치할 수 있음", + "create.item_attributes.consumable": "먹을 수 있음", + "create.item_attributes.smeltable": "구워질 수 있음", + "create.item_attributes.washable": "세척될 수 있음", + "create.item_attributes.smokable": "훈연될 수 있음", + "create.item_attributes.blastable": "용광로에 녹일 수 있음", + "create.item_attributes.enchanted": "마법부여됨", + "create.item_attributes.damaged": "내구도가 닮", + "create.item_attributes.badly_damaged": "심각하게 내구도가 닮", + "create.item_attributes.not_stackable": "겹쳐질 수 없음", + "create.item_attributes.equipable": "장착할 수 있음", + "create.item_attributes.furnace_fuel": "화로 연료로 쓸 수 있음", + "create.item_attributes.in_tag": "%1$s로 등록됨", + "create.item_attributes.in_item_group": "%1$s탭에 속함", + "create.item_attributes.added_by": "%1$s가 추가함", + + "create.gui.attribute_filter.no_selected_attributes": "속성이 선택되지 않음", + "create.gui.attribute_filter.selected_attributes": "선택된 속성:", + "create.gui.attribute_filter.whitelist_disjunctive": "화이트리스트 (최소)", + "create.gui.attribute_filter.whitelist_disjunctive.description": "아이템이 선택된 속성 중 하나라도 가지고 있다면 통과시킵니다.", + "create.gui.attribute_filter.whitelist_conjunctive": "화이트리스트 (모두)", + "create.gui.attribute_filter.whitelist_conjunctive.description": "아이템이 선택된 속성 모두를 가지고 있어야 통과시킵니다.", + "create.gui.attribute_filter.blacklist": "블랙리스트", + "create.gui.attribute_filter.blacklist.description": "아이템이 선택된 속성이 없다면 통과시킵니다.", + "create.gui.attribute_filter.add_reference_item": "참고할 아이템을 추가하기", + + "create.tooltip.holdKey": "[%1$s]를 눌러 설명보기", + "create.tooltip.holdKeyOrKey": "[%1$s] 또는 [%2$s]를 눌러 설명보기", + "create.tooltip.keyShift": "Shift", + "create.tooltip.keyCtrl": "Ctrl", + + "create.tooltip.speedRequirement": "회전속도 요구: %1$s", + "create.tooltip.speedRequirement.none": "없음", + "create.tooltip.speedRequirement.medium": "보통", + "create.tooltip.speedRequirement.high": "빠름", + + "create.tooltip.stressImpact": "피로도 부하: %1$s", + "create.tooltip.stressImpact.low": "낮음", + "create.tooltip.stressImpact.medium": "보통", + "create.tooltip.stressImpact.high": "높음", + "create.tooltip.stressImpact.overstressed": "과부하됨", + + "create.tooltip.capacityProvided": "피로도 용량: %1$s", + "create.tooltip.capacityProvided.low": "적음", + "create.tooltip.capacityProvided.medium": "보통", + "create.tooltip.capacityProvided.high": "큼", + "create.tooltip.capacityProvided.asGenerator": "(발전기로써)", + "create.tooltip.generationSpeed" : "%1$s %2$s만큼 발전함", + + "create.tooltip.analogStrength": "레드스톤 출력: %1$s/15", + + "create.tooltip.wip": "WIP", + "create.tooltip.workInProgress": "Work in progress!", + + "create.tooltip.randomWipDescription0": "Please keep this item away from children.", + "create.tooltip.randomWipDescription1": "A baby panda dies every time you use this item. Every. Time.", + "create.tooltip.randomWipDescription2": "Use at your own risk.", + "create.tooltip.randomWipDescription3": "This is not the item you are looking for, *finger-wiggles* please disperse.", + "create.tooltip.randomWipDescription4": "This item will self-destruct in 10 seconds. 10, 9, 8...", + "create.tooltip.randomWipDescription5": "Believe me, it's useless.", + "create.tooltip.randomWipDescription6": "By using this item, you hereby consent to our disclaimer and agree to its terms.", + "create.tooltip.randomWipDescription7": "This one maybe isn't for you. What about that one?", + "create.tooltip.randomWipDescription8": "Use it and regret your decision immediately.", + + "create.mechanical_mixer.min_ingredients": "최소 재료 종류", + + "create.command.killTPSCommand": "killtps", + "create.command.killTPSCommand.status.slowed_by.0": "[Create]: Server tick is currently slowed by %s ms :o", + "create.command.killTPSCommand.status.slowed_by.1": "[Create]: Server tick is slowed by %s ms now >:)", + "create.command.killTPSCommand.status.slowed_by.2": "[Create]: Server tick is back to regular speed :D", + "create.command.killTPSCommand.status.usage.0": "[Create]: use /killtps stop to bring back server tick to regular speed", + "create.command.killTPSCommand.status.usage.1": "[Create]: use /killtps start to artificially slow down the server tick", + "create.command.killTPSCommand.argument.tickTime": "tickTime", + + "advancement.create:root": "처음부터 Create하기!", + "advancement.create:root.desc": "멋진 장치들을 만들 시간이야!", + "advancement.create:andesite_alloy": "이게.. 합금..?", + "advancement.create:andesite_alloy.desc": "Create모드는 조금 이상한 아이템이 있습니다. 안산암 합금이 그 중 하나죠.", + "advancement.create:andesite_casing": "안산암 시대", + "advancement.create:andesite_casing.desc": "안산암, 나무를 이용하여 기본 케이스를 만드세요.", + "advancement.create:crushing_wheel": "한 쌍의 거인들", + "advancement.create:crushing_wheel.desc": "재료들을 갈 분쇄 휠을 만드세요.", + "advancement.create:rotation": "움직인다!", + "advancement.create:rotation.desc": "당신의 첫 장치가 움직이는 것을 보세요.", + "advancement.create:overstressed": "과부화!", + "advancement.create:overstressed.desc": "직접 물리법칙을 경험해보세요.", + "advancement.create:sand_paper": "힘세고 강한 윤내기", + "advancement.create:sand_paper.desc": "사포를 만들고 재료를 윤내세요.", + "advancement.create:polished_rose_quartz": "분홍빛 다이아몬드", + "advancement.create:polished_rose_quartz.desc": "장밋빛 석영을 반대편까지 보이도록 열심히 사포질하세요.", + "advancement.create:sand_paper_secret": "사포, 사포, 사포!", + "advancement.create:sand_paper_secret.desc": "당신의 사포로 사포를 사포질 하세요!", + "advancement.create:press": "'깡!'", + "advancement.create:press.desc": "압착기를 만들고 판을 찍으세요.", + "advancement.create:mixer": "섞고 돌리고 섞고", + "advancement.create:mixer.desc": "믹서를 만드세요.", + "advancement.create:brass": "진짜 합금", + "advancement.create:brass.desc": "구리와 아연을 가지고 황동을 만드세요.", + "advancement.create:brass_casing": "황동기 시대", + "advancement.create:brass_casing.desc": "새롭게 얻은 황동과 나무를 가지고 업그레이드된 케이스를 만드세요.", + "advancement.create:deployer": "찌르고, 설치하고, 공격!", + "advancement.create:deployer.desc": "완벽한 당신의 분신, 배포기를 만드세요.", + "advancement.create:deployer_secret": "Pound It, Bro!", + "advancement.create:deployer_secret.desc": "두 배포기의 주먹을 부딫치세요.", + "advancement.create:chromatic_compound": "양극성 재료", + "advancement.create:chromatic_compound.desc": "색채 혼합물를 만드세요.", + "advancement.create:shadow_steel": "공허를 받아들여라", + "advancement.create:shadow_steel.desc": "무의 금속, 그림자 강철을 생성하세요.", + "advancement.create:refined_radiance": "빛과 질서", + "advancement.create:refined_radiance.desc": "색이 하나로 합쳐진 정제된 빛을 생성하세요.", + "advancement.create:refined_radiance_secret": "빛줄기로 제련되다", + "advancement.create:refined_radiance_secret.desc": "정제된 광채를 만들 대체제를 찾아보세요.", + "advancement.create:speed_secret": "?", + "advancement.create:speed_secret.desc": "속도 계측기가 정확히 69RPM에 도달하는걸 보세요.", + + "create.subtitle.schematicannon_launch_block": "청사진 대포가 발포함", + "create.subtitle.schematicannon_finish": "청사진 대포가 끝남", + "create.subtitle.slime_added": "슬라임이 철퍽거림", + "create.subtitle.mechanical_press_activation": "압착기가 가동됨", + "create.subtitle.mechanical_press_item_break": "금속이 부딫힘", + "create.subtitle.blockzapper_place": "블럭이 순간이동됨", + "create.subtitle.blockzapper_confirm": "확인 효과음", + "create.subtitle.blockzapper_deny": "취소 효과음", + "create.subtitle.block_funnel_eat": "깔때기가 흡입함", + + "_comment": "-------------------------] ITEM DESCRIPTIONS [------------------------------------------------", + "item.create.example_item.tooltip": "EXAMPLE ITEM (just a marker that this tooltip exists)", + "item.create.example_item.tooltip.summary": "A brief description of the item. _Underscores_ highlight a term.", + "item.create.example_item.tooltip.condition1": "When this", + "item.create.example_item.tooltip.behaviour1": "Then this item does this. (behaviours show on shift)", + "item.create.example_item.tooltip.condition2": "And When this", + "item.create.example_item.tooltip.behaviour2": "You can add as many behaviours as you like", + "item.create.example_item.tooltip.control1": "When Ctrl pressed", + "item.create.example_item.tooltip.action1": "These controls are displayed.", + + "item.create.symmetry_wand.tooltip": "SYMMETRY WAND", + "item.create.symmetry_wand.tooltip.summary": "설정된 반사 모드에 따라 블럭 설치를 똑같이 재현합니다.", + "item.create.symmetry_wand.tooltip.condition1": "단축바에 있을 때", + "item.create.symmetry_wand.tooltip.behaviour1": "활성화 유지", + "item.create.symmetry_wand.tooltip.control1": "땅에다 우클릭", + "item.create.symmetry_wand.tooltip.action1": "거울을 _생성하거나_ _옮깁니다_.", + "item.create.symmetry_wand.tooltip.control2": "공중에 우클릭", + "item.create.symmetry_wand.tooltip.action2": "활성화된 거을을 _제거합니다_.", + "item.create.symmetry_wand.tooltip.control3": "웅크린 상태에서 우클릭", + "item.create.symmetry_wand.tooltip.action3": "_설정_ _창_을 엽니다.", + + "item.create.placement_handgun.tooltip": "BLOCKZAPPER", + "item.create.placement_handgun.tooltip.summary": "멀리있는 블럭을 교체, 설치하는 놀라운 도구입니다.", + "item.create.placement_handgun.tooltip.control1": "블럭을 보고 좌클릭", + "item.create.placement_handgun.tooltip.action1": "이 도구로 설치할 블럭을 설정합니다.", + "item.create.placement_handgun.tooltip.control2": "블럭을 보고 우클릭", + "item.create.placement_handgun.tooltip.action2": "해당 위치에 설정된 블럭으로 설치하거나 교체합니다.", + "item.create.placement_handgun.tooltip.control3": "웅크린 상태에서 우클릭", + "item.create.placement_handgun.tooltip.action3": "_설정_ _창_을 엽니다.", + + "item.create.terrain_zapper.tooltip": "HANDHELD WORLDSHAPER", + "item.create.terrain_zapper.tooltip.summary": "_지형경관_을 만들 때 좋은 간편한 도구입니다.", + "item.create.terrain_zapper.tooltip.control1": "블럭을 보고 좌클릭", + "item.create.terrain_zapper.tooltip.action1": "이 도구로 설치할 블럭을 설정합니다.", + "item.create.terrain_zapper.tooltip.control2": "블럭을 보고 우클릭", + "item.create.terrain_zapper.tooltip.action2": "해당 위치에 설정된 _브러쉬_ 와 _도구_를 적용합니다.", + "item.create.terrain_zapper.tooltip.control3": "웅크린 상태에서 우클릭", + "item.create.terrain_zapper.tooltip.action3": "_설정_ _창_을 엽니다.", + + "item.create.tree_fertilizer.tooltip": "TREE FERTILIZER", + "item.create.tree_fertilizer.tooltip.summary": "일반적인 나무 종류들의 성장을 촉진시킬 강력한 미네랄의 혼합물입니다.", + "item.create.tree_fertilizer.tooltip.condition1": "묘목에 사용했을 때", + "item.create.tree_fertilizer.tooltip.behaviour1": "묘목을 주위 공간과 _상관없이_ 성장시킵니다.", + + "item.create.deforester.tooltip": "DEFORESTER", + "item.create.deforester.tooltip.summary": "수 초 만에 나무를 쓰러뜨리는 _경이로운_ _도끼_입니다.", + + "item.create.filter.tooltip": "FILTER", + "item.create.filter.tooltip.summary": "장치의 _입력_과 _출력_을 필터 _아이템_ 목록에 따라 정확하게 _조정_합니다.", + "item.create.filter.tooltip.condition1": "필터 슬롯에 있을 때", + "item.create.filter.tooltip.behaviour1": "필터 _설정_에 따라 아이템 흐름을 _조정_합니다.", + "item.create.filter.tooltip.condition2": "우클릭", + "item.create.filter.tooltip.behaviour2": "_설정_ _창_을 엽니다.", + + "item.create.property_filter.tooltip": "ATTRIBUTE FILTER", + "item.create.property_filter.tooltip.summary": "장치의 _입력_과 _출력_을 필터 _속성_ 목록에 따라 정확하게 _조정_합니다.", + "item.create.property_filter.tooltip.condition1": "필터 슬롯에 있을 때", + "item.create.property_filter.tooltip.behaviour1": "필터 _설정_에 따라 아이템 흐름을 _조정_합니다.", + "item.create.property_filter.tooltip.condition2": "우클릭", + "item.create.property_filter.tooltip.behaviour2": "_설정_ _창_을 엽니다.", + + "block.create.cocoa_log.tooltip": "COCOA LOG", + "block.create.cocoa_log.tooltip.summary": "코코아 콩 _자동화_를 더 쉽게 해줄 정글 나무 원목입니다.", + "block.create.cocoa_log.tooltip.condition1": "성장했을 때", + "block.create.cocoa_log.tooltip.behaviour1": "모든 면에 코코아 콩을 생성합니다.", + + "item.create.empty_blueprint.tooltip": "EMPTY SCHEMATIC", + "item.create.empty_blueprint.tooltip.summary": "조합 재료로 쓰이거나 청사진 테이블에서 청사진을 불러올 때 쓰입니다.", + + "item.create.blueprint.tooltip": "SCHEMATIC", + "item.create.blueprint.tooltip.summary": "세계에 구조물을 홀로그램으로 불러와 지정하고 설치합니다. 지정된 홀로그램은 청사진 대포의 작업 영역이 됩니다.", + "item.create.blueprint.tooltip.condition1": "들고 있을 떄", + "item.create.blueprint.tooltip.behaviour1": "UI의 도구로 변경/설치 할 수 있습니다.", + "item.create.blueprint.tooltip.control1": "웅크린 상태에서 우클릭", + "item.create.blueprint.tooltip.action1": "정확한 _좌표_ 입력을 위한 창을 엽니다.", + + "item.create.blueprint_and_quill.tooltip": "SCHEMATIC AND QUILL", + "item.create.blueprint_and_quill.tooltip.summary": "세계에 있는 구조물을 .nbt 파일로 저장할 때 쓰입니다.", + "item.create.blueprint_and_quill.tooltip.condition1": "1단계", + "item.create.blueprint_and_quill.tooltip.behaviour1": "두 모서리를 우클릭으로 선택하세요.", + "item.create.blueprint_and_quill.tooltip.condition2": "2단계", + "item.create.blueprint_and_quill.tooltip.behaviour2": "면을 바라보고 _Ctrl-스크롤_하여 크기를 조정하세요. 우클릭을 다시 하면 저장됩니다.", + "item.create.blueprint_and_quill.tooltip.control1": "우클릭", + "item.create.blueprint_and_quill.tooltip.action1": "모서리 선택 / 저장 확인", + "item.create.blueprint_and_quill.tooltip.control2": "Ctrl를 누르고 있을 때", + "item.create.blueprint_and_quill.tooltip.action2": "_Scroll_를 이용하여 거리를 조정합니다.", + "item.create.blueprint_and_quill.tooltip.control3": "웅크린 상태에서 우클릭", + "item.create.blueprint_and_quill.tooltip.action3": "선택 영역을 리셋하고 _삭제_합니다.", + + "block.create.creative_crate.tooltip": "CREATIVE CRATE", + "block.create.creative_crate.tooltip.summary": "옆 _청사진 대포_에 _무한한_ 재료를 공급합니다.", + + "block.create.schematicannon.tooltip": "SCHEMATICANNON", + "block.create.schematicannon.tooltip.summary": "장착된 청사진을 바탕으로 블럭들을 발포합니다. 화약을 연료로 사용하고 주변 인벤토리 공간에서 아이템을 사용합니다.", + "block.create.schematicannon.tooltip.control1": "우클릭", + "block.create.schematicannon.tooltip.action1": "창을 엽니다.", + + "block.create.schematic_table.tooltip": "SCHEMATIC TABLE", + "block.create.schematic_table.tooltip.summary": "_빈_ _청사진_에 저장된 청사진을 불러옵니다.", + "block.create.schematic_table.tooltip.condition1": "빈 청사진을 넣을 때", + "block.create.schematic_table.tooltip.behaviour1": "Schematics 폴더에서 선택한 파일을 업로드합니다.", + + "block.create.shaft.tooltip": "SHAFT", + "block.create.shaft.tooltip.summary": "_일직선_으로 _회전_을 전달합니다.", + + "block.create.cogwheel.tooltip": "COGWHEEL", + "block.create.cogwheel.tooltip.summary": " _일직선_이나 _옆_ _톱니바퀴_로 _회전_을 _전달_합니다.", + + "block.create.large_cogwheel.tooltip": "LARGE COGWHEEL", + "block.create.large_cogwheel.tooltip.summary": "큰 톱니바퀴입니다. 작은 톱니바퀴와 맞물렸을때, _회전 속도_가 _변합니다_.", + + "block.create.encased_shaft.tooltip": "ENCASED SHAFT", + "block.create.encased_shaft.tooltip.summary": "_일직선_으로 _회전_을 전달합니다. _벽을_ _넘어_ 회전을 보낼 때 유용합니다.", + + "block.create.gearbox.tooltip": "GEARBOX", + "block.create.gearbox.tooltip.summary": "_전후좌우_ / _상하전후_로 회전을 보냅니다. 한번 더 조합해서 설정을 바꿀 수 있습니다.", + + "block.create.gearshift.tooltip": "GEARSHIFT", + "block.create.gearshift.tooltip.summary": "연결된 축의 회전 방향을 _변경_합니다.", + "block.create.gearshift.tooltip.condition1": "레드스톤 신호를 받았을 때", + "block.create.gearshift.tooltip.behaviour1": "_출력_ 회전 방향을 _반전_시킵니다.", + + "block.create.clutch.tooltip": "CLUTCH", + "block.create.clutch.tooltip.summary": "연결된 축의 회전을 끄고 킬 수 있습니다.", + "block.create.clutch.tooltip.condition1": "레드스톤 신호를 받았을 때", + "block.create.clutch.tooltip.behaviour1": "출력 방향 회전을 멈춥니다.", + + "block.create.encased_belt.tooltip": "ENCASED_BELT", + "block.create.encased_belt.tooltip.summary": "연결된 다른 _덮힌 벨트_에 회전을 _연결_합니다.", + "block.create.encased_belt.tooltip.condition1": "축에 연결 되었을 때", + "block.create.encased_belt.tooltip.behaviour1": "연결된 축, 기어, 장치들은 _같은_ _회전_ _속도_와 _방향_을 가집니다. 같은 방향으로 _맞대지_ _않아도_ _됩니다_.", + + "block.create.adjustable_pulley.tooltip": "ANALOG BELT PULLEY", + "block.create.adjustable_pulley.tooltip.summary": "덮힌 벨트와 같은 역할을 가집니다. 또한 입/출력 부분에 설치하고 레드스톤 신호 세기에 따라 _회전_ _속도_를 _조정_할 수 있습니다.", + "block.create.adjustable_pulley.tooltip.condition1": "레드스톤 신호 설정", + "block.create.adjustable_pulley.tooltip.behaviour1": "_입력_ 부분에 설치하면 출력 회전 속도를 _낮추고_ (최대 0.5배), _출력_ 부분에 설치하면 출력 회전 속도를 _증가시킵니다_ (최대 2배).", + + "item.create.belt_connector.tooltip": "BELT CONNECTOR", + "item.create.belt_connector.tooltip.summary": "두 개 이상의 _축_을 벨트로 연결할 수 있습니다. 연결된 축들은 _모두_ _같은_ _속도_와 _방향_을 가집니다. 벨트는 _아이템_이나 _엔티티_를 _옮길_ _수_ _있습니다_.", + "item.create.belt_connector.tooltip.control1": "축에다 우클릭", + "item.create.belt_connector.tooltip.action1": "첫번째 벨트 끝부분을 설정합니다. 두번째 축은 반드시 _수평_이나 _수직_, _대각선_ 방향에 있는 축에 연결해야합니다.", + "item.create.belt_connector.tooltip.control2": "웅크린 상태에서 우클릭", + "item.create.belt_connector.tooltip.action2": "첫번째 벨트 설정을 초기화합니다.", + + "item.create.goggles.tooltip": "GOGGLES", + "item.create.goggles.tooltip.summary": "장치 정보를 착용자의 시야에 띄어주는 안경입니다.", + "item.create.goggles.tooltip.condition1": "장착했을 때", + "item.create.goggles.tooltip.behaviour1": "해당 장치의 _속도_, _피로도_, _용량_을 레벨에 따라 에 따라 색상 UI를 보여줍니다.", + "item.create.goggles.tooltip.condition2": "계측기를 바라볼 때", + "item.create.goggles.tooltip.behaviour2": "계측기가 연결된 네트워크의 _속도_나 _스트레스_의 자세한 정보를 보여줍니다.", + + "item.create.wrench.tooltip": "WRENCH", + "item.create.wrench.tooltip.summary": "장치 구성에 유용한 도구입니다. 장치를 _회전_, _설정_, _해체_하는 데 쓰입니다.", + "item.create.wrench.tooltip.control1": "장치에 우클릭", + "item.create.wrench.tooltip.action1": "사용자가 바라보는 _면으로_ 혹은 _반대로_ 장치를 돌립니다.", + "item.create.wrench.tooltip.control2": "웅크린 상태에서 우클릭", + "item.create.wrench.tooltip.action2": "_장치_를 _해체_하고 _즉시_ _인벤토리_로 넣습니다.", + + "block.create.creative_motor.tooltip": "CREATIVE MOTOR", + "block.create.creative_motor.tooltip.summary": "회전 속도를 _조정_할 수 있는 장치입니다.", + + "block.create.water_wheel.tooltip": "WATER WHEEL", + "block.create.water_wheel.tooltip.summary": "인접한 _물의_ _흐름_에서 얻은 회전을 제공합니다.", + + "block.create.encased_fan.tooltip": "ENCASED FAN", + "block.create.encased_fan.tooltip.summary": "회전력을 바람으로 전환합니다. 다양한 용도로 사용 가능합니다.", + "block.create.encased_fan.tooltip.condition1": "레드스톤 신호를 받을 때", + "block.create.encased_fan.tooltip.behaviour1": "장치 아래의 _열_을 _회전력_으로 _바꾸어_ 제공합니다. 날개가 아래를 바라보아야 합니다.", + "block.create.encased_fan.tooltip.condition2": "돌려질 때", + "block.create.encased_fan.tooltip.behaviour2": "들어오는 회적 속도에 따라 엔티티를 밀거나 당깁니다.", + "block.create.encased_fan.tooltip.condition3": "특정 블럭을 통해 바람을 보낼 때", + "block.create.encased_fan.tooltip.behaviour3": "공기 흐름에 _액체_ 혹은 _불꽃_ 효과가 _추가_됩니다. 이는 아이템을 _공정_하는데 쓰일 수 있습니다.", + + "block.create.nozzle.tooltip": "NOZZLE", + "block.create.nozzle.tooltip.summary": "덮힌 환풍기 _앞_에 붙여 환풍기의 효과를 _전방_으로 _확대_합니다.", + + "block.create.hand_crank.tooltip": "HAND CRANK", + "block.create.hand_crank.tooltip.summary": "간단한 회전력의 원천입니다. 플레이어의 _상호작용_이 필요합니다.", + "block.create.hand_crank.tooltip.condition1": "사용될 때", + "block.create.hand_crank.tooltip.behaviour1": "연결된 장치에 _회전력_을 _제공_합니다. 웅크리면 _반대로_ 회전시킵니다.", + + "block.create.cuckoo_clock.tooltip": "CUCKOO CLOCK", + "block.create.cuckoo_clock.tooltip.summary": "_시간의_ _흐름_을 알고 공간을 _꾸미는_ 데 좋은 공예품입니다.", + "block.create.cuckoo_clock.tooltip.condition1": "회전할 때", + "block.create.cuckoo_clock.tooltip.behaviour1": "현재 시각을 보여주고 하루에 두 번 울립니다. 점심과 플레이어가 바로 잘 수 있는 저녁에 울립니다.", + + "block.create.turntable.tooltip": "TURNTABLE", + "block.create.turntable.tooltip.summary": "_회전력_으로 _멀미_를 일으킵니다.", + + "block.create.millstone.tooltip": "MILLSTONE", + "block.create.millstone.tooltip.summary": "투입된 _재료_를 _가는_ 데 좋은 장치입니다. 측면 톱니바퀴나 바닥에 축을 이어 작동합니다. 결과물은 직접 빼내야 합니다.", + "block.create.millstone.tooltip.condition1": "회전 할 때", + "block.create.millstone.tooltip.behaviour1": "옆이나 위에서 투입된 아이템을 _맷돌질_합니다.", + "block.create.millstone.tooltip.condition2": "우클릭할때", + "block.create.millstone.tooltip.behaviour2": "결과물을 직접 꺼냅니다.", + + "block.create.crushing_wheel.tooltip": "CRUSHING WHEEL", + "block.create.crushing_wheel.tooltip.summary": "모든 것을 _부숴버리는_ 큰 바퀴입니다.", + "block.create.crushing_wheel.tooltip.condition1": "다른 분쇄 휠과 붙어있을 때", + "block.create.crushing_wheel.tooltip.behaviour1": "다양한 것을 _분쇄_하는 분쇄 기계를 형성합니다. 휠의 이빨이 _같은_ _속력_으로, _반대_ _방향_으로 맞물려야합니다.", + + "block.create.mechanical_press.tooltip": "MECHANICAL PRESS", + "block.create.mechanical_press.tooltip.summary": "아래있는 아이템을 _눌러버리는_ 힘센 피스톤입니다. _지속적인_ _회전력_이 필요합니다.", + "block.create.mechanical_press.tooltip.condition1": "레드스톤 신호를 받았을 때", + "block.create.mechanical_press.tooltip.behaviour1": "_아래 있는_ 아이템을 누르기 시작합니다.", + "block.create.mechanical_press.tooltip.condition2": "컨베이어 벨트 위에 있을 때", + "block.create.mechanical_press.tooltip.behaviour2": "_자동으로_ 벨트 위를 지나가는 아이템을 누릅니다.", + "block.create.mechanical_mixer.tooltip.condition3": "대야 위에 있을 때", + "block.create.mechanical_mixer.tooltip.behaviour3": "필요한 재료들이 _들어올_ _때마다_ 아이템을 _압축_시킵니다.", + + "block.create.basin.tooltip": "BASIN", + "block.create.basin.tooltip.summary": "믹서나 압착기와 같이 쓰이는 간편한 _아이템_ _저장소_입니다. 레드스톤 비교기와 호환됩니다.", + + "block.create.mechanical_mixer.tooltip": "MECHANICAL MIXER", + "block.create.mechanical_mixer.tooltip.summary": "아래있는 아이템을 조합할 혼합기입니다. _지속적인_ _회전력_과 한 칸 아래에 _대야_가 필요합니다.", + "block.create.mechanical_mixer.tooltip.condition1": "대야 위에 있을 때", + "block.create.mechanical_mixer.tooltip.behaviour1": "모든 필요한 아이템이 준비될 때마다 대야 안의 아이템을 섞기 시작합니다.", + "block.create.mechanical_mixer.tooltip.condition2": "렌치를 사용할 때", + "block.create.mechanical_mixer.tooltip.behaviour2": "필요한 조합법의 _최소_ _재료_ _종류_를 설정합니다. 이는 적은 재료로 _원치_ _않은_ _조합법_이 작동되는 것을 막습니다.", + + "block.create.mechanical_crafter.tooltip": "MECHANICAL CRAFTER", + "block.create.mechanical_crafter.tooltip.summary": "모든 조합법을 _자동화_할 장치입니다. 조합법대로 여러개를 _격자_로 설치하고, 화살표를 돌려 _한_ _곳으로_ _모이게_ 설정해야합니다.", + "block.create.mechanical_crafter.tooltip.condition1": "회전할 때", + "block.create.mechanical_crafter.tooltip.behaviour1": "모든 조합칸에 있는 아이템들을 조합하기 시작합니다.", + "block.create.mechanical_crafter.tooltip.control1": "전면을 렌치로 조정할 때", + "block.create.mechanical_crafter.tooltip.action1": "각 기계식 조합기의 아이템 이동 방향을 설정합니다. 모든 조합기의 방향은 _하나의_ _최종_ _조합기_로 이동해야하며, 최종 조합기는 조합기 _바깥으로_ 아이템을 운송해야합니다.", + "block.create.mechanical_crafter.tooltip.control2": "측면/후면에서 렌치로 조정할 때", + "block.create.mechanical_crafter.tooltip.action2": "인접한 조합기와 입력 공간을 _연결_합니다. 이를 통해 일일히 아이템을 넣는 노력을 줄일 수 있습니다.", + + "block.create.furnace_engine.tooltip": "FURNACE ENGINE", + "block.create.furnace_engine.tooltip.summary": "_화로의_ _작동_을 필요로 하는 강력한 회전 동력원입니다.", + "block.create.furnace_engine.tooltip.condition1": "작동하는 화로에 붙였을 때", + "block.create.furnace_engine.tooltip.behaviour1": "붙어있는(한칸 띄어져있는) _플라이휠_에 동력을 공급합니다. _용광로_는 _두_ _배_의 화력을 냅니다.", + + "block.create.flywheel.tooltip": "FLYWHEEL", + "block.create.flywheel.tooltip.summary": "붙어있는 _화로_ _엔진_에서 생산된 힘을 안정시키고 _동력화_하는 거대한 금속 바퀴입니다. 화로 엔진으로부터 _한_ _칸_ _떨어져_ 설치해야 합니다.", + "block.create.flywheel.tooltip.condition1": "작동하는 엔진에 붙었을 때", + "block.create.flywheel.tooltip.behaviour1": "엔진의 힘에 따라 연결된 장치에 _회전력_을 제공합니다.", + + "block.create.portable_storage_interface.tooltip": "PORTABLE STORAGE INTERFACE", + "block.create.portable_storage_interface.tooltip.summary": "움직이는 피스톤, 베어링, 수레, 밧줄 도르래의 인벤토리에서 _아이템을_ _교환하는_ 휴대용 장치입니다.", + "block.create.portable_storage_interface.tooltip.condition1": "움직일 때", + "block.create.portable_storage_interface.tooltip.behaviour1": "고정된 트랜스포저의 _방향에_ _따라_ 아이템을 _주거나_ _받습니다_. 아이템이 이동하는 동안 움직이는 기기는 _멈춥니다_.", + + "block.create.rotation_speed_controller.tooltip": "ROTATION SPEED CONTROLLER", + "block.create.rotation_speed_controller.tooltip.summary": "해당 톱니바퀴의 속도를 _변경_할 수 있는 컨트롤러입니다.", + "block.create.rotation_speed_controller.tooltip.condition1": "큰 톱니바퀴와 연결되었을 때", + "block.create.rotation_speed_controller.tooltip.behaviour1": "들어오는 회전력을 받아, 대상의 속도를 변경합니다. _큰_ _톱니바퀴_가 컨트롤러 위에 있어야합니다.", + + "block.create.mechanical_piston.tooltip": "MECHANICAL PISTON", + "block.create.mechanical_piston.tooltip.summary": "피스톤의 업그레이드 버전입니다. 회전력을 사용해 연결된 구조물을 옮깁니다. _피스톤_ _연장_ _축_을 후면에 붙여 이 장치의 사거리를 늘이거나 줄일 수 있습니다. 축이 없다면 움직이지 않습니다. _섀시_나 _슬라임_ _블럭_을 붙여 일직선의 블럭들을 움직일 수 있습니다.", + "block.create.mechanical_piston.tooltip.condition1": "회전될 때", + "block.create.mechanical_piston.tooltip.behaviour1": "붙어있는 구조물을 움직이기 시작합니다. 속도와 방향은 들어오는 회전 속도와 방향에 따라 달라집니다.", + + "block.create.sticky_mechanical_piston.tooltip": "STICKY MECHANICAL PISTON", + "block.create.sticky_mechanical_piston.tooltip.summary": "끈끈이 피스톤의 업그레이드 버전입니다. 회전력을 사용해 연결된 구조물을 옮깁니다. _피스톤_ _연장_ _축_을 후면에 붙여 이 장치의 사거리를 늘이거나 줄일 수 있습니다. 축이 없다면 움직이지 않습니다. _섀시_나 _슬라임_ _블럭_을 붙여 일직선의 블럭들을 움직일 수 있습니다.", + "block.create.sticky_mechanical_piston.tooltip.condition1": "회전될 때", + "block.create.sticky_mechanical_piston.tooltip.behaviour1": "붙어있는 구조물을 움직이기 시작합니다. 속도와 방향은 들어오는 회전 속도와 방향에 따라 달라집니다.", + + "block.create.piston_pole.tooltip": "PISTON POLE", + "block.create.piston_pole.tooltip.summary": "기계식 피스톤의 _사거리_를 늘려줍니다.", + "block.create.piston_pole.tooltip.condition1": "기계식 피스톤에 연결했을 때", + "block.create.piston_pole.tooltip.behaviour1": "피스톤의 사거리를 한 블럭 늘립니다.", + + "block.create.mechanical_bearing.tooltip": "MECHANICAL BEARING", + "block.create.mechanical_bearing.tooltip.summary": "큰 구조물을 _회전_시키거나 _바람으로부터_ 회전력을 얻습니다.", + "block.create.mechanical_bearing.tooltip.condition1": "회전될 때", + "block.create.mechanical_bearing.tooltip.behaviour1": "연결된 블럭들을 돌리기 시작합니다. _섀시_나 _슬라임_ _블럭_을 이용해 더 많은 블럭을 움직이세요.", + "block.create.mechanical_bearing.tooltip.condition2": "레드스톤 신호를 받을 때", + "block.create.mechanical_bearing.tooltip.behaviour2": "붙어있는 구조물의 회전을 이용하여 회전력을 제공합니다. 구조물은 _날개_에 적합한 블럭이 포함되어야합니다. (현재는 _아무_ _양털_이나 가능합니다).", + + "block.create.clockwork_bearing.tooltip": "CLOCKWORK BEARING", + "block.create.clockwork_bearing.tooltip.summary": "현재 _인게임_ _시간_을 알려주는 _시침_, _분침_을 돌리는 업그레이드된 베어링입니다.", + "block.create.clockwork_bearing.tooltip.condition1": "회전될 때", + "block.create.clockwork_bearing.tooltip.behaviour1": "현재 시간에 맞춰 연결된 구조물을 _시침_으로써 돌리기 시작합니다. _다른_ _종류의_ _섀시_가 있다면, _분침_처럼 돌립니다.", + + "block.create.sequenced_gearshift.tooltip": "SEQUENCED GEARSHIFT", + "block.create.sequenced_gearshift.tooltip.summary": "연속으로 5개의 회전 명령을 내릴 수 있는 _프로그램이_ _가능한_ 장치입니다. 이것으로 베어링, 피스톤, 도르래의 움직임과 타이밍을 정할 수 있습니다. 빠른 속력에는 부정확해질 수 있습니다.", + "block.create.sequenced_gearshift.tooltip.condition1": "레드스톤 신호를 받을 때", + "block.create.sequenced_gearshift.tooltip.behaviour1": "입력 속도에 따른 프로그램된 명령들을 수행하기 시작합니다.", + "block.create.sequenced_gearshift.tooltip.condition2": "우클릭했을 때", + "block.create.sequenced_gearshift.tooltip.behaviour2": "설정 창을 엽니다.", + + "block.create.cart_assembler.tooltip": "CART ASSEMBLER", + "block.create.cart_assembler.tooltip.summary": "지나가는 _광산_ _수레_에 연결된 구조물을 붙입니다.", + "block.create.cart_assembler.tooltip.condition1": "레드스톤 신호를 받을 때", + "block.create.cart_assembler.tooltip.behaviour1": "지나가는 광산 수레에 장착된 구조물을 분리시키고 조립기에 다시 설치합니다.", + + "block.create.rope_pulley.tooltip": "ROPE PULLEY", + "block.create.rope_pulley.tooltip.summary": "_수직으로_ 붙은 구조물을 움직입니다. _섀시_나 _슬라임_ _블럭_을 붙여 일직선의 블럭들을 움직일 수 있습니다.", + "block.create.rope_pulley.tooltip.condition1": "회전될 때", + "block.create.rope_pulley.tooltip.behaviour1": "연결된 구조물을 움직이기 시작합니다. 속도와 방향은 들어오는 회전 속도, 방향에 따라 다릅니다.", + + "block.create.translation_chassis.tooltip": "TRANSLATION CHASSIS", + "block.create.translation_chassis.tooltip.summary": "연결된 구조물의 이동을 위한 베이스 블럭입니다.", + "block.create.translation_chassis.tooltip.condition1": "움직일 때", + "block.create.translation_chassis.tooltip.behaviour1": "섀시의 _기둥_ _방향_으로 붙어있는 모든 블럭들을 같은 방향으로 옮깁니다. 블럭들은 섀시가 끈끈할 때만 당겨집니다 ([Ctrl]를 누르세요).", + "block.create.translation_chassis.tooltip.condition2": "렌치로 조정할 때", + "block.create.translation_chassis.tooltip.behaviour2": "대상 섀시의 사거리를 조정합니다. 또는 CTRL을 눌러 인접한 모든 섀시의 사거리를 조정합니다.", + "block.create.translation_chassis.tooltip.control1": "슬라임 볼로 우클릭", + "block.create.translation_chassis.tooltip.action1": "대상 면을 끈끈하게 만듭니다. 당겨질 때, 섀시는 연결된 _모든_ _블럭_을 움직이는 방향에 상관없이 당깁니다.", + + "block.create.rotation_chassis.tooltip": "ROTATION CHASSIS", + "block.create.rotation_chassis.tooltip.summary": "연결된 구조물의 이동을 위한 베이스 블럭입니다.", + "block.create.rotation_chassis.tooltip.condition1": "움직일 때", + "block.create.rotation_chassis.tooltip.behaviour1": "섀시의 _원_ _방향_으로 붙어있는 모든 블럭들을 같은 방향으로 옮깁니다. 블럭들이 섀시가 끈끈한 면에 붙어있을 때만 움직입니다 ([Ctrl]를 누르세요).", + "block.create.rotation_chassis.tooltip.condition2": "렌치로 조정할 때", + "block.create.rotation_chassis.tooltip.behaviour2": "대상 섀시의 사거리를 조정합니다. 또는 CTRL을 눌러 인접한 모든 섀시의 사거리를 조정합니다.", + "block.create.rotation_chassis.tooltip.control1": "슬라임 볼로 우클릭", + "block.create.rotation_chassis.tooltip.action1": "대상 면을 끈끈하게 만듭니다. 당겨질 때, 끈끈한 면에 붙은 _모든_ _블럭_을 움직이게 합니다", + + "block.create.drill.tooltip": "MECHANICAL DRILL", + "block.create.drill.tooltip.summary": "블럭을 _파괴하는_ 데 적합한 장치입니다. 베어링이나 기계식 피스톤으로 움직여집니다.", + "block.create.drill.tooltip.condition1": "회전될 때", + "block.create.drill.tooltip.behaviour1": "고정되어 블럭을 부숩니다. 또한 해당영역의 엔티티에게 피해를 줍니다.", + "block.create.drill.tooltip.condition2": "움직일 때", + "block.create.drill.tooltip.behaviour2": "드릴이 부딫히는 모든 블럭을 부숩니다.", + + "block.create.harvester.tooltip": "MECHANICAL HARVESTER", + "block.create.harvester.tooltip.summary": "중간 크기의 작물 자동화에 적합한 _작물_ _수확기_입니다. 베어링이나 기계식 피스톤으로 움직여집니다.", + "block.create.harvester.tooltip.condition1": "움직일 때", + "block.create.harvester.tooltip.behaviour1": "칼날에 닿는 모두 자란 작물을 수확하고 최초 성장 상태로 변경합니다.", + + "block.create.saw.tooltip": "MECHANICAL SAW", + "block.create.saw.tooltip.summary": "효율적인 _벌목_과 블럭을 _제재_하는데 적합합니다. 베어링이나 기계식 피스톤으로 움직여집니다.", + "block.create.saw.tooltip.condition1": "위를 바라볼 때", + "block.create.saw.tooltip.behaviour1": "_제재_와 _석재_ _절단_ 조합법을 떨어진/투입된 아이템에 적용합니다. 결과물이 여러 종류고 필터가 적용이 되지 않았다면, 결과물은 _목록_ _순서_대로 배출됩니다.", + "block.create.saw.tooltip.condition2": "옆을 바라볼 때", + "block.create.saw.tooltip.behaviour2": "앞에 있는 원목을 자릅니다. 나무의 원목이라면, 나무가 쓰러지면서 아이템을 떨굽니다.", + "block.create.saw.tooltip.condition3": "움직일 때", + "block.create.saw.tooltip.behaviour3": "톱이 만나는 모든 나무를 벱니다.", + + "block.create.stockswitch.tooltip": "STOCKSWITCH", + "block.create.stockswitch.tooltip.summary": "붙어있는 _저장소_에 _여유_ _공간_을 기반으로 레드스톤 신호를 보냅니다.", + "block.create.stockswitch.tooltip.condition1": "_최소_ _경계_보다 낮을 경우", + "block.create.stockswitch.tooltip.behaviour1": "레드스톤 신호를 보내지 않습니다.", + "block.create.stockswitch.tooltip.condition2": "_최초_ _경계_보다 높을 경우", + "block.create.stockswitch.tooltip.behaviour2": "최소 경계에 다시 도달할 때까지 레드스톤 신호를 보냅니다.", + "block.create.stockswitch.tooltip.control1": "우클릭했을 때", + "block.create.stockswitch.tooltip.action1": "설정 창을 엽니다.", + + "block.create.redstone_bridge.tooltip": "REDSTONE LINK", + "block.create.redstone_bridge.tooltip.summary": "_무선_ 레드스톤 단말기입니다. 아무 아이템으로 두 개의 _주파수_를 설정할 수 있습니다. 통신거리는 제한되어 있지만, 그래도 충분히 넓습니다.", + "block.create.redstone_bridge.tooltip.condition1": "신호를 줄 때", + "block.create.redstone_bridge.tooltip.behaviour1": "같은 주파주의 다른 단말기에서 레드스톤 신호를 받습니다.", + "block.create.redstone_bridge.tooltip.control1": "아이템을 들고 우클릭", + "block.create.redstone_bridge.tooltip.action1": "그 아이템으로 주파수를 설정합니다. 주파수는 최대 두가지 아이템 조합으로 이룰 수 있습니다.", + "block.create.redstone_bridge.tooltip.control2": "웅크린 상태에서 우클릭", + "block.create.redstone_bridge.tooltip.action2": "수신/발신 모드로 바꿉니다.", + + "block.create.contact.tooltip": "REDSTONE CONTACT", + "block.create.contact.tooltip.summary": "_한_ _쌍_이 _서로_ _바라보고_ 있을 때 레드스톤 신호를 보냅니다. 베어링이나 기계식 피스톤으로 움직여집니다.", + "block.create.contact.tooltip.condition1": "다른 동형 감지기를 맞댈 때", + "block.create.contact.tooltip.behaviour1": "레드스톤 신호를 보냅니다.", + "block.create.contact.tooltip.condition2": "움직일 때", + "block.create.contact.tooltip.behaviour2": "지나가는 모든 고정된 동형 감지기를 작동시킵니다.", + + "block.create.flexcrate.tooltip": "ADJUSTABLE CRATE", + "block.create.flexcrate.tooltip.summary": "이 저장소는 용량을 _직접_ _정할_ 수 있습니다. 아무아이템이나 최대 16스택씩 담을 수 있습니다. 레드스톤 비교기와 호환됩니다.", + "block.create.flexcrate.tooltip.control1": "우클릭 했을 때", + "block.create.flexcrate.tooltip.action1": "창을 엽니다.", + + "block.create.extractor.tooltip": "EXTRACTOR", + "block.create.extractor.tooltip.summary": "_연결된_ _인벤토리_로부터 아이템을 꺼내 땅에 떨어뜨립니다. 공간이 비지 않았다면 아이템을 떨어뜨리지 않습니다. 개수/필터를 설정 가능합니다.", + "block.create.extractor.tooltip.condition1": "레드스톤 신호를 받았을 때", + "block.create.extractor.tooltip.behaviour1": "추출기를 _멈춥니다_.", + "block.create.extractor.tooltip.condition2": "움직이는 벨트에 연결되었을 때", + "block.create.extractor.tooltip.behaviour2": "추출기는 _황동_ _케이스_가 장착된 _벨트_에서 아이템을 빼낼 수 있습니다. 추출기가 막혔을 때는, 벨트가 _멈춥니다_.", + "block.create.extractor.tooltip.control1": "필터 슬롯을 우클릭할 때", + "block.create.extractor.tooltip.action1": "현재 들고있는 아이템의 개수 혹은 필터 틀로 필터를 정합니다. 추출기는 필터 설정에 맞춰 아이템을 빼낼 것입니다.", + + "block.create.transposer.tooltip": "TRANSPOSER", + "block.create.transposer.tooltip.summary": "연결된 인벤토리로부터 대상 인벤토리로 아이템을 _바로_ _이동_시킵니다. 개수/필터를 설정 가능합니다.", + "block.create.transposer.tooltip.condition1": "레드스톤 신호를 받았을 때", + "block.create.transposer.tooltip.behaviour1": "트랜스포저를 _멈춥니다_.", + "block.create.transposer.tooltip.condition2": "움직이는 벨트에 연결되었을 때", + "block.create.transposer.tooltip.behaviour2": "트랜스포저는 _황동_ _케이스_가 장착된 _벨트_에서 아이템을 빼낼 수 있습니다. 추출기가 막혔을 때는, 벨트가 _멈춥니다_.", + "block.create.transposer.tooltip.control1": "필터 슬롯을 우클릭할 때", + "block.create.transposer.tooltip.action1": "현재 들고있는 아이템의 개수 혹은 필터 틀로 필터를 정합니다. 트랜스포저는 필터 설정에 맞춰 아이템을 빼낼 것입니다.", + + "block.create.deployer.tooltip": "DEPLOYER", + "block.create.deployer.tooltip.summary": " _때리고_, _사용하고_ _작동시킵니다_. 이 장치는 _플레이어_를 가능한 한 _흉내내려할_ _것입니다_. 주변 인벤토리에서 아이템을 쓰거나 넣을 수 있습니다. 필터로 사용하는 아이템을 설정할 수 있습니다.", + "block.create.deployer.tooltip.condition1": "회전될 때", + "block.create.deployer.tooltip.behaviour1": "팔을 늘려 한 칸앞에 있는 공간에서 행동합니다.", + "block.create.deployer.tooltip.condition2": "렌치로 우클릭", + "block.create.deployer.tooltip.behaviour2": "_펀치_ _모드_로 바꿉니다. 이 상태에서는 배포기가 아이템을 가지고 _부수거나_ _때리려고_ 할 것입니다.", + + "block.create.linked_extractor.tooltip": "LINKED EXTRACTOR", + "block.create.linked_extractor.tooltip.summary": "_연결된_ _인벤토리_로부터 아이템을 꺼내 땅에 떨어뜨립니다. 공간이 비지 않았다면 아이템을 떨어뜨리지 않습니다. 개수/필터를 설정 가능합니다. 레드스톤 링크를 통해 _무선으로_ 컨트롤 될 수 있습니다.", + "block.create.linked_extractor.tooltip.condition1": "레드스톤 링크 신호를 받았을 때", + "block.create.linked_extractor.tooltip.behaviour1": "추출기를 _멈춥니다_.", + "block.create.linked_extractor.tooltip.control1": "필터 슬롯을 우클릭할 때", + "block.create.linked_extractor.tooltip.action1": "현재 들고있는 아이템의 개수 혹은 필터 틀로 필터를 정합니다. 추출기는 필터 설정에 맞춰 아이템을 빼낼 것입니다.", + "block.create.linked_extractor.tooltip.control2": "아이템을 들고 주파수 슬롯을 우클릭", + "block.create.linked_extractor.tooltip.action2": "그 아이템으로 주파수를 설정합니다. _같은_ _주파수_의 레드스톤 링크가 신호를 보낸다면, 추출기는 멈출 것입니다.", + + "block.create.linked_transposer.tooltip": "LINKED TRANSPOSER", + "block.create.linked_transposer.tooltip.summary": "연결된 인벤토리로부터 대상 인벤토리로 아이템을 _바로_ _이동_시킵니다. 개수/필터를 설정 가능합니다. 레드스톤 링크를 통해 _무선으로_ 컨트롤 될 수 있습니다.", + "block.create.linked_transposer.tooltip.condition1": "레드스톤 링크 신호를 받았을 때", + "block.create.linked_transposer.tooltip.behaviour1": "트랜스포저를 _멈춥니다_.", + "block.create.linked_transposer.tooltip.control1": "필터 슬롯을 우클릭할 때", + "block.create.linked_transposer.tooltip.action1": "현재 들고있는 아이템의 개수 혹은 필터 틀로 필터를 정합니다. 트랜스포저는 필터 설정에 맞춰 아이템을 빼낼 것입니다.", + "block.create.linked_transposer.tooltip.control2": "아이템을 들고 주파수 슬롯을 우클릭", + "block.create.linked_transposer.tooltip.action2": "그 아이템으로 주파수를 설정합니다. _같은_ _주파수_의 레드스톤 링크가 신호를 보낸다면, 트랜스포저는 멈출 것입니다.", + + "block.create.belt_funnel.tooltip": "FUNNEL", + "block.create.belt_funnel.tooltip.summary": "들어오는 아이템을 가능하면 _연결된_ _인벤토리_에 넣습니다. _벨트_ _위_의 아이템도 끌어올 수 있습니다.", + "block.create.belt_funnel.tooltip.condition1": "움직이는 벨트위에 있을 때", + "block.create.belt_funnel.tooltip.behaviour1": "_벨트_의 _중간_, _끝부분_에서 아이템을 끌어올 수 있습니다. 중간에 설치된 깔때기가 _정체_되었을 땐, 벨트가 _멈춥니다_.", + + "block.create.belt_tunnel.tooltip": "BELT TUNNEL", + "block.create.belt_tunnel.tooltip.summary": "벽을 통과하는 컨베이어 벨트를 _꾸미는_ 옵션 중 하나입니다. 벨트는 _황동_ _케이스_가 장착되어 있어야합니다. 터널은 다른 벨트 라인의 터널과 _동기화_되어 모든 터널이 _같은_ _타이밍_에 아이템을 들어오게 만들 수 있습니다. [Ctrl를 누르세요]", + "block.create.belt_tunnel.tooltip.control1": "전면에 렌치로 우클릭", + "block.create.belt_tunnel.tooltip.action1": "동기화 모드를 킵니다. 동기화된 터널은 다른 동기화된 터널들이 아이템을 인식할 때까지 아이템을 통과시키지 않습니다.", + "block.create.belt_tunnel.tooltip.control2": "륵면을 우클릭", + "block.create.belt_tunnel.tooltip.action2": "터널 측면에 창문이 있다면 창문 셔터를 조절합니다.", + + "block.create.brass_casing.tooltip": "BRASS CASING", + "block.create.brass_casing.tooltip.summary": "다양한 용도가 있는 단단한 기계 케이스입니다. 꾸미는 용도로도 사용 가능합니다.", + "block.create.brass_casing.tooltip.condition1": "컨베이어 벨트에 사용할 때", + "block.create.brass_casing.tooltip.behaviour1": "벨트 밑 부분에 황동 케이스를 씌웁니다. 이 상태에선 _벨트_ _터널_, _추출기_, _깔대기_, _트랜스포저_를 벨트 _측면_, _바닥면_에 연결할 수 있습니다.", + + "block.create.entity_detector.tooltip": "BELT OBSERVER", + "block.create.entity_detector.tooltip.summary": "컨베이어 벨트위를 _지나가는_ _엔티티_나 _아이템_을 감지합니다. 렌치를 이용해 _감지시_ _행동_을 바꿉니다. 필터를 설정할 수 있습니다.", + "block.create.entity_detector.tooltip.condition1": "감지 모드", + "block.create.entity_detector.tooltip.behaviour1": "감지기 앞에 아이템이 _지나가는_ _동안_ 레드스톤 신호를 줍니다.", + "block.create.entity_detector.tooltip.condition2": "펄스 모드", + "block.create.entity_detector.tooltip.behaviour2": "감지기 앞에 아이템이 _지나갈_ _때_ 레드스톤 신호를 _1틱_ 줍니다.", + "block.create.entity_detector.tooltip.condition3": "사출 모드", + "block.create.entity_detector.tooltip.behaviour3": "옆으로 아이템을 _밀어냅니다_. 벨트나 밀어내는 공간이 _정체_되어 있다면, 아이템은 감지기 앞에서 _멈춥니다_.", + "block.create.entity_detector.tooltip.condition4": "분리 모드", + "block.create.entity_detector.tooltip.behaviour4": "아이템의 _수_를 _반으로_ _나누어_ 반은 벨트 옆으로 내보냅니다.", + + "block.create.pulse_repeater.tooltip": "PULSE REPEATER", + "block.create.pulse_repeater.tooltip.summary": "_1틱_의 레드스톤 신호를 보내는 간단한 리피터입니다.", + + "block.create.flexpeater.tooltip": "FLEX REPEATER", + "block.create.flexpeater.tooltip.summary": "최대 30분까지 _딜레이_를 설정할 수 있는 업그레이드된 _레드스톤_ _리피터_입니다.", + + "block.create.flexpulsepeater.tooltip": "FLEX PULSE REPEATER", + "block.create.flexpulsepeater.tooltip.summary": "최대 30분까지 _딜레이_를 설정할 수 있는 _펄스_ _리피터_입니다.", + + "block.create.analog_lever.tooltip": "ANALOG LEVER", + "block.create.analog_lever.tooltip.summary": "레드스톤 _신호_ _세기_를 자세히 _조정_할 수 있는 레버입니다.", + + "block.create.toggle_latch.tooltip": "POWERED TOGGLE LATCH", + "block.create.toggle_latch.tooltip.summary": "레드스톤 신호로 끄고 켤 수 있는 _레버_입니다.", + + "block.create.redstone_latch.tooltip": "POWERED LATCH", + "block.create.redstone_latch.tooltip.summary": "레드스톤 신호로 컨트롤 할 수 있는 _레버_입니다. 후면에서 들어오는 신호는 레버를 키고, 측면에서 들어오는 신호는 레버를 초기화합니다.", + + "block.create.speed_gauge.tooltip": "SPEEDOMETER", + "block.create.speed_gauge.tooltip.summary": "연결된 장치의 _회전_ _속도_를 _계측_하고 _나타냅니다_. 레드스톤 비교기와 호환됩니다.", + "block.create.speed_gauge.tooltip.condition1": "회전될 때", + "block.create.speed_gauge.tooltip.behaviour1": "속도에 따라 색깔을 나타냅니다. _초록색_은 _느림_을, _파랑색_은 _보통_, _보라색_은 _빠른_ _속도_를 나타냅니다. 몇몇 장치들은 작동하기 위해 일정수준 이상의 속도가 필요합니다.", + + "block.create.stress_gauge.tooltip": "STRESSOMETER", + "block.create.stress_gauge.tooltip.summary": "연결된 네트워크의 _전체_ _피로도_ _수치_를 _계측_하고 _나타냅니다_. 레드스톤 비교기와 호환됩니다.", + "block.create.stress_gauge.tooltip.condition1": "회전될 때", + "block.create.stress_gauge.tooltip.behaviour1": "피로도에 따라 색깔을 나타냅니다. _과부화된_ _네트워크_는 움직이는 것을 멈춥니다. 과부하는 네트워크에 _추가_ _피로도_ _용량_을 가진 장치를 설치하면 해결됩니다. ", + + "tool.create.sand_paper.tooltip": "SAND PAPER", + "tool.create.sand_paper.tooltip.summary": "재료를 _사포질_ 하기위한 거친 종이입니다. 배포기를 통해 자동으로 쓰일 수 있습니다.", + "tool.create.sand_paper.tooltip.condition1": "사용할 때", + "tool.create.sand_paper.tooltip.behaviour1": "_반대_ _손_에 있는, 혹은 _바닥에_ _있는_ 아이템을 사포질 합니다.", + + "item.create.refined_radiance.tooltip": "REFINED RADIANCE", + "item.create.refined_radiance.tooltip.summary": "_흡수된_ _빛_으로 제련된 색채 혼합물입니다.", + + "item.create.shadow_steel.tooltip": "SHADOW STEEL", + "item.create.shadow_steel.tooltip.summary": "_공허_에서 제련된 색채 혼합물입니다.", + + "item.create.slot_cover.tooltip": "SLOT COVER", + "item.create.slot_cover.tooltip.summary": "기계 조합기에서 _빈_ _슬롯_을 표시하기 위해 쓰입니다. 조합기들은 정사각형 모양을 형성할 필요는 없습니다. 재료가 서로 대각선인 조합법이있을 때 유용합니다.", + + "tool.create.shadow_steel.tooltip": "SHADOW STEEL TOOLS", + "tool.create.shadow_steel.tooltip.summary": "블럭, 엔티티에서 나오는 아이템을 _없애버리는_ 빠르고 강력한 도구입니다. _약탈_ 마법부여에 따라 몬스터은 _더_ _많은_ _경험치_를 줍니다.", + + "tool.create.blazing.tooltip": "BLAZING TOOLS", + "tool.create.blazing.tooltip.summary": "이 도구는 블럭을 _녹이고_ 몬스터에게 _불_을 붙입니다. _지옥_에서는 내구도가 닳지 않습니다.", + + "tool.create.rose_quartz.tooltip": "ROSE QUARTZ TOOLS", + "tool.create.rose_quartz.tooltip.summary": "이 도구를 사용하면 _도구의_ _사거리_와 _다른_ _손_ _사거리_가 증가합니다.", + + "itemGroup.create": "Create" +} From 76f81910c406422867896b5275e52a9820204a2e Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Mon, 27 Apr 2020 14:44:57 +0200 Subject: [PATCH 06/11] SGS hotfix - Fixed Sequenced Gearshift crashing when removing instructions while active --- .../advanced/sequencer/SequencedGearshiftTileEntity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java index b50f20dbd..26453997c 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java @@ -50,6 +50,8 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity { Instruction instruction = getInstruction(currentInstruction); if (instruction == null) return; + if (getSpeed() == 0) + run(-1); // Update instruction time with regards to new speed float initialProgress = timer / (float) currentInstructionDuration; @@ -68,6 +70,8 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity { world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, 0), 3); return; } + if (getSpeed() == 0) + return; run(0); } @@ -122,6 +126,8 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity { } public int getModifier() { + if (currentInstruction >= instructions.size()) + return 0; return isIdle() ? 0 : instructions.get(currentInstruction).getSpeedModifier(); } From 45897e4c1820c7e7eb00ebf8f406c19a4d6db4f5 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 29 Apr 2020 19:12:42 +0200 Subject: [PATCH 07/11] Mechanical Ploughs - Added the Mechanical Plough - Mounted Drills now briefly stall a contraption after breaking a block below falling blocks (sand, gravel, etc) - Mechanical Saws can now harvest Bamboo, Chorus, Kelp, Sugar Cane, Cactus, Melons and Pumpkins - Fixed harvester position inconsistency when moved vertically - Fixed saws/drills not hurting entities in some cases - Fixed saws/drill throwing back hurt entities in weird directions --- .../java/com/simibubi/create/AllBlocks.java | 4 +- .../create/foundation/utility/TreeCutter.java | 63 ++++++++++ .../components/actors/AttachedActorBlock.java | 60 ++++++++++ .../BlockBreakingMovementBehaviour.java | 90 ++++++++++---- .../actors/DrillMovementBehaviour.java | 10 +- .../components/actors/HarvesterBlock.java | 59 +-------- .../actors/HarvesterMovementBehaviour.java | 2 +- .../components/actors/PloughBlock.java | 34 ++++++ .../actors/PloughMovementBehaviour.java | 88 ++++++++++++++ .../actors/SawMovementBehaviour.java | 8 +- .../contraptions/BlockMovementTraits.java | 5 +- .../components/saw/SawTileEntity.java | 32 ++++- .../assets/create/blockstates/plough.json | 14 +++ .../resources/assets/create/lang/en_us.json | 12 +- .../assets/create/models/block/plough.json | 113 ++++++++++++++++++ .../assets/create/models/item/plough.json | 3 + .../create/loot_tables/blocks/plough.json | 19 +++ .../crafting_shaped/contraptions/plough.json | 29 +++++ 18 files changed, 550 insertions(+), 95 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/actors/AttachedActorBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java create mode 100644 src/main/resources/assets/create/blockstates/plough.json create mode 100644 src/main/resources/assets/create/models/block/plough.json create mode 100644 src/main/resources/assets/create/models/item/plough.json create mode 100644 src/main/resources/data/create/loot_tables/blocks/plough.json create mode 100644 src/main/resources/data/create/recipes/crafting_shaped/contraptions/plough.json diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 9cb2e32ff..10cde1866 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -14,6 +14,7 @@ import com.simibubi.create.modules.IModule; import com.simibubi.create.modules.contraptions.CasingBlock; import com.simibubi.create.modules.contraptions.components.actors.DrillBlock; import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock; +import com.simibubi.create.modules.contraptions.components.actors.PloughBlock; import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.modules.contraptions.components.clock.CuckooClockBlock; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock; @@ -162,9 +163,10 @@ public enum AllBlocks { ROTATION_CHASSIS(new RadialChassisBlock()), DRILL(new DrillBlock()), SAW(new SawBlock()), - HARVESTER(new HarvesterBlock()), DEPLOYER(new DeployerBlock()), PORTABLE_STORAGE_INTERFACE(new PortableStorageInterfaceBlock()), + PLOUGH(new PloughBlock()), + HARVESTER(new HarvesterBlock()), ANALOG_LEVER(new AnalogLeverBlock()), ANDESITE_CASING(new CasingBlock("andesite_casing")), diff --git a/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java index 7635aa7bc..5849c8625 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.utility; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -8,8 +9,16 @@ import java.util.Set; import com.google.common.base.Predicates; +import net.minecraft.block.BambooBlock; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.CactusBlock; +import net.minecraft.block.ChorusFlowerBlock; +import net.minecraft.block.ChorusPlantBlock; +import net.minecraft.block.KelpBlock; +import net.minecraft.block.KelpTopBlock; import net.minecraft.block.LeavesBlock; +import net.minecraft.block.SugarCaneBlock; import net.minecraft.tags.BlockTags; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -40,6 +49,41 @@ public class TreeCutter { Set visited = new HashSet<>(); List frontier = new LinkedList<>(); + // Bamboo, Sugar Cane, Cactus + BlockState stateAbove = reader.getBlockState(pos.up()); + if (isVerticalPlant(stateAbove)) { + logs.add(pos.up()); + for (int i = 1; i < 256; i++) { + BlockPos current = pos.up(i); + if (!isVerticalPlant(reader.getBlockState(current))) + break; + logs.add(current); + } + Collections.reverse(logs); + return new Tree(logs, leaves); + } + + // Chorus + if (isChorus(stateAbove)) { + frontier.add(pos.up()); + while (!frontier.isEmpty()) { + BlockPos current = frontier.remove(0); + visited.add(current); + logs.add(current); + for (Direction direction : Iterate.directions) { + BlockPos offset = current.offset(direction); + if (visited.contains(offset)) + continue; + if (!isChorus(reader.getBlockState(offset))) + continue; + frontier.add(offset); + } + } + Collections.reverse(logs); + return new Tree(logs, leaves); + } + + // Regular Tree if (!validateCut(reader, pos)) return null; @@ -94,6 +138,25 @@ public class TreeCutter { return new Tree(logs, leaves); } + public static boolean isChorus(BlockState stateAbove) { + return stateAbove.getBlock() instanceof ChorusPlantBlock || stateAbove.getBlock() instanceof ChorusFlowerBlock; + } + + public static boolean isVerticalPlant(BlockState stateAbove) { + Block block = stateAbove.getBlock(); + if (block instanceof BambooBlock) + return true; + if (block instanceof CactusBlock) + return true; + if (block instanceof SugarCaneBlock) + return true; + if (block instanceof KelpBlock) + return true; + if (block instanceof KelpTopBlock) + return true; + return false; + } + /** * Checks whether a tree was fully cut by seeing whether the layer above the cut * is not supported by any more logs. diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/AttachedActorBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/AttachedActorBlock.java new file mode 100644 index 000000000..c738f69b1 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/AttachedActorBlock.java @@ -0,0 +1,60 @@ +package com.simibubi.create.modules.contraptions.components.actors; + +import com.simibubi.create.foundation.utility.AllShapes; +import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.HorizontalBlock; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorldReader; + +public abstract class AttachedActorBlock extends HorizontalBlock implements IPortableBlock { + + public AttachedActorBlock() { + super(Properties.from(Blocks.IRON_BLOCK)); + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + Direction direction = state.get(HORIZONTAL_FACING); + return AllShapes.HARVESTER_BASE.get(direction); + } + + @Override + protected void fillStateContainer(Builder builder) { + builder.add(HORIZONTAL_FACING); + super.fillStateContainer(builder); + } + + @Override + public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { + Direction direction = state.get(HORIZONTAL_FACING); + BlockPos offset = pos.offset(direction.getOpposite()); + return Block.hasSolidSide(worldIn.getBlockState(offset), worldIn, offset, direction); + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + Direction facing; + if (context.getFace().getAxis().isVertical()) + facing = context.getPlacementHorizontalFacing().getOpposite(); + else { + BlockState blockState = + context.getWorld().getBlockState(context.getPos().offset(context.getFace().getOpposite())); + if (blockState.getBlock() instanceof AttachedActorBlock) + facing = blockState.get(HORIZONTAL_FACING); + else + facing = context.getFace(); + } + return getDefaultState().with(HORIZONTAL_FACING, facing); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java index c7c2ef8af..438c17094 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java @@ -6,9 +6,11 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Movement import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import net.minecraft.block.BlockState; +import net.minecraft.block.FallingBlock; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; import net.minecraft.util.DamageSource; @@ -32,30 +34,10 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { World world = context.world; BlockState stateVisited = world.getBlockState(pos); + if (!stateVisited.isNormalCube(world, pos)) + damageEntities(context, pos, world); if (world.isRemote) return; - if (stateVisited.getCollisionShape(world, pos).isEmpty()) { - DamageSource damageSource = getDamageSource(); - if (damageSource == null) - return; - for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) { - - if (entity instanceof ItemEntity) - return; - if (entity instanceof ContraptionEntity) - return; - if (entity instanceof AbstractMinecartEntity) - for (Entity passenger : entity.getRecursivePassengers()) - if (passenger instanceof ContraptionEntity - && ((ContraptionEntity) passenger).getContraption() == context.contraption) - return; - - float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20); - entity.attackEntityFrom(damageSource, damage); - entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3))); - } - return; - } if (!canBreak(world, pos, stateVisited)) return; @@ -63,10 +45,39 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { context.stall = true; } + public void damageEntities(MovementContext context, BlockPos pos, World world) { + DamageSource damageSource = getDamageSource(); + if (damageSource == null && !throwsEntities()) + return; + Entities: for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) { + if (entity instanceof ItemEntity) + continue; + if (entity instanceof ContraptionEntity) + continue; + if (entity instanceof AbstractMinecartEntity) + for (Entity passenger : entity.getRecursivePassengers()) + if (passenger instanceof ContraptionEntity + && ((ContraptionEntity) passenger).getContraption() == context.contraption) + continue Entities; + + float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20); + if (damageSource != null && !world.isRemote) + entity.attackEntityFrom(damageSource, damage); + if (throwsEntities() && (world.isRemote == (entity instanceof PlayerEntity))) { + entity.setMotion(entity.getMotion().add(context.motion.add(0, context.motion.length() / 4f, 0))); + entity.velocityChanged = true; + } + } + } + protected DamageSource getDamageSource() { return null; } + protected boolean throwsEntities() { + return getDamageSource() != null; + } + @Override public void stopMoving(MovementContext context) { CompoundNBT data = context.data; @@ -89,6 +100,27 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { @Override public void tick(MovementContext context) { + tickBreaker(context); + + CompoundNBT data = context.data; + if (!data.contains("WaitingTicks")) + return; + + int waitingTicks = data.getInt("WaitingTicks"); + if (waitingTicks-- > 0) { + data.putInt("WaitingTicks", waitingTicks); + context.stall = true; + return; + } + + BlockPos pos = NBTUtil.readBlockPos(data.getCompound("LastPos")); + data.remove("WaitingTicks"); + data.remove("LastPos"); + context.stall = false; + visitNewPosition(context, pos); + } + + public void tickBreaker(MovementContext context) { CompoundNBT data = context.data; if (context.world.isRemote) return; @@ -129,13 +161,13 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { if (destroyProgress >= 10) { BlockHelper.destroyBlock(context.world, breakingPos, 1f, stack -> this.dropItem(context, stack)); - onBlockBroken(context, breakingPos); + context.stall = false; + onBlockBroken(context, breakingPos, stateToBreak); ticksUntilNextProgress = -1; world.sendBlockBreakProgress(id, breakingPos, -1); data.remove("Progress"); data.remove("TicksUntilNextProgress"); data.remove("BreakingPos"); - context.stall = false; return; } @@ -150,7 +182,15 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { return BlockBreakingKineticTileEntity.isBreakable(state, blockHardness); } - protected void onBlockBroken(MovementContext context, BlockPos pos) { + protected void onBlockBroken(MovementContext context, BlockPos pos, BlockState brokenState) { + BlockState above = context.world.getBlockState(pos.up()); + if (!(above.getBlock() instanceof FallingBlock)) + return; + + CompoundNBT data = context.data; + data.putInt("WaitingTicks", 10); + data.put("LastPos", NBTUtil.writeBlockPos(pos)); + context.stall = true; } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java index 9fdc5a399..be4ff48b1 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/DrillMovementBehaviour.java @@ -4,8 +4,11 @@ import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; +import net.minecraft.block.BlockState; import net.minecraft.util.DamageSource; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -27,10 +30,15 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour { public SuperByteBuffer renderInContraption(MovementContext context) { return DrillTileEntityRenderer.renderInContraption(context); } - + @Override protected DamageSource getDamageSource() { return DrillBlock.damageSourceDrill; } + @Override + public boolean canBreak(World world, BlockPos breakingPos, BlockState state) { + return super.canBreak(world, breakingPos, state) && !state.getCollisionShape(world, breakingPos).isEmpty(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java index 0ed7177f3..c2f00dc68 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterBlock.java @@ -1,34 +1,17 @@ package com.simibubi.create.modules.contraptions.components.actors; -import com.simibubi.create.AllBlocks; -import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock; import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.HorizontalBlock; -import net.minecraft.block.material.PushReaction; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.state.StateContainer.Builder; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorldReader; -public class HarvesterBlock extends HorizontalBlock implements IPortableBlock { +public class HarvesterBlock extends AttachedActorBlock implements IPortableBlock { public static MovementBehaviour MOVEMENT = new HarvesterMovementBehaviour(); - public HarvesterBlock() { - super(Properties.from(Blocks.IRON_BLOCK)); - } - @Override public boolean hasTileEntity(BlockState state) { return true; @@ -39,51 +22,11 @@ public class HarvesterBlock extends HorizontalBlock implements IPortableBlock { return new HarvesterTileEntity(); } - @Override - public PushReaction getPushReaction(BlockState state) { - return PushReaction.PUSH_ONLY; - } - - @Override - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - Direction direction = state.get(HORIZONTAL_FACING); - return AllShapes.HARVESTER_BASE.get(direction); - } - - @Override - protected void fillStateContainer(Builder builder) { - builder.add(HORIZONTAL_FACING); - super.fillStateContainer(builder); - } - @Override public BlockRenderLayer getRenderLayer() { return BlockRenderLayer.CUTOUT; } - @Override - public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { - Direction direction = state.get(HORIZONTAL_FACING); - BlockPos offset = pos.offset(direction.getOpposite()); - return Block.hasSolidSide(worldIn.getBlockState(offset), worldIn, offset, direction); - } - - @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - Direction facing; - if (context.getFace().getAxis().isVertical()) - facing = context.getPlacementHorizontalFacing().getOpposite(); - else { - BlockState blockState = - context.getWorld().getBlockState(context.getPos().offset(context.getFace().getOpposite())); - if (AllBlocks.HARVESTER.typeOf(blockState)) - facing = blockState.get(HORIZONTAL_FACING); - else - facing = context.getFace(); - } - return getDefaultState().with(HORIZONTAL_FACING, facing); - } - @Override public MovementBehaviour getMovementBehaviour() { return MOVEMENT; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java index 2f3bfe2b0..83a8548b4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/HarvesterMovementBehaviour.java @@ -42,7 +42,7 @@ public class HarvesterMovementBehaviour extends MovementBehaviour { @Override public Vec3d getActiveAreaOffset(MovementContext context) { - return new Vec3d(context.state.get(HORIZONTAL_FACING).getDirectionVec()).scale(.5); + return new Vec3d(context.state.get(HORIZONTAL_FACING).getDirectionVec()).scale(.45); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughBlock.java new file mode 100644 index 000000000..9c263de6c --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughBlock.java @@ -0,0 +1,34 @@ +package com.simibubi.create.modules.contraptions.components.actors; + +import java.util.UUID; + +import com.mojang.authlib.GameProfile; +import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; + +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.common.util.FakePlayer; + +public class PloughBlock extends AttachedActorBlock { + + public static MovementBehaviour MOVEMENT = new PloughMovementBehaviour(); + + @Override + public MovementBehaviour getMovementBehaviour() { + return MOVEMENT; + } + + /** + * The OnHoeUse event takes a player, so we better not pass null + */ + static class PloughFakePlayer extends FakePlayer { + + public static final GameProfile PLOUGH_PROFILE = + new GameProfile(UUID.fromString("9e2faded-eeee-4ec2-c314-dad129ae971d"), "Plough"); + + public PloughFakePlayer(ServerWorld world) { + super(world, PLOUGH_PROFILE); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java new file mode 100644 index 000000000..24b57f619 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java @@ -0,0 +1,88 @@ +package com.simibubi.create.modules.contraptions.components.actors; + +import static net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING; + +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.components.actors.PloughBlock.PloughFakePlayer; +import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; + +import net.minecraft.block.BlockState; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; +import net.minecraft.item.Items; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.RayTraceContext; +import net.minecraft.util.math.RayTraceContext.BlockMode; +import net.minecraft.util.math.RayTraceContext.FluidMode; +import net.minecraft.util.math.RayTraceResult.Type; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; + +public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour { + + @Override + public boolean isActive(MovementContext context) { + return !VecHelper.isVecPointingTowards(context.relativeMotion, + context.state.get(HORIZONTAL_FACING).getOpposite()); + } + + @Override + public void visitNewPosition(MovementContext context, BlockPos pos) { + super.visitNewPosition(context, pos); + + World world = context.world; + if (world.isRemote) + return; + BlockPos below = pos.down(); + if (!world.isBlockPresent(below)) + return; + + Vec3d vec = VecHelper.getCenterOf(pos); + PloughFakePlayer player = getPlayer(context); + + if (player == null) + return; + + BlockRayTraceResult ray = world + .rayTraceBlocks(new RayTraceContext(vec, vec.add(0, -1, 0), BlockMode.OUTLINE, FluidMode.NONE, player)); + if (ray == null || ray.getType() != Type.BLOCK) + return; + + ItemUseContext ctx = new ItemUseContext(player, Hand.MAIN_HAND, ray); + new ItemStack(Items.DIAMOND_HOE).onItemUse(ctx); + } + + @Override + public Vec3d getActiveAreaOffset(MovementContext context) { + return new Vec3d(context.state.get(HORIZONTAL_FACING).getDirectionVec()).scale(.45); + } + + @Override + protected boolean throwsEntities() { + return true; + } + + @Override + public boolean canBreak(World world, BlockPos breakingPos, BlockState state) { + return state.getCollisionShape(world, breakingPos).isEmpty(); + } + + @Override + public void stopMoving(MovementContext context) { + if (context.temporaryData instanceof PloughFakePlayer) + ((PloughFakePlayer) context.temporaryData).remove(); + } + + private PloughFakePlayer getPlayer(MovementContext context) { + if (!(context.temporaryData instanceof PloughFakePlayer) && context.world instanceof ServerWorld) { + PloughFakePlayer player = new PloughFakePlayer((ServerWorld) context.world); + player.setHeldItem(Hand.MAIN_HAND, new ItemStack(Items.DIAMOND_HOE)); + context.temporaryData = player; + } + return (PloughFakePlayer) context.temporaryData; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java index 00071f5ea..4c0036de2 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/SawMovementBehaviour.java @@ -6,6 +6,7 @@ import com.simibubi.create.foundation.utility.TreeCutter.Tree; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import com.simibubi.create.modules.contraptions.components.saw.SawBlock; +import com.simibubi.create.modules.contraptions.components.saw.SawTileEntity; import net.minecraft.block.BlockState; import net.minecraft.entity.item.ItemEntity; @@ -31,12 +32,13 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public boolean canBreak(World world, BlockPos breakingPos, BlockState state) { - return super.canBreak(world, breakingPos, state) - && (state.isIn(BlockTags.LOGS) || state.isIn(BlockTags.LEAVES)); + return super.canBreak(world, breakingPos, state) && SawTileEntity.isSawable(state); } @Override - protected void onBlockBroken(MovementContext context, BlockPos pos) { + protected void onBlockBroken(MovementContext context, BlockPos pos, BlockState brokenState) { + if (brokenState.isIn(BlockTags.LEAVES)) + return; Tree tree = TreeCutter.cutTree(context.world, pos); if (tree != null) { for (BlockPos log : tree.logs) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java index 21ea16106..96e7419cb 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java @@ -1,6 +1,7 @@ package com.simibubi.create.modules.contraptions.components.contraptions; import com.simibubi.create.AllBlocks; +import com.simibubi.create.modules.contraptions.components.actors.AttachedActorBlock; import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock; import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock; @@ -175,7 +176,7 @@ public class BlockMovementTraits { return direction == (state.get(BlockStateProperties.HANGING) ? Direction.UP : Direction.DOWN); if (block instanceof AbstractRailBlock) return direction == Direction.DOWN; - if (block instanceof HarvesterBlock) + if (block instanceof AttachedActorBlock) return direction == state.get(HarvesterBlock.HORIZONTAL_FACING).getOpposite(); return false; } @@ -191,7 +192,7 @@ public class BlockMovementTraits { return state.get(BlockStateProperties.FACING) == facing; if (AllBlocks.PORTABLE_STORAGE_INTERFACE.typeOf(state)) return state.get(PortableStorageInterfaceBlock.FACING) == facing; - if (AllBlocks.HARVESTER.typeOf(state)) + if (state.getBlock() instanceof AttachedActorBlock) return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing; if (AllBlocks.ROPE_PULLEY.typeOf(state)) return facing == Direction.DOWN; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java index fb695c9f8..34c08729e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java @@ -24,7 +24,15 @@ import com.simibubi.create.modules.contraptions.components.actors.BlockBreakingK import com.simibubi.create.modules.contraptions.processing.ProcessingInventory; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; +import net.minecraft.block.BambooBlock; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.CactusBlock; +import net.minecraft.block.ChorusPlantBlock; +import net.minecraft.block.KelpBlock; +import net.minecraft.block.KelpTopBlock; +import net.minecraft.block.StemGrownBlock; +import net.minecraft.block.SugarCaneBlock; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; @@ -379,7 +387,29 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { @Override public boolean canBreak(BlockState stateToBreak, float blockHardness) { - return super.canBreak(stateToBreak, blockHardness) && stateToBreak.isIn(BlockTags.LOGS); + boolean sawable = isSawable(stateToBreak); + return super.canBreak(stateToBreak, blockHardness) && sawable; + } + + public static boolean isSawable(BlockState stateToBreak) { + if (stateToBreak.isIn(BlockTags.LOGS) || stateToBreak.isIn(BlockTags.LEAVES)) + return true; + Block block = stateToBreak.getBlock(); + if (block instanceof BambooBlock) + return true; + if (block instanceof StemGrownBlock) + return true; + if (block instanceof CactusBlock) + return true; + if (block instanceof SugarCaneBlock) + return true; + if (block instanceof KelpBlock) + return true; + if (block instanceof KelpTopBlock) + return true; + if (block instanceof ChorusPlantBlock) + return true; + return false; } } diff --git a/src/main/resources/assets/create/blockstates/plough.json b/src/main/resources/assets/create/blockstates/plough.json new file mode 100644 index 000000000..1805fe595 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/plough.json @@ -0,0 +1,14 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "create:block/plough" + }, + "variants": { + "facing": { + "north": { "y": 180 }, + "south": {}, + "east": { "y": 270 }, + "west": { "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index b8b7668f5..6bb894769 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -99,6 +99,7 @@ "block.create.drill": "Mechanical Drill", "block.create.portable_storage_interface": "Portable Storage Interface", "block.create.harvester": "Mechanical Harvester", + "block.create.plough": "Mechanical Plough", "block.create.saw": "Mechanical Saw", "block.create.water_wheel": "Water Wheel", "block.create.mechanical_press": "Mechanical Press", @@ -986,16 +987,21 @@ "block.create.rotation_chassis.tooltip.action1": "Makes the clicked face _Sticky_. When Chassis move, all designated blocks attached to the sticky side are moved with it.", "block.create.drill.tooltip": "MECHANICAL DRILL", - "block.create.drill.tooltip.summary": "A mechanical device suitable for _breaking_ _blocks_. It is movable with _Mechanical_ _Pistons_ or _Bearings_.", + "block.create.drill.tooltip.summary": "A mechanical device suitable for _breaking_ _blocks_. It is movable with _Mechanical_ _Pistons_, _Bearings_ or other controllers.", "block.create.drill.tooltip.condition1": "When Rotated", "block.create.drill.tooltip.behaviour1": "Acts as a _stationary_ Block Breaker. Also _hurts_ _entities_ in its effective area.", "block.create.drill.tooltip.condition2": "While Moving", "block.create.drill.tooltip.behaviour2": "Breaks Blocks with which the drill collides.", "block.create.harvester.tooltip": "MECHANICAL HARVESTER", - "block.create.harvester.tooltip.summary": "A mechanical plant cutter suitable for medium scale crop automation. It is movable with _Mechanical_ _Pistons_ or _Bearings_.", + "block.create.harvester.tooltip.summary": "A mechanical plant cutter suitable for medium scale crop automation. It is movable with _Mechanical_ _Pistons_, _Bearings_ or other controllers.", "block.create.harvester.tooltip.condition1": "While Moving", "block.create.harvester.tooltip.behaviour1": "_Harvests_ all _mature_ _crops_ which which the blade collides and reset them to their initial growth state.", + + "block.create.plough.tooltip": "MECHANICAL PLOUGH", + "block.create.plough.tooltip.summary": "A mechanical plough has a variety of uses. It is movable with _Mechanical_ _Pistons_, _Bearings_ or other controllers.", + "block.create.plough.tooltip.condition1": "While Moving", + "block.create.plough.tooltip.behaviour1": "_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.saw.tooltip": "MECHANICAL SAW", "block.create.saw.tooltip.summary": "Suitable for _cutting_ _trees_ effectively and for _cutting_ _blocks_ into their carpentered counterparts. It is movable using _Mechanical_ _Pistons_ or _Bearings_.", @@ -1025,7 +1031,7 @@ "block.create.redstone_bridge.tooltip.action2": "Toggles between _Receiver_ and _Transmitter_ Mode.", "block.create.contact.tooltip": "REDSTONE CONTACT", - "block.create.contact.tooltip.summary": "Only emits redstone power in pairs. It is movable with _Mechanical_ _Pistons_ or _Bearings_.", + "block.create.contact.tooltip.summary": "Only emits redstone power in pairs. It is movable with _Mechanical_ _Pistons_, _Bearings_ or other controllers.", "block.create.contact.tooltip.condition1": "When facing other Contact", "block.create.contact.tooltip.behaviour1": "Provides a _Redstone_ _Signal_.", "block.create.contact.tooltip.condition2": "While Moving", diff --git a/src/main/resources/assets/create/models/block/plough.json b/src/main/resources/assets/create/models/block/plough.json new file mode 100644 index 000000000..9c678684d --- /dev/null +++ b/src/main/resources/assets/create/models/block/plough.json @@ -0,0 +1,113 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "1": "block/anvil", + "particle": "create:block/andesite_casing_short", + "andesite_casing_short": "create:block/andesite_casing_short" + }, + "elements": [ + { + "name": "Core", + "from": [0, 2, 0], + "to": [16, 14, 2.9], + "faces": { + "north": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "east": {"uv": [2, 0, 14, 3], "rotation": 270, "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "west": {"uv": [2, 0, 14, 3], "rotation": 90, "texture": "#andesite_casing_short"}, + "up": {"uv": [0, 0, 16, 2.9], "rotation": 180, "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 0, 16, 2.9], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Attachment", + "from": [0.1, 4, 6], + "to": [2, 7, 15], + "rotation": {"angle": 22.5, "axis": "x", "origin": [0, 10, 3]}, + "faces": { + "north": {"uv": [0, 0, 1.9, 3], "texture": "#andesite_casing_short"}, + "east": {"uv": [0, 0, 9, 3], "texture": "#andesite_casing_short"}, + "south": {"uv": [0.1, 8, 2, 11], "texture": "#andesite_casing_short"}, + "west": {"uv": [0, 0, 9, 3], "texture": "#andesite_casing_short"}, + "up": {"uv": [0, 4, 1.9, 13], "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 4, 1.9, 13], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Attachment", + "from": [2.1, 5, 5], + "to": [14, 6, 17], + "rotation": {"angle": 22.5, "axis": "x", "origin": [0, 10, 3]}, + "faces": { + "north": {"uv": [0, 0, 11.9, 1], "texture": "#andesite_casing_short"}, + "east": {"uv": [0, 0, 12, 1], "texture": "#1"}, + "south": {"uv": [2, 15, 13.9, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 12, 1], "texture": "#1"}, + "up": {"uv": [2, 2, 13.9, 14], "texture": "#1"}, + "down": {"uv": [2, 4, 13.9, 16], "texture": "#1"} + } + }, + { + "name": "Attachment", + "from": [14, 4, 6], + "to": [15.9, 7, 15], + "rotation": {"angle": 22.5, "axis": "x", "origin": [0, 10, 3]}, + "faces": { + "north": {"uv": [0, 0, 1.9, 3], "texture": "#andesite_casing_short"}, + "east": {"uv": [0, 0, 9, 3], "texture": "#andesite_casing_short"}, + "south": {"uv": [14, 8, 15.9, 11], "texture": "#andesite_casing_short"}, + "west": {"uv": [0, 0, 9, 3], "texture": "#andesite_casing_short"}, + "up": {"uv": [14, 4, 15.9, 13], "texture": "#andesite_casing_short"}, + "down": {"uv": [14, 4, 15.9, 13], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Attachment", + "from": [0, 4, 2.9], + "to": [16, 7, 6], + "rotation": {"angle": 0, "axis": "x", "origin": [0, 10, 2]}, + "faces": { + "north": {"uv": [0, 0, 16, 3], "texture": "#andesite_casing_short"}, + "east": {"uv": [0, 0, 3.1, 3], "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 0, 16, 3], "texture": "#andesite_casing_short"}, + "west": {"uv": [0, 0, 3.1, 3], "texture": "#andesite_casing_short"}, + "up": {"uv": [0, 0, 16, 3], "rotation": 180, "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 0, 16, 3], "texture": "#andesite_casing_short"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, -135, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, -135, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 45, 0], + "translation": [1, 0, 0], + "scale": [0.625, 0.625, 0.625] + }, + "fixed": { + "rotation": [0, 180, 0], + "translation": [0, 0, -4], + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/plough.json b/src/main/resources/assets/create/models/item/plough.json new file mode 100644 index 000000000..241430659 --- /dev/null +++ b/src/main/resources/assets/create/models/item/plough.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/plough" +} \ No newline at end of file diff --git a/src/main/resources/data/create/loot_tables/blocks/plough.json b/src/main/resources/data/create/loot_tables/blocks/plough.json new file mode 100644 index 000000000..3714a2487 --- /dev/null +++ b/src/main/resources/data/create/loot_tables/blocks/plough.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:plough" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crafting_shaped/contraptions/plough.json b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/plough.json new file mode 100644 index 000000000..9547e94b5 --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/plough.json @@ -0,0 +1,29 @@ +{ + "type": "crafting_shaped", + "pattern": [ + "III", + "AAA", + " C " + ], + "key": { + "C": { + "item": "create:andesite_casing" + }, + "I": { + "tag": "forge:plates/iron" + }, + "A": { + "item": "create:andesite_alloy" + } + }, + "result": { + "item": "create:plough", + "count": 1 + }, + "conditions": [ + { + "type": "create:module", + "module": "contraptions" + } + ] +} \ No newline at end of file From 885791f878a7693056342aab0b00b65c1a8a14cc Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 29 Apr 2020 23:32:17 +0200 Subject: [PATCH 08/11] Cart Rotation Lock - Minecart assemblers can now be configured to 3 different rotation modes --- .../com/simibubi/create/AllTileEntities.java | 2 + .../com/simibubi/create/ScreenResources.java | 3 + .../foundation/utility/AngleHelper.java | 8 +-- .../contraptions/ContraptionEntity.java | 45 ++++++++---- .../mounted/CartAssemblerBlock.java | 30 ++++++-- .../mounted/CartAssemblerTileEntity.java | 65 ++++++++++++++++++ .../mounted/MountedContraption.java | 22 +++++- .../resources/assets/create/lang/en_us.json | 4 ++ .../assets/create/textures/gui/icons.png | Bin 3955 -> 4163 bytes 9 files changed, 154 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerTileEntity.java diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 2ffc992a1..53519a6c0 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -15,6 +15,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.bearing. import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonTileEntityRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyRenderer; @@ -146,6 +147,7 @@ public enum AllTileEntities { SPEED_GAUGE(SpeedGaugeTileEntity::new, AllBlocks.SPEED_GAUGE), STRESS_GAUGE(StressGaugeTileEntity::new, AllBlocks.STRESS_GAUGE), ANALOG_LEVER(AnalogLeverTileEntity::new, AllBlocks.ANALOG_LEVER), + CART_ASSEMBLER(CartAssemblerTileEntity::new, AllBlocks.CART_ASSEMBLER), // Logistics REDSTONE_BRIDGE(RedstoneLinkTileEntity::new, AllBlocks.REDSTONE_BRIDGE), diff --git a/src/main/java/com/simibubi/create/ScreenResources.java b/src/main/java/com/simibubi/create/ScreenResources.java index 3270590ab..19f7f780a 100644 --- a/src/main/java/com/simibubi/create/ScreenResources.java +++ b/src/main/java/com/simibubi/create/ScreenResources.java @@ -133,6 +133,9 @@ public enum ScreenResources { I_MOVE_PLACE(9, 1), I_MOVE_PLACE_RETURNED(10, 1), I_MOVE_NEVER_PLACE(11, 1), + I_CART_ROTATE(12, 1), + I_CART_ROTATE_PAUSED(13, 1), + I_CART_ROTATE_LOCKED(14, 1), I_DONT_REPLACE(0, 2), I_REPLACE_SOLID(1, 2), diff --git a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java index 058c23c1e..580c4d3cb 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java @@ -19,16 +19,16 @@ public class AngleHelper { public static float rad(float angle) { return (float) (angle / 180 * Math.PI); } - + public static float deg(float angle) { return (float) (angle * 180 / Math.PI); } - - public static float angleLerp(float pct, float current, float target) { + + public static float angleLerp(float pct, float current, float target) { return current + getShortestAngleDiff(current, target) * pct; } - public static float getShortestAngleDiff(double current, double target) { + public static float getShortestAngleDiff(double current, double target) { current = current % 360; target = target % 360; return (float) (((((target - current) % 360) + 540) % 360) - 180); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index 6e4f01a95..2a0afc2a0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -12,8 +12,11 @@ import org.apache.commons.lang3.tuple.MutablePair; import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllEntities; import com.simibubi.create.AllPackets; +import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MountedContraption; import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity; import net.minecraft.block.material.PushReaction; @@ -156,6 +159,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public void tickAsPassenger(Entity e) { + boolean rotationLock = false; + boolean pauseWhileRotating = false; + + if (contraption instanceof MountedContraption) { + rotationLock = ((MountedContraption) contraption).rotationMode == CartMovementMode.ROTATION_LOCKED; + pauseWhileRotating = ((MountedContraption) contraption).rotationMode == CartMovementMode.ROTATE_PAUSED; + } + Entity riding = e; while (riding.getRidingEntity() != null) riding = riding.getRidingEntity(); @@ -163,20 +174,28 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (riding instanceof BoatEntity) movementVector = new Vec3d(posX - prevPosX, posY - prevPosY, posZ - prevPosZ); Vec3d motion = movementVector.normalize(); + boolean rotating = false; - if (motion.length() > 0) { - targetYaw = yawFromVector(motion); - if (targetYaw < 0) - targetYaw += 360; - if (yaw < 0) - yaw += 360; + if (!rotationLock) { + if (motion.length() > 0) { + targetYaw = yawFromVector(motion); + if (targetYaw < 0) + targetYaw += 360; + if (yaw < 0) + yaw += 360; + } + + prevYaw = yaw; + yaw = angleLerp(0.4f, yaw, targetYaw); + if (Math.abs(AngleHelper.getShortestAngleDiff(yaw, targetYaw)) < 1f) + yaw = targetYaw; + else + rotating = true; } - prevYaw = yaw; - yaw = angleLerp(0.4f, yaw, targetYaw); - boolean wasStalled = isStalled(); - tickActors(movementVector); + if (!rotating || !pauseWhileRotating) + tickActors(movementVector); if (isStalled()) { if (!wasStalled) motionBeforeStall = riding.getMotion(); @@ -434,8 +453,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } @Override - protected void doWaterSplashEffect() { - } + protected void doWaterSplashEffect() {} public void preventMovedEntitiesFromGettingStuck() { Vec3d stuckTest = new Vec3d(0, -2, 0); @@ -524,8 +542,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override // Make sure nothing can move contraptions out of the way - public void setMotion(Vec3d motionIn) { - } + public void setMotion(Vec3d motionIn) {} @Override public PushReaction getPushReaction() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java index d33f49619..a789eef59 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java @@ -1,10 +1,11 @@ package com.simibubi.create.modules.contraptions.components.contraptions.mounted; import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.RenderUtilityBlock; import com.simibubi.create.foundation.utility.AllShapes; -import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode; import net.minecraft.block.AbstractRailBlock; import net.minecraft.block.Block; @@ -19,6 +20,7 @@ import net.minecraft.state.IProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.RailShape; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; @@ -28,7 +30,7 @@ import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -public class CartAssemblerBlock extends AbstractRailBlock { +public class CartAssemblerBlock extends AbstractRailBlock implements ITE { public static IProperty RAIL_SHAPE = EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH); @@ -45,6 +47,16 @@ public class CartAssemblerBlock extends AbstractRailBlock { super.fillStateContainer(builder); } + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new CartAssemblerTileEntity(); + } + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { boolean alongX = context.getPlacementHorizontalFacing().getAxis() == Axis.X; @@ -72,12 +84,15 @@ public class CartAssemblerBlock extends AbstractRailBlock { if (!cart.getPassengers().isEmpty()) return; - Contraption contraption = MountedContraption.assembleMinecart(world, pos); + MountedContraption contraption = MountedContraption.assembleMinecart(world, pos); if (contraption == null) return; if (contraption.blocks.size() == 1) return; + float initialAngle = ContraptionEntity.yawFromVector(cart.getMotion()); + + withTileEntityDo(world, pos, te -> contraption.rotationMode = CartMovementMode.values()[te.movementMode.value]); ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle); entity.setPosition(pos.getX(), pos.getY(), pos.getZ()); world.addEntity(entity); @@ -129,7 +144,7 @@ public class CartAssemblerBlock extends AbstractRailBlock { public PushReaction getPushReaction(BlockState state) { return PushReaction.BLOCK; } - + @Override public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) { return false; @@ -142,7 +157,7 @@ public class CartAssemblerBlock extends AbstractRailBlock { builder.add(BlockStateProperties.HORIZONTAL_AXIS); super.fillStateContainer(builder); } - + @Override public boolean isSolid(BlockState state) { return false; @@ -155,4 +170,9 @@ public class CartAssemblerBlock extends AbstractRailBlock { return AllBlocks.MINECART_ANCHOR.get().getDefaultState().with(BlockStateProperties.HORIZONTAL_AXIS, axis); } + @Override + public Class getTileEntityClass() { + return CartAssemblerTileEntity.class; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerTileEntity.java new file mode 100644 index 000000000..89ae09aa9 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerTileEntity.java @@ -0,0 +1,65 @@ +package com.simibubi.create.modules.contraptions.components.contraptions.mounted; + +import java.util.List; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.ScreenResources; +import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.behaviour.scrollvalue.INamedIconOptions; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollOptionBehaviour; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.util.Direction; + +public class CartAssemblerTileEntity extends SmartTileEntity { + + protected ScrollOptionBehaviour movementMode; + + public CartAssemblerTileEntity() { + super(AllTileEntities.CART_ASSEMBLER.type); + } + + @Override + public void addBehaviours(List behaviours) { + movementMode = new ScrollOptionBehaviour<>(CartMovementMode.class, + Lang.translate("contraptions.cart_movement_mode"), this, getMovementModeSlot()); + movementMode.requiresWrench(); + behaviours.add(movementMode); + } + + protected ValueBoxTransform getMovementModeSlot() { + return new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP); + } + + public static enum CartMovementMode implements INamedIconOptions { + + ROTATE(ScreenResources.I_CART_ROTATE), + ROTATE_PAUSED(ScreenResources.I_CART_ROTATE_PAUSED), + ROTATION_LOCKED(ScreenResources.I_CART_ROTATE_LOCKED), + + ; + + private String translationKey; + private ScreenResources icon; + + private CartMovementMode(ScreenResources icon) { + this.icon = icon; + translationKey = "contraptions.cart_movement_mode." + Lang.asId(name()); + } + + @Override + public ScreenResources getIcon() { + return icon; + } + + @Override + public String getTranslationKey() { + return translationKey; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java index fd6697d7d..0c4b56ca0 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java @@ -7,11 +7,14 @@ import java.util.List; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes; import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode; import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.RailShape; import net.minecraft.tileentity.TileEntity; @@ -26,12 +29,14 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo; public class MountedContraption extends Contraption { + public CartMovementMode rotationMode; + @Override protected AllContraptionTypes getType() { return AllContraptionTypes.MOUNTED; } - public static Contraption assembleMinecart(World world, BlockPos pos) { + public static MountedContraption assembleMinecart(World world, BlockPos pos) { if (isFrozen()) return null; @@ -39,7 +44,7 @@ public class MountedContraption extends Contraption { if (!state.has(RAIL_SHAPE)) return null; - Contraption contraption = new MountedContraption(); + MountedContraption contraption = new MountedContraption(); if (!contraption.searchMovedStructure(world, pos, null)) return null; @@ -83,6 +88,19 @@ public class MountedContraption extends Contraption { return pair; } + @Override + public CompoundNBT writeNBT() { + CompoundNBT writeNBT = super.writeNBT(); + writeNBT.putString("RotationMode", NBTHelper.writeEnum(rotationMode)); + return writeNBT; + } + + @Override + public void readNBT(World world, CompoundNBT nbt) { + rotationMode = NBTHelper.readEnum(nbt.getString("RotationMode"), CartMovementMode.class); + super.readNBT(world, nbt); + } + @Override public void removeBlocksFromWorld(IWorld world, BlockPos offset) { super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor)); diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 6bb894769..8eab4367d 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -391,6 +391,10 @@ "create.contraptions.movement_mode.rotate_place": "Always Place when Stopped", "create.contraptions.movement_mode.rotate_place_returned": "Only Place near Initial Angle", "create.contraptions.movement_mode.rotate_never_place": "Only Place when Anchor Destroyed", + "create.contraptions.cart_movement_mode": "Cart Movement Mode", + "create.contraptions.cart_movement_mode.rotate": "Always face toward motion", + "create.contraptions.cart_movement_mode.rotate_paused": "Pause actors while rotating", + "create.contraptions.cart_movement_mode.rotation_locked": "Lock rotation", "create.logistics.filter": "Filter", "create.logistics.firstFrequency": "Freq. #1", diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 0b0183a2e7a6a8b1351d069813bcf3ed735cce33..06aa1ce240b58cd034610eb2b430b161c20fe611 100644 GIT binary patch delta 3941 zcmV-r51R1v9>XAzNq@2c01mPNF*QE7000lzNkl;`I*LICI@gzR|^wW1SrR-OA&40E>U2_q#0pM*q7J2c! z|Ni^Ua<^(r|7$TLb-jDn-)r8!eHpGr_|cC)NU!#D=&ugy(7QvQzoZwrTHC(Yn%;P> z#$S^9_S)@_%$*T?)e{vb##ZX!NJ_DPo zvccy{^=z?MJ-J;sfLq}=*^@Ws^~7@dL>Q@KW|7w%+SI}A4lQ8IVr{Ap-KXw5Cf%1d zu~ei>b;Oji-*^)#Q9H40PS?|EQ7PUrzSgRv6)zftR)2ghmTlcv&tCPEG%It%dpCLy z@;7>94B{umuYdnZI{ShiwS7Hq68U5JpjHaF}n_E^4@m(E|b?Y?P|Ymt^V zGLK2=dW=7wG}P)ZQJWfjw>|Pc9g%sPtA)8V`D9?j?@M$p6gh% zHQv|7WqPRBzX%>^8_%GIvrn~(diKIRMA zd9B5}<^FRnC#oZVoldJt@ug!ba;DT?%&YZ3*6Z@Ec1D!?vbW|Z%Cm}ZU}+N6#EB8h zkHlt9i}Y~RVdl+0#va-{wtGmQkJjP->!|yV>3?|Ppfvd{zyFw0b~9e(Vq40FGdo$L4-wzR1YK=iZfZ2aiseEh{*{)@O3hyLoIK5HVMHuqY7-nQ?zrZ*0&@e=D8 z9rx(k@wwWVlBUdry3*KXJ@eM8Y}4dT7pbMwJ{VqxrH^piig*W%mSzJIOs zgH7bVJ>>5I0F2=Y-~n9o2>{on-&wW(wxWj(U2mKrOob-vPAL7GL~jYW!NV^k$cS4%fu+pYCb{`1l`xIp#Y) z_PNxDUVQHB-}r7iYy0G%e@$mE^?x?GYtj3#@=IjJYYeyES1*2b1GuT*0qAC9O4+Z< z6Y&zXIrvj~geP9>&rhZG30{j;j8jXm?MR!%pZ@rpcTQUDdFokx{~dR&`BS5L<+R0W ze9iO*u=3`N(4=>ATQQ|#RkP(I4X!49UPny5H=*_EKl5ZDYA>BG(PB)en}3YP=bJ@u ztRj7it;CDQ%bTW;dx>)(WlizD>FE2KxwqB$nyC$7uL(ISZU#=hKB!DOJu};XJ$fmn zmqWh)t@q!xlFH;y0;M;zbsw{S_~B2M>Y9l!jn~X%U5SrlwmMhyc+bDl_eJrs&x+F~ z=c7~2YW%3-4ImE4=pd|6dw-?mYsW$bwQD1>tGuYaapXzY^c3KfQ{SBQTI1}b*V_H# z^+=N?j~B)I=XX)LII(h$_2in3_a~L_H*(x+e2x3AqsMGUFJAdhDeHwi-ec(FYP{)s zZ!AU)Z2+;uTLyNP2cVWxv8KG-Xxxgps5OyeO4+AR|M&!;H#n9l@qhKw!jMwD%eoIS z9SbC$OmPD0I2vy%@07C6`qi4atMPu1eN;*wvL@$ zE55W2MEN84p2vF}UwGB!Pai^4Zn)h+>#p{t{eLaqw;(fj) z-r}0v!)XJEol+yQp<0J;Sw2u(22PWuHDPjktoNjIN|#Rg>3`*!{LS}!;C|=VbEWHf z-_^brfm2kzR$$7^rP6h}!+P%*4lWk4bTgkEujubxlXT*1hYs+ts;KNh@CW z;QLV8!;2??(%|$4Y)@*-H@;Quuj+D2S>5~bAg7nr1wAUp)E@nF`2xwuq_+rlEnjpq zR^u)9am&~_K7W5t(`nb1c$F=sbh*oAeVo1T)%aP($~{OkH@>%#H!7VLmEwCbaaYv> z(BQ{OEGm=dUE)uH-GB8#eVKhP)K4$sIEnJU*Q~}{tVc>?+TwWKzs5wz(tA)-icgn@ zDCVPI{Pyji|M1I{^M50KP<$M}Xpi`ru_)Od`JgnQHh(&>-T>ln_H(sQ{?Z2EKE#Ey zWdjh^v2_EGt?_$Wo#ZR_*Z?jWzdAP88Pyv%JE(g<0eJDPys@q$w^HZcuDP&BegDIs zACFrX@TKF~0B*q64WRdT_y7Q03{L<%`P;wCkK8ri`6@$?>+8-!{SqSn0xEw!LNV#| zWTuYQ_#2(*W#Dadh)hi-%5Nb_TD#ud+YzByO#}mxRsMe*MPIHj!9g3BjmNhy9t9-r6Kt9Lct z;)2_<_~LixI?unB>rKMh_EmpOy3f*4No}{1cz>MoW2t;hHI5(Q{^~qGZnY)e;}!e! zXo?d{H|t3k&n16d(u>!zRY$Ll)$5lKC;zv<^5)Io|C3%+tUki44e@utnxt;?YhV82 zk9Yh>JpO|sZ%VzsDPH5}ag5{H>u2fHb2h&B{>}D5_37UIy?O8cJ+|g?T=~BJR-HWo zNPiss{EcY6F_xFn8{nkZy*lD`$He1mypAm@Q%dP_mnMuBQJ&J}BA3zRjWIFBYbmU# zwD@gg5^MZ)zxgp;p0XuAzJIpTejJC{MeK1*FCWg(K$qT-nixM5XV;Dw)uGsURDP^a zpCnS6P%2+qgn55dhvI#-*lsO8Z$EyrX@7%=ai%<#?|p(Q-tEVJjKs!I-x%+{zvdG_ zY+tWO``{;leDQm%AIXa+01wnwdAwfF)OpQ#Eg&aRoZfsNOJ!O#c{JgCOxY)S9eLeu zH%`J>Mw8JK(lO?^^m3XPO+3!lm&favE_JDVIz5?**LbMB-@lZ78oLp`Umcx}7k?hi z*^dAke5aH(*J^xACvM%?mv!M9{*_A05Wl+ z`IErM)+E%Yls~b|zpV4opJqz=Z=y?et6V&)j8p69SoOD*9NXhQ<|$q7D#a?L%Uz{d zrF6Ng6sx3bBljQ2ERTOQFGizulQTQty~ppR_bD?n2_K2ZW6yh@`9);OYJdDAd9Im= ztJr%3Sj7ea0002sN%6zZqLu#-Q21}ba7}y-2t2X7*#PtvpHs>Lu&DYYKyRV-zF%*} zZ~1OM)_0BX_G|bN0Qao<1fYc$lk<)j8?;#SSjYKTqu4y9O8|DZ`;P!xu%$&F^LvZh z8-|nf;t{~Q;|8$Dr>yE|Er0%alvbO0c^_H)z`l+ffEHH1*k-8?FVND$jn^ff=kjZM zy|rHe>P|lb?77HXS8b8k@^ho*0Bm#G07{Erc`-Tfc(Flc_S{eaT*l3P!nQVzTYMtm zYe3vH9AgyH68Ohwtw~+cx1;7V9Vmz8sn6*Uhw7+7rDp4FLD-RlfzehHE`}0000000000aJ%&NS^VA{z~iZYMSte+&u70!kDG?$N_jQC zO^2`bfLEY}=*8Gulu;>Wrk+-rk$3>(x_=0yMdv4hl+{%#I~$*;bP2$YhW-*z3vhN5 z0C4+;{}hqze3ykM}IdlzILu-N&NaQFQ;p+r&dQV zKAkrE06des`TqcViyy$en_5i0Pw?I*(2Gx}JOKbTS}0yDweyx*OgtYkQ?_I^9(V?4 zKLY5}@e-eqv-PTM+&qq%6ISB^+yE`!l?A*S4?ME7CxEzMYUeGrn0P*FwtQ|i9(Z(T zkK|r7`8(r!Ex#qkjKr&q%huYLS{#_s!u&!)!N@ z0RX!h5XsFCJ^-+1yW6>+FUFx}KiJca+zzxZ3{@p--fx#536UPF{5s5a6_HqIX-`Bm_By_tS|b*42bh#9V>K@jx=H>8m_=a=rp}!({Jvo z{TC-X<6jzoq9rXy#xskZ3Cs&Ajt505o5p)lF+)t@(&{a&>PQ8)zZwjgNgsG|(BhCT zyyA{gMTn=;fw@lhZ|aGYEM~S2j;Uqs7EU3@Jk(_8V&Mdh|K!^JGc~pxyU`RqkU@85^NdxEJ#`zdL5?bz*N!3^JD#2@N}d3;1Gm54ZFSOkv-QOWHU;xb{ny2tQ)6 zf5B4aMY9c$`BuNEQ`5fLa50?6SNjbMZ4oySz0uz>9NXTlDI^}wR8{)aMKN;NNa{S+ zo}aNIe^>X9jQ_y4kjk$(ZQ6ZB*c_95gviGTpIrPaYtbi)6yfvURc0}S3A*(Ppw9$>B!uc@Sz9exmAu} zl`siiJ&qGte~)Pw7Q{Xb9~X0@_x367d|J$E)+%#L7>Kf7oPY)Ii7}i$^PJ|=UbBp; zoL>GCH+t9rR2ic2v=g?fVW4Whbe-rY%RQ0{s zw`B;n$MAaU#`dF8v`q?s>Yoe#@oodTInIwgn|0MSJl)}bF1jKSO{MZeo7q5cUwm|f$^b~Vbb!oo%_+eAfG=QM6Q+^r?znNc&7G=7 ztCvWU<@Zw6$8iR1ee@;e8YB*71{loic#)2)?UTu(u|?2bj)sS&on1ctA&Fe+YYtF0 zBwaiSR610|eDWiV~ztmaU)d6s9U9v>QrukvoT$jHXGMJeKvApJGespp z^!2rbAcNqcgh_!`N1?g)_PtS)KsX5%enJw@;*&7UM%0ows>|4Tjp^l*;IKPh6GxqG#YYCcn&(Mt~H>h(qMYt#ELP=co zL@aPY8Vf|Fh^*F7<;Avtt&gQ)X?~kwPCt-GrnOA33QR;{(w`Afw8y99ciT?{c6>g( zh~6UXn^Q3&5pY5$Rxq*2pWAJ&c3>p6q?!FYLA zdwuuE!K)ZAq2UI2X+vb|t7kb(B4G9a4hP5|GgNZ1(kQlbrOB;dvi$nlPwMg8ZD{XV z3(<(X9!BEY;qeg}4EYC|>XL(4r5bb6$vV?4nXoy$HmeD6@LyY*y8!+C>9Ww+!!!Lo z2AlUVl*|fEWxnqaZr%#oRZA@4gO%rD~Xib#eBA4XQ&>%(!q zcS_TkKTob4X?nLb%EadOR0hu~;qxgQ3>=%SnspjK-y(926MVOPsX(hjprq13)k5a_ zJsz0k6_Vyn!`{EL;peofo?%)y5Z<+}jBo~R%N+t5R{1MF8FFfE(g#UD`HK`FPV!DZ z-5mCOS6uRu#<|>2UC4BCbw)qyeEeo>#zt}@_P1R0C^O5_qGc_#QB1E@M9T_uey&o# zm$zb1p9%dcJ~|3k6P-Fdf~I-0o3UW3ogKkBil}lgdKJSi-_^28&0Le+Hpz)TdknPQ z5lpz4I*P>*8<`4U4u=tWXa0r@?;$64+aVd<1upb^b zlTx*iPn$q*te;XuBX^h4?cr3ldpaxxY+TUo3=HH2U?v z%CUbOKoMYQuAA`=9hhd$9)(FsnHg6(Qid+)q#1Ar7J)aZ!D9AK9S@B)3kItg)ZxyD zqv)p$dTtjkm*+iwt4dUOByG0Vwsn)L(Ar|v3YuWe-NIk2V@1|>b;Nr3^*oTHv4brAT0n)E%4Riyom#Tk)0dcjxsl(yIyKF zX>BbTcw+{v-tY20y*03O$~Af9+;k#m-^jb9M{SeV_r9>6s5d9U z281^t-Ocw&STet6M*-q0h*Bke)AdE(i-(lkCvF|M`M}SQ>9+YqXH0CV>4=29HRfb0 zLwK1c1`osAH8r`RABGRHm|(;Qi4Fw4Wi)5uUgQ3qfZ^Z-dP~qdk>*z46ipy5$PD1> z1Vez5fnf`Pn7jSzyEzKrdp7y?T|eMNj(M&#a5+J4pFFa)a$Pq(@@fX3f!4`vUA6V? za98a|5;J%>$aT{%I?2ZAp7@zK`n4abnO+00M9&2`;NxCDrfJTDqDxL1iXBM~+1;;1 zTMZu#@ZTd31H{|@K$vl7?~cFQA}bF5D&XVHcLz<@WrUhxt!u)0nt^R&zWTux2knB> zQYd3An(olbBqqqPk(GdvZ|RzN38cH1MH&7q@X_G)o1-KLB!agP^>Y;#q6<58>99a2Dsobt{HOKfM zY4`u<2L?1Z&8EJL0f!fOs^U(z`2wSuOg<0>XEiP~M+Krv^9@ik< l*z=N Date: Thu, 30 Apr 2020 16:45:35 +0200 Subject: [PATCH 09/11] Pocket Carts - Minecarts with mounted contraptions can now be picked up as an item - Furnace Minecarts can now be used in the cart assembler - Fixed superglue not re-appearing when moved in piston contraptions - Fixed deployer not being able to interact with non-living entities - Fixed Schematic deploy tool outline not rendering at the right location for certain boundary sizes - Fixed leaking GL texture parameters from outline rendering - Added Italian localization - Fixed file extension of Japanese localization --- .../java/com/simibubi/create/AllItems.java | 4 + .../create/foundation/utility/GlHelper.java | 12 + .../utility/outliner/AABBOutline.java | 10 +- .../components/contraptions/Contraption.java | 2 +- .../contraptions/ContraptionEntity.java | 88 +- .../mounted/CartAssemblerBlock.java | 24 +- .../mounted/MinecartContraptionItem.java | 215 +++ .../piston/PistonContraption.java | 10 + .../components/deployer/DeployerHandler.java | 8 +- .../schematics/client/tools/DeployTool.java | 32 +- .../schematics/client/tools/FlipTool.java | 5 +- .../resources/assets/create/lang/en_us.json | 1 + .../resources/assets/create/lang/it_it.json | 1156 +++++++++++++++++ .../create/lang/{ja_jp.lang => ja_jp.json} | 0 .../item/furnace_minecart_contraption.json | 6 + .../models/item/minecart_contraption.json | 6 + .../textures/item/minecart_contraption.png | Bin 0 -> 582 bytes .../recipes/crafting_shapeless/minecart.json | 17 + 18 files changed, 1558 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MinecartContraptionItem.java create mode 100644 src/main/resources/assets/create/lang/it_it.json rename src/main/resources/assets/create/lang/{ja_jp.lang => ja_jp.json} (100%) create mode 100644 src/main/resources/assets/create/models/item/furnace_minecart_contraption.json create mode 100644 src/main/resources/assets/create/models/item/minecart_contraption.json create mode 100644 src/main/resources/assets/create/textures/item/minecart_contraption.png create mode 100644 src/main/resources/data/create/recipes/crafting_shapeless/minecart.json diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index ee2527e0d..8c6f1c348 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -17,6 +17,7 @@ import com.simibubi.create.modules.IModule; import com.simibubi.create.modules.contraptions.GogglesItem; import com.simibubi.create.modules.contraptions.WrenchItem; import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueItem; +import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MinecartContraptionItem; import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem; import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem; import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem; @@ -39,6 +40,7 @@ import com.simibubi.create.modules.schematics.item.SchematicItem; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.color.ItemColors; import net.minecraft.client.renderer.tileentity.ItemStackTileEntityRenderer; +import net.minecraft.entity.item.minecart.AbstractMinecartEntity.Type; import net.minecraft.item.Item; import net.minecraft.item.Item.Properties; import net.minecraft.item.ItemStack; @@ -99,6 +101,8 @@ public enum AllItems { RED_SAND_PAPER(SandPaperItem::new), WRENCH(WrenchItem::new), GOGGLES(GogglesItem::new), + MINECART_CONTRAPTION(p -> new MinecartContraptionItem(Type.RIDEABLE, p)), + FURNACE_MINECART_CONTRAPTION(p -> new MinecartContraptionItem(Type.FURNACE, p)), __LOGISTICS__(module()), FILTER(FilterItem::new), diff --git a/src/main/java/com/simibubi/create/foundation/utility/GlHelper.java b/src/main/java/com/simibubi/create/foundation/utility/GlHelper.java index 6c2488bab..0dfd457ac 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/GlHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/GlHelper.java @@ -1,5 +1,7 @@ package com.simibubi.create.foundation.utility; +import org.lwjgl.opengl.GL11; + import com.mojang.blaze3d.platform.GlStateManager; import net.minecraft.util.math.Vec3d; @@ -20,4 +22,14 @@ public class GlHelper { GlStateManager.popMatrix(); } + public static void enableTextureRepeat() { + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_REPEAT); + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_REPEAT); + } + + public static void disableTextureRepeat() { + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_CLAMP); + GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_CLAMP); + } + } diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java index f899ee4b3..514f92707 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java @@ -1,10 +1,9 @@ package com.simibubi.create.foundation.utility.outliner; -import org.lwjgl.opengl.GL11; - import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.GlHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; @@ -99,9 +98,6 @@ public class AABBOutline extends Outline { } protected void renderFace(Direction direction, Vec3d p1, Vec3d p2, Vec3d p3, Vec3d p4, BufferBuilder buffer) { - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_REPEAT); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_REPEAT); - if (direction == highlightedFace && highlightedTexture != null) highlightedTexture.bind(); else if (faceTexture != null) @@ -109,16 +105,18 @@ public class AABBOutline extends Outline { else return; - GlStateManager.depthMask(false); Vec3d uDiff = p2.subtract(p1); Vec3d vDiff = p4.subtract(p1); Axis axis = direction.getAxis(); float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); + GlHelper.enableTextureRepeat(); + GlStateManager.depthMask(false); putQuadUV(p1, p2, p3, p4, 0, 0, maxU, maxV, new Vec3d(1, 1, 1), 1, buffer); flush(); GlStateManager.depthMask(true); + GlHelper.disableTextureRepeat(); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java index 62aed5140..d06f73f8a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java @@ -86,7 +86,7 @@ public abstract class Contraption { protected BlockPos anchor; List renderOrder; - List glueToRemove; + protected List glueToRemove; public Contraption() { blocks = new HashMap<>(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index 2a0afc2a0..d29371dde 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -12,6 +12,7 @@ import org.apache.commons.lang3.tuple.MutablePair; import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllEntities; import com.simibubi.create.AllPackets; +import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.bearing.BearingContraption; @@ -19,12 +20,17 @@ import com.simibubi.create.modules.contraptions.components.contraptions.mounted. import com.simibubi.create.modules.contraptions.components.contraptions.mounted.MountedContraption; import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity; +import net.minecraft.block.BlockState; import net.minecraft.block.material.PushReaction; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.item.BoatEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity; +import net.minecraft.entity.item.minecart.FurnaceMinecartEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.NBTUtil; @@ -33,11 +39,14 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.tags.BlockTags; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; import net.minecraft.util.ReuseableStream; 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.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.ISelectionContext; @@ -56,12 +65,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD protected Contraption contraption; protected float initialAngle; + protected float forcedAngle; protected BlockPos controllerPos; protected Vec3d motionBeforeStall; protected boolean stationary; final List collidingEntities = new ArrayList<>(); + private static final Ingredient FUEL_ITEMS = Ingredient.fromItems(Items.COAL, Items.CHARCOAL); private static final DataParameter STALLED = EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.BOOLEAN); @@ -81,19 +92,25 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD super(entityTypeIn, worldIn); motionBeforeStall = Vec3d.ZERO; stationary = entityTypeIn == AllEntities.STATIONARY_CONTRAPTION.type; + forcedAngle = -1; } public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) { ContraptionEntity entity = new ContraptionEntity(AllEntities.CONTRAPTION.type, world); entity.contraption = contraption; entity.initialAngle = initialAngle; - entity.prevYaw = initialAngle; - entity.yaw = initialAngle; - entity.targetYaw = initialAngle; + entity.forceYaw(initialAngle); if (contraption != null) contraption.gatherStoredItems(); return entity; } + + public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle, Direction facing) { + ContraptionEntity entity = createMounted(world, contraption, initialAngle); + entity.forcedAngle = facing.getHorizontalAngle(); + entity.forceYaw(entity.forcedAngle); + return entity; + } public static ContraptionEntity createStationary(World world, Contraption contraption) { ContraptionEntity entity = new ContraptionEntity(AllEntities.STATIONARY_CONTRAPTION.type, world); @@ -207,6 +224,39 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD motionBeforeStall = Vec3d.ZERO; } + if (!isStalled() && (riding instanceof FurnaceMinecartEntity)) { + FurnaceMinecartEntity furnaceCart = (FurnaceMinecartEntity) riding; + CompoundNBT nbt = furnaceCart.serializeNBT(); + int fuel = nbt.getInt("Fuel"); + int fuelBefore = fuel; + double pushX = nbt.getDouble("PushX"); + double pushZ = nbt.getDouble("PushZ"); + + int i = MathHelper.floor(furnaceCart.posX); + int j = MathHelper.floor(furnaceCart.posY); + int k = MathHelper.floor(furnaceCart.posZ); + if (furnaceCart.world.getBlockState(new BlockPos(i, j - 1, k)).isIn(BlockTags.RAILS)) + --j; + + BlockPos blockpos = new BlockPos(i, j, k); + BlockState blockstate = this.world.getBlockState(blockpos); + if (furnaceCart.canUseRail() && blockstate.isIn(BlockTags.RAILS)) + if (fuel > 1) + riding.setMotion(riding.getMotion().normalize().scale(1)); + if (fuel < 5 && contraption != null) { + ItemStack coal = ItemHelper.extract(contraption.inventory, FUEL_ITEMS, 1, false); + if (!coal.isEmpty()) + fuel += 3600; + } + + if (fuel != fuelBefore || pushX != 0 || pushZ != 0) { + nbt.putInt("Fuel", fuel); + nbt.putDouble("PushX", 0); + nbt.putDouble("PushZ", 0); + furnaceCart.deserializeNBT(nbt); + } + } + super.tick(); } @@ -383,7 +433,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD protected void readAdditional(CompoundNBT compound) { contraption = Contraption.fromNBT(world, compound.getCompound("Contraption")); initialAngle = compound.getFloat("InitialAngle"); - targetYaw = yaw = prevYaw = initialAngle; + forceYaw(compound.contains("ForcedYaw") ? compound.getFloat("ForcedYaw") : initialAngle); dataManager.set(STALLED, compound.getBoolean("Stalled")); ListNBT vecNBT = compound.getList("CachedMotion", 6); if (!vecNBT.isEmpty()) { @@ -396,6 +446,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller")); } + public void forceYaw(float forcedYaw) { + targetYaw = yaw = prevYaw = forcedYaw; + } + public void checkController() { if (controllerPos == null) return; @@ -415,14 +469,18 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override protected void writeAdditional(CompoundNBT compound) { - compound.put("Contraption", getContraption().writeNBT()); - compound.putFloat("InitialAngle", initialAngle); - if (!stationary) + if (contraption != null) + compound.put("Contraption", contraption.writeNBT()); + if (!stationary && motionBeforeStall != null) compound.put("CachedMotion", newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z)); - compound.putBoolean("Stalled", isStalled()); if (controllerPos != null) compound.put("Controller", NBTUtil.writeBlockPos(controllerPos)); + if (forcedAngle != -1) + compound.putFloat("ForcedYaw", forcedAngle); + + compound.putFloat("InitialAngle", initialAngle); + compound.putBoolean("Stalled", isStalled()); } @Override @@ -553,4 +611,18 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD super.setMotion(vec); } + @Override + public boolean canBeCollidedWith() { + return false; + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + return false; + } + + public float getInitialAngle() { + return initialAngle; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java index a789eef59..3475d35d4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java @@ -13,7 +13,9 @@ import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.material.PushReaction; import net.minecraft.entity.item.minecart.AbstractMinecartEntity; +import net.minecraft.entity.item.minecart.FurnaceMinecartEntity; import net.minecraft.item.BlockItemUseContext; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.BooleanProperty; import net.minecraft.state.EnumProperty; import net.minecraft.state.IProperty; @@ -72,7 +74,7 @@ public class CartAssemblerBlock extends AbstractRailBlock implements ITE contraption.rotationMode = CartMovementMode.values()[te.movementMode.value]); ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle); entity.setPosition(pos.getX(), pos.getY(), pos.getZ()); world.addEntity(entity); entity.startRiding(cart); + + if (cart instanceof FurnaceMinecartEntity) { + CompoundNBT nbt = cart.serializeNBT(); + nbt.putDouble("PushZ", 0); + nbt.putDouble("PushX", 0); + cart.deserializeNBT(nbt); + } } protected void disassemble(World world, BlockPos pos, AbstractMinecartEntity cart) { @@ -105,6 +116,13 @@ public class CartAssemblerBlock extends AbstractRailBlock implements ITE items) {} + + @SubscribeEvent + public static void wrenchCanBeUsedToPickUpMinecartContraptions(PlayerInteractEvent.EntityInteract event) { + Entity entity = event.getTarget(); + PlayerEntity player = event.getPlayer(); + if (player == null || entity == null) + return; + + ItemStack wrench = player.getHeldItem(event.getHand()); + if (!AllItems.WRENCH.typeOf(wrench)) + return; + if (entity instanceof ContraptionEntity) + entity = entity.getRidingEntity(); + if (!(entity instanceof AbstractMinecartEntity)) + return; + AbstractMinecartEntity cart = (AbstractMinecartEntity) entity; + Type type = cart.getMinecartType(); + if (type != Type.RIDEABLE && type != Type.FURNACE) + return; + List passengers = cart.getPassengers(); + if (passengers.isEmpty() || !(passengers.get(0) instanceof ContraptionEntity)) + return; + ContraptionEntity contraption = (ContraptionEntity) passengers.get(0); + + if (!event.getWorld().isRemote) { + player.inventory.placeItemBackInInventory(event.getWorld(), create(type, contraption)); + contraption.remove(); + entity.remove(); + } + + event.setCancellationResult(ActionResultType.SUCCESS); + event.setCanceled(true); + } + + public static ItemStack create(Type type, ContraptionEntity entity) { + ItemStack stack = + (type == Type.RIDEABLE ? AllItems.MINECART_CONTRAPTION : AllItems.FURNACE_MINECART_CONTRAPTION).asStack(); + CompoundNBT tag = entity.getContraption().writeNBT(); + tag.remove("UUID"); + tag.remove("Pos"); + tag.remove("Motion"); + tag.putFloat("InitialAngle", entity.getInitialAngle()); + stack.getOrCreateTag().put("Contraption", tag); + return stack; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java index 33e754a46..947321a0d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java @@ -17,6 +17,7 @@ import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes; import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; +import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; import net.minecraft.block.BlockState; @@ -169,6 +170,15 @@ public class PistonContraption extends Contraption { super.add(pos.offset(orientation, -initialExtensionProgress), capture); } + @Override + public void addGlue(SuperGlueEntity entity) { + BlockPos pos = entity.getHangingPosition(); + Direction direction = entity.getFacingDirection(); + BlockPos localPos = pos.subtract(anchor).offset(orientation, -initialExtensionProgress); + this.superglue.add(Pair.of(localPos, direction)); + glueToRemove.add(entity); + } + @Override public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) { super.addBlocksToWorld(world, offset, rotation, (pos, state) -> { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java index 8f9f23a5a..303c79761 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerHandler.java @@ -15,6 +15,7 @@ import com.simibubi.create.modules.curiosities.tools.SandPaperItem; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.material.Material; +import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.item.ItemEntity; @@ -113,10 +114,10 @@ public class DeployerHandler { // Check for entities final ServerWorld world = player.getServerWorld(); - List entities = world.getEntitiesWithinAABB(LivingEntity.class, new AxisAlignedBB(clickedPos)); + List entities = world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(clickedPos)); Hand hand = Hand.MAIN_HAND; if (!entities.isEmpty()) { - LivingEntity entity = entities.get(world.rand.nextInt(entities.size())); + Entity entity = entities.get(world.rand.nextInt(entities.size())); List capturedDrops = new ArrayList<>(); boolean success = false; entity.captureDrops(capturedDrops); @@ -131,7 +132,8 @@ public class DeployerHandler { if (cancelResult == null) { if (entity.processInitialInteract(player, hand)) success = true; - else if (stack.interactWithEntity(player, entity, hand)) + else if (entity instanceof LivingEntity + && stack.interactWithEntity(player, (LivingEntity) entity, hand)) success = true; } } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java index 417a0cf5e..3f44b39c7 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/DeployTool.java @@ -10,6 +10,7 @@ import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTUtil; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -48,15 +49,19 @@ public class DeployTool extends PlacementToolBase { double z = MathHelper.lerp(pt, lastChasingSelectedPos.z, chasingSelectedPos.z); SchematicTransformation transformation = schematicHandler.getTransformation(); - Vec3d center = schematicHandler.getBounds().getCenter(); - Vec3d offset = transformation.getRotationOffset(true); + AxisAlignedBB bounds = schematicHandler.getBounds(); + Vec3d center = bounds.getCenter(); + Vec3d rotationOffset = transformation.getRotationOffset(true); + int centerX = (int) center.x; + int centerZ = (int) center.z; + double xOrigin = bounds.getXSize() / 2f; + double zOrigin = bounds.getZSize() / 2f; - if (schematicHandler.getBounds().getXSize() % 2 == 1 || schematicHandler.getBounds().getZSize() % 2 == 1) - GlStateManager.translated(.5f, 0, .5f); - GlStateManager.translated(x, y, z); + GlStateManager.translated(x - centerX, y, z - centerZ); + GlStateManager.translated(xOrigin + rotationOffset.x, 0, zOrigin + rotationOffset.z); GlStateManager.rotated(transformation.getCurrentRotation(), 0, 1, 0); - GlStateManager.translated(-offset.x, 0, -offset.z); - GlStateManager.translated(-(center.x), 0, -(center.z)); + GlStateManager.translated(-rotationOffset.x, 0, -rotationOffset.z); + GlStateManager.translated(-xOrigin, 0, -zOrigin); schematicHandler.getOutline().setTextures(AllSpecialTextures.CHECKERED, null); schematicHandler.getOutline().render(Tessellator.getInstance().getBuffer()); @@ -66,14 +71,11 @@ public class DeployTool extends PlacementToolBase { @Override public boolean handleMouseWheel(double delta) { - - if (selectIgnoreBlocks) { - selectionRange += delta; - selectionRange = MathHelper.clamp(selectionRange, 1, 100); - return true; - } - - return super.handleMouseWheel(delta); + if (!selectIgnoreBlocks) + return super.handleMouseWheel(delta); + selectionRange += delta; + selectionRange = MathHelper.clamp(selectionRange, 1, 100); + return true; } @Override diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java index 2e9cba5ab..7718c4297 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java @@ -5,6 +5,7 @@ import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.GlHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.outliner.AABBOutline; @@ -89,8 +90,7 @@ public class FlipTool extends PlacementToolBase { Tessellator.getInstance().draw(); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_REPEAT); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_REPEAT); + GlHelper.enableTextureRepeat(); GlStateManager.depthMask(false); Vec3d uDiff = v2.subtract(v1); Vec3d vDiff = v4.subtract(v1); @@ -103,6 +103,7 @@ public class FlipTool extends PlacementToolBase { outline.putQuadUV(v2, v1, v4, v3, 0, 0, maxU, maxV, color, 1, buffer); Tessellator.getInstance().draw(); GlStateManager.popMatrix(); + GlHelper.disableTextureRepeat(); } } diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 8eab4367d..566681264 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -37,6 +37,7 @@ "item.create.sand_paper": "Sand Paper", "item.create.red_sand_paper": "Red Sand Paper", "item.create.super_glue": "Super Glue", + "item.create.minecart_contraption": "Minecart with Contraption", "item.create.brass_ingot": "Brass Ingot", "item.create.brass_sheet": "Brass Sheets", diff --git a/src/main/resources/assets/create/lang/it_it.json b/src/main/resources/assets/create/lang/it_it.json new file mode 100644 index 000000000..631e7e68f --- /dev/null +++ b/src/main/resources/assets/create/lang/it_it.json @@ -0,0 +1,1156 @@ +{ + + "_comment": "-------------------------] GAME ELEMENTS [------------------------------------------------", + + "item.create.symmetry_wand": "Asta di Simetria", + "item.create.placement_handgun": "Zapper di Blocchi Portatile", + "item.create.terrain_zapper": "Plasmatore del Mondo Portatile", + "item.create.tree_fertilizer": "Fertilizzante per Alberi", + "item.create.empty_blueprint": "Schematica Vuota", + "item.create.andesite_alloy": "Lega di Andesite", + "item.create.chromatic_compound": "Composto Cromatico", + "item.create.shadow_steel": "Acciaio Oscuro", + "item.create.blueprint_and_quill": "Schematica e Penna d'Oca", + "item.create.blueprint": "Schematica", + "item.create.belt_connector": "Nastro Meccanico", + "item.create.goggles": "Occhiali da Ingegnere", + "item.create.filter": "Filtro", + "item.create.property_filter": "Filtro Attributi", + "item.create.rose_quartz": "Quarzo Rosa", + "item.create.polished_rose_quartz": "Quarzo Rosa Levigato", + "item.create.refined_radiance": "Radiance Raffinata", + "item.create.iron_sheet": "Lamiera di Ferro", + "item.create.gold_sheet": "Lamiera di Oro", + "item.create.lapis_plate": "Placcatura di Lapislazzuli", + "item.create.obsidian_dust": "Polvere di Ossidiana", + "item.create.propeller": "Elica", + "item.create.whisk": "Frusta", + "item.create.brass_hand": "Mano", + "item.create.slot_cover": "Rivestimento Slot Creazione", + "item.create.zinc_handle": "Impugnatura per Strumenti di Qualità", + "item.create.flour": "Farina di Grano", + "item.create.dough": "Impasto", + "item.create.wrench": "Chiave Inglese", + "item.create.deforester": "Deforestatore", + "item.create.crushed_iron": "Ferro Grezzo Frantumato", + "item.create.crushed_gold": "Oro Grezzo Frantumato", + "item.create.sand_paper": "Carta Vetrata", + "item.create.red_sand_paper": "Carta Vetrata Rossa", + + "item.create.brass_ingot": "Lingotto di Ottone", + "item.create.brass_sheet": "Lamiera di Ottone", + "item.create.brass_nugget": "Pepita di Ottone", + "item.create.crushed_brass": "Ottone Frantumato", + "item.create.zinc_ingot": "Barra di Zinco", + "item.create.zinc_nugget": "Pepita di Zinco", + "item.create.crushed_zinc": "Zinco Frantumato", + "item.create.copper_sheet": "Lamiera di Rame", + "item.create.copper_ingot": "Lingotto di Rame", + "item.create.copper_nugget": "Pepita di Rame", + "item.create.crushed_copper": "Rame Frantumato", + + "item.create.electron_tube": "Valvola", + "item.create.integrated_circuit": "Circuito Integrato", + + "item.create.blazing_pickaxe": "Piccone Fiammeggiante", + "item.create.blazing_shovel": "Pala Fiammeggiante", + "item.create.blazing_axe": "Ascia Fiammeggiante", + "item.create.blazing_sword": "Mannaia Fiammeggiante", + + "item.create.shadow_steel_pickaxe": "Piccone di Acciaio Oscuro", + "item.create.shadow_steel_mattock": "Zappa di Acciaio Oscuro", + "item.create.shadow_steel_sword": "Spada di Acciaio Oscuro", + + "item.create.rose_quartz_pickaxe": "Piccone di Quarzo Dorato", + "item.create.rose_quartz_shovel": "Pala di Quarzo Dorato", + "item.create.rose_quartz_axe": "Ascia di Quarzo Dorato", + "item.create.rose_quartz_sword": "Spada di Quarzo Dorato", + + "block.create.copper_ore": "Rame Grezzo", + "block.create.copper_block": "Blocco di Rame", + "block.create.copper_shingles": "Tegole di Rame", + "block.create.zinc_ore": "Zinco Grezzo", + "block.create.zinc_block": "Blocco di Zinco", + "block.create.brass_block": "Blocco di Ottone", + + "block.create.andesite_casing": "Involucro di Andesite", + "block.create.brass_casing": "Involucro di Ottone", + "block.create.copper_casing": "Involucro di Rame", + + "block.create.cogwheel": "Ruota Dentata", + "block.create.large_cogwheel": "Ruota Dentata Grande", + "block.create.turntable": "Piatto", + "block.create.gearbox": "Riduttore", + "block.create.gearshift": "Cambio", + "block.create.clutch": "Frizione", + "block.create.shaft": "Albero", + "block.create.encased_belt": "Nastro Incassato", + "block.create.encased_shaft": "Albero Incassato", + "block.create.encased_fan": "Ventilatore incassato", + "block.create.adjustable_pulley": "Puleggia analogica", + "block.create.nozzle": "Ugello", + "block.create.hand_crank": "Manovella", + "block.create.cuckoo_clock": "Orologio a Cucù", + "block.create.creative_motor": "Motore", + "block.create.belt": "Nastro Meccanico", + "block.create.millstone": "Macina", + "block.create.crushing_wheel": "Ruota di Frantumazione", + "block.create.drill": "Trapano Meccanico", + "block.create.portable_storage_interface": "Interfaccia di Archiviazione Portatile", + "block.create.harvester": "Mietitrice Meccanica", + "block.create.saw": "Sega Meccanica", + "block.create.water_wheel": "Ruota d'Acqua", + "block.create.mechanical_press": "Pressa Meccanica", + "block.create.mechanical_mixer": "Miscelatore Meccanico", + "block.create.deployer": "Installatore", + "block.create.basin": "Bacinella", + "block.create.mechanical_crafter": "Costruttore Meccanico", + "block.create.flywheel": "Volano", + "block.create.furnace_engine": "Motore Fornace", + "block.create.speed_gauge": "Tachimetro", + "block.create.stress_gauge": "Stressometro", + "block.create.cart_assembler": "Assemblatore Carrello da Miniera", + "block.create.analog_lever": "Leva Analogica", + "block.create.rotation_speed_controller": "Regolatore di Velocità di Rotazione", + + "block.create.sticky_mechanical_piston": "Pistome Meccanico Appiccicoso", + "block.create.mechanical_piston": "Pistome Meccanico", + "block.create.mechanical_piston_head": "Testa Pistome Meccanico", + "block.create.piston_pole": "Palo Pistome", + "block.create.mechanical_bearing": "Supporto Meccanico", + "block.create.clockwork_bearing": "Supporto del Orologio", + "block.create.rope_pulley": "Puleggia della Corda", + "block.create.rope": "Corda", + "block.create.pulley_magnet": "Magnete della Puleggia", + "block.create.translation_chassis": "Telaio Lineare", + "block.create.rotation_chassis": "Telaio Radiale", + + "block.create.contact": "Contatto Redstone", + "block.create.redstone_bridge": "Collegamento Redstone", + "block.create.stockswitch": "Interruttore Accumulatore", + "block.create.flexcrate": "Baule Regolabile", + "block.create.extractor": "Estrattore", + "block.create.belt_funnel": "Imbuto", + "block.create.linked_extractor": "Estrattore Connesso", + "block.create.transposer": "Traspositore", + "block.create.linked_transposer": "Traspositore Connesso", + "block.create.pulse_repeater": "Ripetitore di Impulsi", + "block.create.flexpulsepeater": "Ripetitore di Impulsi Regolabile", + "block.create.redstone_latch": "Leva Alimentata", + "block.create.toggle_latch": "Leva Alimentata Alterata", + "block.create.flexpeater": "Ripetitore Regolabile", + "block.create.entity_detector": "Osservatore a Cinghia", + "block.create.belt_tunnel": "Tunnel Trasportatore", + "block.create.sequenced_gearshift": "Cambio Sequenziale", + + "block.create.tiled_glass": "Vetro Piastrellato", + "block.create.framed_glass": "Finestra Grande Vetro", + "block.create.vertical_framed_glass": "Finestra Verticale Vetro", + "block.create.horizontal_framed_glass": "Finestra Orizzontale Vetro", + "block.create.oak_glass": "Finestra di Quercia", + "block.create.spruce_glass": "Finestra di Abete", + "block.create.birch_glass": "Finestra di Betulla", + "block.create.jungle_glass": "Finestra della Giungla", + "block.create.dark_oak_glass": "Finestra di Quercia Oscura", + "block.create.acacia_glass": "Finestra di Acacia", + "block.create.iron_glass": "Finestra di Ferro Ornata", + + "block.create.tiled_glass_pane": "Pannello di Vetro Piastrellato", + "block.create.framed_glass_pane": "Pannello di Finestra Grande Vetro", + "block.create.vertical_framed_glass_pane": "Pannello di Finestra Verticale Vetro", + "block.create.horizontal_framed_glass_pane": "Pannello di Finestra Orizzontale Vetro", + "block.create.oak_glass_pane": "Pannello di Finestra di Quercia", + "block.create.spruce_glass_pane": "Pannello di Finestra di Abete", + "block.create.birch_glass_pane": "Pannello di Finestra di Betulla", + "block.create.jungle_glass_pane": "Pannello di Finestra della Giungla", + "block.create.dark_oak_glass_pane": "Pannello di Finestra di Quercia Oscura", + "block.create.acacia_glass_pane": "Pannello di Finestra di Acacia", + "block.create.iron_glass_pane": "Pannello di Finestra di Ferro Ornata", + + "block.create.window_in_a_block": "BLocco con Pannello di Vetro", + "block.create.andesite_bricks": "Mattoni di Andesite", + "block.create.andesite_layers": "Andesite Stratificata", + "block.create.diorite_bricks": "Mattoni di Diorite", + "block.create.diorite_layers": "Diorite Stratificata", + "block.create.granite_bricks": "Mattoni di Granito", + "block.create.granite_layers": "Granito Stratificato", + + "block.create.gabbro": "Gabbro", + "block.create.gabbro_stairs": "Scalini di Gabbro", + "block.create.gabbro_slab": "Lastra di Gabbro", + "block.create.gabbro_wall": "Muretto di Gabbro", + "block.create.polished_gabbro": "Gabbro Levigato", + "block.create.gabbro_bricks": "Mattoni di Gabbro", + "block.create.gabbro_bricks_stairs": "Scalini di Mattoni di Gabbro", + "block.create.gabbro_bricks_wall": "Muretto di Mattoni di Gabbro", + "block.create.paved_gabbro_bricks": "Mattoni di Gabbro Pavimentato", + "block.create.paved_gabbro_bricks_slab": "Lastra di Mattoni di Gabbro Pavimentato", + "block.create.indented_gabbro": "Piastrella di Gabbro Frastagliato", + "block.create.indented_gabbro_slab": "Lastra di Gabbro Frastagliato", + "block.create.Limestone": "Mattoni di Gabbro Muschiosi", + "block.create.mossy_gabbro_bricks": "Mattoni di Gabbro Coperto di Vegetazione", + "block.create.gabbro_layers": "Gabbro Stratificato", + + "block.create.weathered_limestone": "Calcare Consumato", + "block.create.weathered_limestone_stairs": "Scalini di Calcare Consumato", + "block.create.weathered_limestone_wall": "Muretto di Calcare Consumato", + "block.create.weathered_limestone_slab": "Lastra di Calcare Consumato", + "block.create.polished_weathered_limestone": "Calcare Consumato Levigato", + "block.create.polished_weathered_limestone_slab": "Lastra di Calcare Consumato Levigato", + "block.create.weathered_limestone_bricks": "Mattoni di Calcare Consumato", + "block.create.weathered_limestone_bricks_stairs": "Scalini di Mattoni di Calcare Consumato Levigato", + "block.create.weathered_limestone_bricks_wall": "Muretto di Mattoni di Calcare Consumato Levigato", + "block.create.weathered_limestone_bricks_slab": "Lastra di Mattoni di Calcare Consumato", + "block.create.weathered_limestone_pillar": "Pilastro di Calcare Consumato", + "block.create.weathered_limestone_layers": "Calcare Consumato Stratificato", + + "block.create.dolomite_pillar": "Pilastro di Dolomite", + "block.create.dolomite": "Dolomite", + "block.create.dolomite_stairs": "Scalini di Dolomite", + "block.create.dolomite_wall": "Muretto di Dolomite", + "block.create.dolomite_slab": "Lastra di Dolomite", + "block.create.dolomite_bricks": "Mattoni di Dolomite", + "block.create.dolomite_bricks_wall": "Muretto di Mattoni di Dolomite", + "block.create.dolomite_bricks_stairs": "Scalini di Mattoni di Dolomite", + "block.create.dolomite_bricks_slab": "Lastra di Mattoni di Dolomite", + "block.create.polished_dolomite": "Dolomite Levigato", + "block.create.dolomite_layers": "Dolomite Stratificato", + + "block.create.limesand": "Silico Calcare", + "block.create.limestone": "Calcare", + "block.create.limestone_stairs": "Scalini di Calcare", + "block.create.limestone_slab": "Lastra di Calcare", + "block.create.limestone_wall": "Muretto di Calcare", + "block.create.limestone_bricks": "Mattoni di Calcare", + "block.create.limestone_bricks_stairs": "Scalini di Mattoni di Calcare Levigato", + "block.create.limestone_bricks_slab": "Lastra di Mattoni di Calcare", + "block.create.limestone_bricks_wall": "Muretto di Mattoni di Calcare Levigato", + "block.create.polished_limestone": "Calcare Levigato", + "block.create.polished_limestone_slab": "Lastra di Calcare Levigato", + "block.create.limestone_pillar": "Pilastro di Calcare", + "block.create.limestone_layers": "Calcare Stratificato", + + "block.create.natural_scoria": "Scoria Naturale", + "block.create.scoria": "Scoria", + "block.create.scoria_stairs": "Scalini di Scoria", + "block.create.scoria_slab": "Lastra di Scoria", + "block.create.scoria_wall": "Muretto di Scoria", + "block.create.scoria_bricks": "Mattoni di Scoria", + "block.create.polished_scoria": "Scoria Levigata", + "block.create.polished_scoria_slab": "Lastra di Scoria Levigata", + "block.create.scoria_pillar": "Pilastro di Scoria", + "block.create.scoria_layers": "Scoria Stratificata", + + "block.create.dark_scoria": "Scoria Scura", + "block.create.polished_dark_scoria": "Scoria Scura Levigata", + "block.create.dark_scoria_tiles": "Piastrelle di Scoria Scura", + "block.create.dark_scoria_tiles_stairs": "Scalini di Piastrelle di Scoria Scura", + "block.create.dark_scoria_tiles_slab": "Lastra di Piastrelle di Scoria Scura", + "block.create.dark_scoria_bricks": "Mattoni di Scoria Scura", + "block.create.dark_scoria_bricks_stairs": "Scalini di Mattoni di Scoria Scura", + "block.create.dark_scoria_bricks_slab": "Lastra di Mattoni di Scoria Scura", + "block.create.dark_scoria_bricks_wall": "Muretto di Mattoni di Scoria Scura", + + "block.create.schematicannon": "Cannoneschematico", + "block.create.schematic_table": "Banco Schematico", + "block.create.creative_crate": "Creatore Cannoneschematico", + + "block.create.cocoa_log": "Tronco di Giungla Cacao", + + "_comment": "-------------------------] UI & MESSAGES [------------------------------------------------", + + "death.attack.create.crush": "%1$s è stato elaborato dala Ruota di Frantumazione", + "death.attack.create.fan_fire": "%1$s è stato bruciato a morte da aria calda", + "death.attack.create.fan_lava": "%1$s è stato bruciato a morte dal ventilatore di lava", + "death.attack.create.drill": "%1$s è stato impalato dal Trapano Meccanico", + "death.attack.create.saw": "%1$s è stato tagliato a metà dalla Sega Meccanica", + "create.block.deployer.damage_source_name": "un Disadattato", + "death.attack.create.curse_polish": "%1$s ha provato a lucidare un oggetto maledetto", + "death.attack.create.cuckoo_clock_explosion": "%1$s è saltato in aria dall'orologio a cucù manomesso", + + "create.recipe.crushing": "Frantumazione", + "create.recipe.milling": "Fresatura", + "create.recipe.splashing": "Lavaggio alla Rinfusa", + "create.recipe.splashing.fan": "Ventilatore Dietro l'Acqua Corrente", + "create.recipe.smokingViaFan": "Massa di Fumo", + "create.recipe.smokingViaFan.fan": "Ventilatore Dietro il Fuoco", + "create.recipe.blastingViaFan": "Fusione", + "create.recipe.blastingViaFan.fan": "Ventilatore Dietro la Lava", + "create.recipe.pressing": "Pressatura", + "create.recipe.mixing": "Mescolamento", + "create.recipe.packing": "Compattazione", + "create.recipe.sawing": "Segagione", + "create.recipe.mechanical_crafting": "Creazione Meccanico", + "create.recipe.block_cutting": "Taglio Blocco", + "create.recipe.blockzapperUpgrade": "Posizionatore di Blocchi Portatile", + "create.recipe.sandpaper_polishing": "Carta Vetrata Levigata", + "create.recipe.mystery_conversion": "Metamorfosi Cromatica", + "create.recipe.processing.catalyst": "Catalizzatore", + "create.recipe.processing.chance": "%1$s%% Possibilità", + "create.recipe.processing.chanceToReturn": "%1$s%% Possibilità di Ritorno", + + "create.generic.range": "Gamma", + "create.generic.radius": "Raggio", + "create.generic.width": "Larghezza", + "create.generic.height": "Altezza", + "create.generic.length": "Lunghezza", + "create.generic.speed": "Velocità", + "create.generic.delay": "Ritardo", + "create.generic.unit.ticks": "Tick", + "create.generic.unit.seconds": "Secondi", + "create.generic.unit.minutes": "Minuti", + "create.generic.unit.rpm": "RPM", + "create.generic.unit.stress": "su", + "create.generic.unit.degrees": "°", + + "create.action.scroll": "Scorri", + "create.action.confirm": "Conferma", + "create.action.abort": "Annulla", + "create.action.saveToFile": "Salva", + "create.action.discard": "Scarta", + + "create.keyinfo.toolmenu": "Focalizza sul Menu Strumento", + "create.keyinfo.scrollup": "Simula Rotellina del Mouse Verso Su (nel mondo)", + "create.keyinfo.scrolldown": "Simula Rotellina del Mouse Verso Giù (nel mondo)", + + "create.gui.scrollInput.defaultTitle": "Scegli un Opzione:", + "create.gui.scrollInput.scrollToModify": "Scorri per Modificare", + "create.gui.scrollInput.scrollToAdjustAmount": "Scorri Fino a Regolare l'Importo", + "create.gui.scrollInput.scrollToSelect": "Scorri per Selezionare", + "create.gui.scrollInput.shiftScrollsFaster": "Premi Shift per Scorrere più Velocemente", + + "create.gui.toolmenu.focusKey": "Premi [%1$s] per Aprire il Menu", + "create.gui.toolmenu.cycle": "[SCORRI] per navigare", + + "create.gui.symmetryWand.mirrorType": "Specchio", + "create.gui.symmetryWand.orientation": "Orientamento", + "create.symmetry.mirror.plane": "Una volta", + "create.symmetry.mirror.doublePlane": "Rettangolare", + "create.symmetry.mirror.triplePlane": "Ottagonale", + "create.orientation.orthogonal": "Ortogonale", + "create.orientation.diagonal": "Diagonale", + "create.orientation.horizontal": "Orizzontale", + "create.orientation.alongZ": "Lungo Z", + "create.orientation.alongX": "Lungo X", + + "create.gui.blockzapper.title": "Posizionatore di Blocchi", + "create.gui.blockzapper.replaceMode": "Modalità Sostituire", + "create.gui.blockzapper.searchDiagonal": "Segui Diagonali", + "create.gui.blockzapper.searchFuzzy": "Ignora i Bordi dei Materiali", + "create.gui.blockzapper.range": "Gamma Diffusione", + "create.gui.blockzapper.needsUpgradedAmplifier": "Richiede Aggirnamento del Amplificatore", + "create.gui.blockzapper.patternSection": "Schema", + "create.gui.blockzapper.pattern.solid": "Solido", + "create.gui.blockzapper.pattern.checkered": "Scacchiera", + "create.gui.blockzapper.pattern.inversecheckered": "Scacchiera Invertita", + "create.gui.blockzapper.pattern.chance25": "25% Riempito", + "create.gui.blockzapper.pattern.chance50": "50% Riempito", + "create.gui.blockzapper.pattern.chance75": "75% Riempito", + + "create.gui.terrainzapper.title": "Plasmatore del Mondo", + "create.gui.terrainzapper.placement": "Piazzamento", + "create.gui.terrainzapper.placement.merged": "Fuso", + "create.gui.terrainzapper.placement.attached": "Attaccato", + "create.gui.terrainzapper.placement.inserted": "Inserito", + "create.gui.terrainzapper.brush": "Pennello", + "create.gui.terrainzapper.brush.cuboid": "Cuboide", + "create.gui.terrainzapper.brush.sphere": "Sferico", + "create.gui.terrainzapper.brush.cylinder": "Cilindrico", + "create.gui.terrainzapper.tool": "Strumento", + "create.gui.terrainzapper.tool.fill": "Riempi", + "create.gui.terrainzapper.tool.place": "Piazza", + "create.gui.terrainzapper.tool.replace": "Sostituisci", + "create.gui.terrainzapper.tool.clear": "Ripulisci", + "create.gui.terrainzapper.tool.overlay": "Ricopri", + "create.gui.terrainzapper.tool.flatten": "Appiattisci", + "create.terrainzapper.shiftRightClickToSet": "Clic-Destro e Shift per selezionare una forma", + + "create.blockzapper.usingBlock": "In utilizzo: %1$s", + "create.blockzapper.componentUpgrades": "Aggiornamenti dei Componenti:", + "create.blockzapper.component.body": "Corpo", + "create.blockzapper.component.amplifier": "Amplificatore", + "create.blockzapper.component.accelerator": "Acceleratore", + "create.blockzapper.component.retriever": "Cane da Riporto", + "create.blockzapper.component.scope": "Portata", + "create.blockzapper.componentTier.none": "Nessuno", + "create.blockzapper.componentTier.brass": "Ottone", + "create.blockzapper.componentTier.chromatic": "Cromatico", + "create.blockzapper.leftClickToSet": "Clic-Sinistro su un blocco per impostare il materiale", + "create.blockzapper.empty": "Fuori dai Blocchi!", + + "create.contraptions.movement_mode": "Modalità Movimento", + "create.contraptions.movement_mode.move_place": "Posizionare Sempre quando è Fermo", + "create.contraptions.movement_mode.move_place_returned": "Posiziona solo nella Posizione Iniziale", + "create.contraptions.movement_mode.move_never_place": "Posiziona solo quando Ancora Distrutto", + "create.contraptions.movement_mode.rotate_place": "Posiziona Sempre quando è Fermo", + "create.contraptions.movement_mode.rotate_place_returned": "Posiziona solo vicino all'Angolo Iniziale", + "create.contraptions.movement_mode.rotate_never_place": "Posiziona Solo quando l'Ancora viene Distrutta", + + "create.logistics.filter": "Filtro", + "create.logistics.firstFrequency": "Freq. #1", + "create.logistics.secondFrequency": "Freq. #2", + + "create.gui.goggles.generator_stats": "Statistiche del Generatore:", + "create.gui.goggles.kinetic_stats": "Statistiche Cinetiche:", + "create.gui.goggles.at_current_speed": "Alla velocità Attuale", + "create.gui.goggles.base_value": "Valore Base", + + "create.gui.gauge.info_header": "Informazioni sul Calibro:", + "create.gui.speed_gauge.title": "Velocità di Rotazione", + "create.gui.stress_gauge.title": "Stress della Rete", + "create.gui.stress_gauge.capacity": "Capacità Rimanente", + "create.gui.stress_gauge.overstressed": "Sovrastressato", + "create.gui.stress_gauge.no_rotation": "Nessuna Rotazione", + + "create.gui.contraptions.not_fast_enough": "Sembra che questo %1$s _non_ stia girando con una _velocità_ _sufficiente_.", + "create.gui.contraptions.network_overstressed": "Sembra che questo marchingegno sia _sovraccarico_. Aggiungi più fonti o _rallenta_ i componenti con un forte _impatto_ _di_ _stress_.", + + "create.gui.flexcrate.title": "Baule Regolabile", + "create.gui.flexcrate.storageSpace": "Spazio di Immagazzinamento", + + "create.gui.stockswitch.title": "Interruttore Accumulatore", + "create.gui.stockswitch.lowerLimit": "Soglia Inferiore", + "create.gui.stockswitch.upperLimit": "Soglia Superiore", + "create.gui.stockswitch.startAt": "Inizia Segnale al", + "create.gui.stockswitch.startAbove": "Inizia il Segnale dop.", + "create.gui.stockswitch.stopAt": "Ferma Segnale al", + "create.gui.stockswitch.stopBelow": "Ferma il Segnale dop.", + "create.gui.sequenced_gearshift.title": "Cambio Sequenziale", + "create.gui.sequenced_gearshift.instruction": "Istruzione", + "create.gui.sequenced_gearshift.instruction.turn_angle": "Gira", + "create.gui.sequenced_gearshift.instruction.turn_angle.angle": "Angolo", + "create.gui.sequenced_gearshift.instruction.turn_distance": "Pistone", + "create.gui.sequenced_gearshift.instruction.turn_distance.distance": "Distanza", + "create.gui.sequenced_gearshift.instruction.wait": "Aspetta", + "create.gui.sequenced_gearshift.instruction.wait.duration": "Durata", + "create.gui.sequenced_gearshift.instruction.end": "Fine", + "create.gui.sequenced_gearshift.speed": "Velocità, Direzione", + "create.gui.sequenced_gearshift.speed.forward": "Velocità di ingresso, Avanti", + "create.gui.sequenced_gearshift.speed.forward_fast": "Doppia velocità, Avanti", + "create.gui.sequenced_gearshift.speed.back": "Velocità di ingresso, Invertita", + "create.gui.sequenced_gearshift.speed.back_fast": "Doppia velocità, Invertita", + + "create.schematicAndQuill.dimensions": "Dimensione Schematica: %1$sx%2$sx%3$s", + "create.schematicAndQuill.firstPos": "Prima posizione impostata.", + "create.schematicAndQuill.secondPos": "Seconda posizione impostata.", + "create.schematicAndQuill.noTarget": "Premi [Ctrl] per selezionare il Blocco d'Aria.", + "create.schematicAndQuill.abort": "Selezione rimossa.", + "create.schematicAndQuill.prompt": "Immettere un nome per lo schema:", + "create.schematicAndQuill.fallbackName": "La mia Schematica", + "create.schematicAndQuill.saved": "Salvata come %1$s", + + "create.schematic.invalid": "[!] Oggetto non valido - Utilizza invece il Banco Schematico", + "create.schematic.position": "Posizione", + "create.schematic.rotation": "Rotazione", + "create.schematic.rotation.none": "Nessuna", + "create.schematic.rotation.cw90": "Senso Orario 90", + "create.schematic.rotation.cw180": "Senso Orario 180", + "create.schematic.rotation.cw270": "Senso Orario 270", + "create.schematic.mirror": "Specchio", + "create.schematic.mirror.none": "Nessuno", + "create.schematic.mirror.frontBack": "Fronte-Retro", + "create.schematic.mirror.leftRight": "Sinistra-Destra", + + "create.schematic.tool.deploy": "Installa", + "create.schematic.tool.move": "Muovi XZ", + "create.schematic.tool.movey": "Muovi Y", + "create.schematic.tool.rotate": "Ruota", + "create.schematic.tool.print": "Stampa", + "create.schematic.tool.flip": "Capovolgi", + + "create.schematic.tool.deploy.description.0": "Sposta la struttura in una posizione.", + "create.schematic.tool.deploy.description.1": "Clic-Destro sul terreno per posizionarla.", + "create.schematic.tool.deploy.description.2": "premi [Ctrl] per selezionare a distanza fissa.", + "create.schematic.tool.deploy.description.3": "[Ctrl]-Scorri per cambiare la distanza.", + "create.schematic.tool.move.description.0": "Sposta la Schematica in Orizzontale.", + "create.schematic.tool.move.description.1": "Indica la Schematica e [CTRL]-Scorri per spingerla.", + "create.schematic.tool.move.description.2": "", + "create.schematic.tool.move.description.3": "", + "create.schematic.tool.movey.description.0": "Sposta la Schematica verticalmente.", + "create.schematic.tool.movey.description.1": "[CTRL]-Scorri per spostarla su/giù.", + "create.schematic.tool.movey.description.2": "", + "create.schematic.tool.movey.description.3": "", + "create.schematic.tool.rotate.description.0": "Ruota la Schematica attorno al suo centro.", + "create.schematic.tool.rotate.description.1": "[CTRL]-Scorri ruota di 90 gradi.", + "create.schematic.tool.rotate.description.2": "", + "create.schematic.tool.rotate.description.3": "", + "create.schematic.tool.print.description.0": "Posiziona istantaneamente la struttura nel mondo.", + "create.schematic.tool.print.description.1": "[Clic-Destro] per confermare la posizione corrente.", + "create.schematic.tool.print.description.2": "Questo strumento è solo per la modalità creativa.", + "create.schematic.tool.print.description.3": "", + "create.schematic.tool.flip.description.0": "Capovolge la schematica lungo la faccia selezionata.", + "create.schematic.tool.flip.description.1": "Indica la schematica e [CTRL]-Scorri per capovolgerla.", + "create.schematic.tool.flip.description.2": "", + "create.schematic.tool.flip.description.3": "", + + "create.schematics.synchronizing": "Sincronizzazione...", + "create.schematics.uploadTooLarge": "La schematica è troppo grande.", + "create.schematics.maxAllowedSize": "La dimensione massima consentita del file schematica è:", + + "create.gui.schematicTable.title": "Banco Schematico", + "create.gui.schematicTable.availableSchematics": "Schatiche disponibili", + "create.gui.schematicTable.noSchematics": "Nessuna Schatica Salvata", + "create.gui.schematicTable.uploading": "Caricamento...", + "create.gui.schematicTable.finished": "Caricamento Finito!", + + "create.gui.schematicannon.title": "Cannoneschematico", + "create.gui.schematicannon.settingsTitle": "Impostazioni di Posizionamento", + "create.gui.schematicannon.listPrinter": "Stampante Lisra dei Materiali", + "create.gui.schematicannon.gunpowderLevel": "Polvere da sparo al %1$s%%", + "create.gui.schematicannon.shotsRemaining": "Spari Rimanenti: %1$s", + "create.gui.schematicannon.shotsRemainingWithBackup": "Con il backup: %1$s", + "create.gui.schematicannon.optionEnabled": "Attualmente Abilitato", + "create.gui.schematicannon.optionDisabled": "Attualmente Disabilitato", + "create.gui.schematicannon.option.dontReplaceSolid": "Non sostituire i Blocchi Solidi", + "create.gui.schematicannon.option.replaceWithSolid": "Sostituisci Solidi con Solidi", + "create.gui.schematicannon.option.replaceWithAny": "Sostituisci Solidi con Qualsiasi", + "create.gui.schematicannon.option.replaceWithEmpty": "Sostituisci Solidi con il Vuoto", + "create.gui.schematicannon.option.skipMissing": "Salta i Blocchi Mancanti", + "create.gui.schematicannon.option.skipTileEntities": "Proteggi i Blocchi Entità", + + "create.gui.schematicannon.option.skipMissing.description": "Se il cannone non riesce a trovare un blocco richiesto per il posizionamento, continuerà nella posizione successiva.", + "create.gui.schematicannon.option.skipTileEntities.description": "Il cannone eviterà di sostituire i blocchi di dati come bauli.", + "create.gui.schematicannon.option.dontReplaceSolid.description": "Il cannone non sostituirà mai alcun blocco Solido nella sua area di lavoro, solo non solidi e aria.", + "create.gui.schematicannon.option.replaceWithSolid.description": "Il cannone sostituirà i blocchi solidi nella sua area di lavoro se lo schema contiene un blocco solido nella posizione.", + "create.gui.schematicannon.option.replaceWithAny.description": "Il cannone sostituirà i blocchi solidi nella sua area di lavoro se lo schema contiene qualche blocco nella posizione.", + "create.gui.schematicannon.option.replaceWithEmpty.description": "Il cannone eliminerà tutti i blocchi nell'area di lavoro, compresi quelli sostituiti dal aria.", + + "create.schematicannon.status.idle": "Inattivo", + "create.schematicannon.status.ready": "Pronto", + "create.schematicannon.status.running": "In Esecuzione", + "create.schematicannon.status.finished": "Finito", + "create.schematicannon.status.paused": "In Pausa", + "create.schematicannon.status.stopped": "Fermato", + "create.schematicannon.status.noGunpowder": "Niente Polvere da sparo", + "create.schematicannon.status.targetNotLoaded": "Il Blocco non è Caricato", + "create.schematicannon.status.targetOutsideRange": "Obbiettivo Troppo Lontano", + "create.schematicannon.status.searching": "Ricercando", + "create.schematicannon.status.skipping": "Saltando", + "create.schematicannon.status.missingBlock": "Bloc. Mancante:", + "create.schematicannon.status.placing": "Piazzando", + "create.schematicannon.status.clearing": "Cancellando Blocchi", + "create.schematicannon.status.schematicInvalid": "Schematica Non Valida", + "create.schematicannon.status.schematicNotPlaced": "Schematica Non Implementata", + "create.schematicannon.status.schematicExpired": "File Schematica Scaduto", + + "create.gui.filter.blacklist": "Lista Nera", + "create.gui.filter.blacklist.description": "Gli oggetti passano se NON corrispondono a nessuno dei precedenti. Una Lista Nera vuota accetta tutto.", + "create.gui.filter.whitelist": "Lista Bianca", + "create.gui.filter.whitelist.description": "Gli oggetti passano se corrispondono a uno dei precedenti. Una Lista Bianca vuota rifiuta tutto.", + "create.gui.filter.respect_data": "Rispetto dei Dati", + "create.gui.filter.respect_data.description": "Gli oggetti corrispondono solo se la loro durata, incantesimi e altri attributi corrispondono.", + "create.gui.filter.ignore_data": "Ignora Dati", + "create.gui.filter.ignore_data.description": "Gli oggetti corrispondono indipendentemente dai loro attributi.", + + "create.item_attributes.placeable": "è posizionabile", + "create.item_attributes.consumable": "può essere mangiato", + "create.item_attributes.smeltable": "può essere Fuso", + "create.item_attributes.washable": "può essere Lavato", + "create.item_attributes.smokable": "può essere Affumicato", + "create.item_attributes.blastable": "è fondibile in un Forno fusorio", + "create.item_attributes.enchanted": "è incantato", + "create.item_attributes.damaged": "è danneggiato", + "create.item_attributes.badly_damaged": "è gravemente danneggiato", + "create.item_attributes.not_stackable": "non impilabile", + "create.item_attributes.equipable": "può essere equipaggiato", + "create.item_attributes.furnace_fuel": "è il combustibile della fornace", + "create.item_attributes.in_tag": "è etichettato %1$s", + "create.item_attributes.in_item_group": "appartiene a %1$s", + "create.item_attributes.added_by": "è stato aggiunto da %1$s", + + "create.gui.attribute_filter.no_selected_attributes": "Nessun attributo selezionato", + "create.gui.attribute_filter.selected_attributes": "Attributi selezionati:", + "create.gui.attribute_filter.whitelist_disjunctive": "Lista Bianca (Qualsiasi)", + "create.gui.attribute_filter.whitelist_disjunctive.description": "Gli oggetti passano se hanno uno degli attributi selezionati.", + "create.gui.attribute_filter.whitelist_conjunctive": "Lista Bianca (Tutti)", + "create.gui.attribute_filter.whitelist_conjunctive.description": "Gli oggetti passano solo se hanno TUTTI gli attributi selezionati.", + "create.gui.attribute_filter.blacklist": "Lista Nera", + "create.gui.attribute_filter.blacklist.description": "Gli oggetti passano se NON hanno nessuno degli attributi selezionati.", + "create.gui.attribute_filter.add_reference_item": "Agg. Oggetto di Riferim.", + + "create.tooltip.holdKey": "Premi [%1$s]", + "create.tooltip.holdKeyOrKey": "Premi [%1$s] o [%2$s]", + "create.tooltip.keyShift": "Shift", + "create.tooltip.keyCtrl": "Ctrl", + + "create.tooltip.speedRequirement": "Velocità Richiesta: %1$s", + "create.tooltip.speedRequirement.none": "Nessuna", + "create.tooltip.speedRequirement.medium": "Moderata", + "create.tooltip.speedRequirement.high": "Veloce", + + "create.tooltip.stressImpact": "Impatto sullo Stress: %1$s", + "create.tooltip.stressImpact.low": "Basso", + "create.tooltip.stressImpact.medium": "Moderato", + "create.tooltip.stressImpact.high": "Alto", + "create.tooltip.stressImpact.overstressed": "Sovrastressato", + + "create.tooltip.capacityProvided": "Capacità dello Stress: %1$s", + "create.tooltip.capacityProvided.low": "Piccola", + "create.tooltip.capacityProvided.medium": "Media", + "create.tooltip.capacityProvided.high": "Grande", + "create.tooltip.capacityProvided.asGenerator": "(Come generatore)", + "create.tooltip.generationSpeed": "Genera %1$s %2$s", + + "create.tooltip.analogStrength": "Forza Analogica: %1$s/15", + + "create.tooltip.wip": "WIP", + "create.tooltip.workInProgress": "Work in progress!", + + "create.tooltip.randomWipDescription0": "Si prega di tenere questo oggetto lontano dai bambini.", + "create.tooltip.randomWipDescription1": "Un cucciolo di panda muore ogni volta che usi questo oggetto. Ogni. Volta.", + "create.tooltip.randomWipDescription2": "Da utilizzare a proprio rischio.", + "create.tooltip.randomWipDescription3": "Questo non è l'oggetto che stai cercando, *le dita si muovono* perfavore dispartene.", + "create.tooltip.randomWipDescription4": "Questo oggetto si autodistruggerà tra 10 secondi. 10, 9, 8...", + "create.tooltip.randomWipDescription5": "Credimi, è inutile.", + "create.tooltip.randomWipDescription6": "Utilizzando questo articolo, acconsenti al nostro disclaimer e accetti i suoi termini.", + "create.tooltip.randomWipDescription7": "Questo forse non fa per te. Che ne dici di quello?", + "create.tooltip.randomWipDescription8": "Usalo e rimpiangi immediatamente la tua decisione.", + + "create.mechanical_mixer.min_ingredients": "Ingredienti Min.", + + "create.command.killTPSCommand": "killtps", + "create.command.killTPSCommand.status.slowed_by.0": "[Create]: Il tick del server è attualmente rallentato di %s ms :o", + "create.command.killTPSCommand.status.slowed_by.1": "[Create]: Il tick del server è ora rallentato di %s ms >:)", + "create.command.killTPSCommand.status.slowed_by.2": "[Create]: Il tick del server è tornato alla velocità normale :D", + "create.command.killTPSCommand.status.usage.0": "[Create]: usa /killtps per riportare il tick del server alla velocità normale", + "create.command.killTPSCommand.status.usage.1": "[Create]: usa /killtps avvia per rallentare artificialmente il tick del server", + "create.command.killTPSCommand.argument.tickTime": "tickTime", + + "advancement.create:root": "All'inizio, Creiamo!", + "advancement.create:root.desc": "È il momento di iniziare a costruire alcuni meravigliosi aggeggi!", + "advancement.create:andesite_alloy": "Allitterazioni in Abbondanza", + "advancement.create:andesite_alloy.desc": "I materiali di Create hanno nomi strani, Lega di Andesite è uno di questi.", + "advancement.create:andesite_casing": "L'Era del Andesite", + "advancement.create:andesite_casing.desc": "Usa del Andesite, Ferro, e Legno per creare un Involucro di base.", + "advancement.create:crushing_wheel": "Un Paio di Giganti", + "advancement.create:crushing_wheel.desc": "Crea delle Ruote di Frantumazione per frammentare i materiali.", + "advancement.create:rotation": "È vivo!", + "advancement.create:rotation.desc": "Guarda il tuo primo componente cinetico girare.", + "advancement.create:overstressed": "Sovrastressato", + "advancement.create:overstressed.desc": "Sperimenta in prima persona le leggi della fisica.", + "advancement.create:sand_paper": "Potere Levigatore", + "advancement.create:sand_paper.desc": "Crea della Carta Vetrata per rendere le cose belle.", + "advancement.create:polished_rose_quartz": "Diamanti Rosa", + "advancement.create:polished_rose_quartz.desc": "Leviga il Quarzo Rosa fino a quando non riesci a vedere attraverso di esso.", + "advancement.create:sand_paper_secret": "Carta Vetrata Grana 9001", + "advancement.create:sand_paper_secret.desc": "Usa la tua Carta Vetrata per levigare della Carta Vetrata.", + "advancement.create:press": "'Bonk!' ", + "advancement.create:press.desc": "Crea una Pressa Meccanica e usala per creare alcune Lamiere", + "advancement.create:mixer": "Mischiando", + "advancement.create:mixer.desc": "Crea un Miscelatore Meccanico.", + "advancement.create:brass": "Una Lega Vera", + "advancement.create:brass.desc": "Usa Rame e Zinco per creare un pò di Ottone.", + "advancement.create:brass_casing": "L'Era dell'Ottone", + "advancement.create:brass_casing.desc": "Usa L'Ottone appena ottenuto e un pò di Legno per creare un Involucro più avanzato.", + "advancement.create:deployer": "Colpisci, Posiziona e Attacca", + "advancement.create:deployer.desc": "Crea un Installatore, il riflesso perfetto di te stesso.", + "advancement.create:deployer_secret": "Tirartelo, Fra!", + "advancement.create:deployer_secret.desc": "Fai due Installatori batti pugno.", + "advancement.create:chromatic_compound": "Materiali Bipolari", + "advancement.create:chromatic_compound.desc": "Crea una Barra di Composto Cromatico.", + "advancement.create:shadow_steel": "Void Returner", + "advancement.create:shadow_steel.desc": "Crea l'Acciaio Oscuro, una barra di metallo del nulla.", + "advancement.create:refined_radiance": "Luminoso e Atimolante", + "advancement.create:refined_radiance.desc": "Crea una Radiance Raffinata, una potente sostanza cromatica.", + "advancement.create:refined_radiance_secret": "Forgiato dal Raggio di Luce", + "advancement.create:refined_radiance_secret.desc": "Trova il modo alternativo per rendere la Radiance Raffinata.", + "advancement.create:speed_secret": "Bello ", + "advancement.create:speed_secret.desc": "Guarda un tachimetro raggiungere esattamente 69 rpm.", + + "create.subtitle.schematicannon_launch_block": "Tiri del Cannoneschematico", + "create.subtitle.schematicannon_finish": "Finiture Cannoneschematico", + "create.subtitle.slime_added": "Slime schiacciato", + "create.subtitle.mechanical_press_activation": "Pressa Meccanica attiva", + "create.subtitle.mechanical_press_item_break": "Metal clanks", + "create.subtitle.blockzapper_place": "Posiziona blocchi nello spazio", + "create.subtitle.blockzapper_confirm": "Ding Affermativo", + "create.subtitle.blockzapper_deny": "Boop in Calo", + "create.subtitle.block_funnel_eat": "CHOMPS a Imbuto", + + "_comment": "-------------------------] ITEM DESCRIPTIONS [------------------------------------------------", + + "item.create.example_item.tooltip": "OGGETTO DI ESEMPIO (solo un indicatore che esiste nella descrizione)", + "item.create.example_item.tooltip.summary": "Una breve descrizione dell'oggetto. La _sottolineatura_ evidenzia un termine.", + "item.create.example_item.tooltip.condition1": "Quando questo", + "item.create.example_item.tooltip.behaviour1": "Quindi questo articolo fa questo. (i comportamenti mostrati con shift)", + "item.create.example_item.tooltip.condition2": "E quando questo", + "item.create.example_item.tooltip.behaviour2": "Puoi aggiungere tutti i comportamenti che desideri", + "item.create.example_item.tooltip.control1": "Quando premi Ctrl", + "item.create.example_item.tooltip.action1": "Questi controlli vengono visualizzati.", + + "item.create.symmetry_wand.tooltip": "ASTA DI SIMETRIA", + "item.create.symmetry_wand.tooltip.summary": "Rispecchia perfettamente il posizionamento dei blocchi su piani configurati.", + "item.create.symmetry_wand.tooltip.condition1": "In Hotbar", + "item.create.symmetry_wand.tooltip.behaviour1": "Rimane attivo", + "item.create.symmetry_wand.tooltip.control1": "Clic-Destro sul Terreno", + "item.create.symmetry_wand.tooltip.action1": "_Crea_ o _Sposta_ lo Specchio", + "item.create.symmetry_wand.tooltip.control2": "Clic-Destro in Aria", + "item.create.symmetry_wand.tooltip.action2": "_Rimuove_ lo Specchio attivo", + "item.create.symmetry_wand.tooltip.control3": "Clic-Destro da Accovacciato", + "item.create.symmetry_wand.tooltip.action3": "Apre l'_Interfaccia_ _di_ _Configurazione_", + + "item.create.placement_handgun.tooltip": "POSIZIONATORE DI BLOCCHI PORTATILE", + "item.create.placement_handgun.tooltip.summary": "Nuovo gadget per posizionare o scambiare blocchi a distanza.", + "item.create.placement_handgun.tooltip.control1": "Clic-Sinistro su un Blocco", + "item.create.placement_handgun.tooltip.action1": "Imposta i blocchi posizionati dallo strumento sul blocco selezionato.", + "item.create.placement_handgun.tooltip.control2": "Clic-Destro su un Blocco", + "item.create.placement_handgun.tooltip.action2": "_Piazza_ o _Sostituisce_ il blocco selezionato.", + "item.create.placement_handgun.tooltip.control3": "Clic-Destro da Accovacciato", + "item.create.placement_handgun.tooltip.action3": "Apre l'_Interfaccia_ _di_ _Configurazione_.", + + "item.create.terrain_zapper.tooltip": "PLASMATORE DEL MONDO PORTATILE", + "item.create.terrain_zapper.tooltip.summary": "Strumento per la creazione di _paesaggi_ e _caratteristiche_ _del_ _terreno_.", + "item.create.terrain_zapper.tooltip.control1": "Clic-Sinistro su un Blocco", + "item.create.terrain_zapper.tooltip.action1": "Imposta i blocchi posizionati dallo strumento sul blocco selezionato.", + "item.create.terrain_zapper.tooltip.control2": "Clic-Destro su un Blocco", + "item.create.terrain_zapper.tooltip.action2": "Applica il _Pennello_ e lo _Strumento_ attualmente selezionati nella posizione selezionata.", + "item.create.terrain_zapper.tooltip.control3": "Clic-Destro da Accovacciato", + "item.create.terrain_zapper.tooltip.action3": "Apre l'_Interfaccia_ _di_ _Configurazione_", + + "item.create.tree_fertilizer.tooltip": "FERTILIZZANTE PER ALBERI", + "item.create.tree_fertilizer.tooltip.summary": "Una potente combinazione di minerali adatta ad accelerare la crescita di tipi di alberi comuni.", + "item.create.tree_fertilizer.tooltip.condition1": "Se utilizzato su un Arboscello", + "item.create.tree_fertilizer.tooltip.behaviour1": "Cresce gli Alberi _indipendentemente_ dalle _condizioni_ _di_ _spaziatura_", + + "item.create.deforester.tooltip": "DEFORESTATORE", + "item.create.deforester.tooltip.summary": "Un' _ascia_ _radiante_ in grado di abbattere alberi in una frazione di secondo.", + + "item.create.filter.tooltip": "FILTRO", + "item.create.filter.tooltip.summary": "_Controlla_ _gli_ _output_ e gli _input_ dei dispositivi logistici con maggiore _precisione_, confrontandoli con una _serie_ _di_ _oggetti_ o diversi _filtri_ _nidificati_.", + "item.create.filter.tooltip.condition1": "Quando si trova nello slot del filtro", + "item.create.filter.tooltip.behaviour1": "_Controlla_ il flusso degli oggetti in base alla sua _configurazione_.", + "item.create.filter.tooltip.condition2": "Clic-Destro su di esso", + "item.create.filter.tooltip.behaviour2": "Apre l'_Interfaccia_ _di_ _Configurazione_.", + + "item.create.property_filter.tooltip": "FILTRO ATTRIBUTI", + "item.create.property_filter.tooltip.summary": "_Controlla_ _gli_ _output_ e gli _input_ dei dispositivi logistici con maggiore _precisione_, abbinandolo a una _serie_ _di_ _attributi_ e _categorie_ di oggetti.", + "item.create.property_filter.tooltip.condition1": "Quando si trova nello slot del filtro", + "item.create.property_filter.tooltip.behaviour1": "_Controlla_ il flusso degli oggetti in base alla sua _configurazione_.", + "item.create.property_filter.tooltip.condition2": "Clic-Destro su di esso", + "item.create.property_filter.tooltip.behaviour2": "Apre l'_Interfaccia_ _di_ _Configurazione_.", + + "block.create.cocoa_log.tooltip": "TRONCO DI GIUNGLA CACAO", + "block.create.cocoa_log.tooltip.summary": "Un tronco della giungla che consente una più facile automazione delle _Fave_ _di_ _cacao_.", + "block.create.cocoa_log.tooltip.condition1": "Quando Maturo", + "block.create.cocoa_log.tooltip.behaviour1": "Cresce i _Baccelli_ _di_ _Cacao_ su tutti i lati.", + + "item.create.empty_blueprint.tooltip": "SCHEMATICA VUOTA", + "item.create.empty_blueprint.tooltip.summary": "Utilizzato come ingrediente per ricette e per la scrittura al _Banco_ _Schematico_.", + + "item.create.blueprint.tooltip": "SCHEMATICA", + "item.create.blueprint.tooltip.summary": "Contiene una struttura da posizionare e collocare nel mondo. Posiziona l'ologramma come desiderato e usa un _Cannoneschematico_ per costruirla.", + "item.create.blueprint.tooltip.condition1": "Quando Tenuto", + "item.create.blueprint.tooltip.behaviour1": "Può essere posizionato utilizzando gli Strumenti sullo Schermo.", + "item.create.blueprint.tooltip.control1": "Clic-Destro da Accovacciato", + "item.create.blueprint.tooltip.action1": "Apre un'_Interfaccia_ per l'immissione di _Coordinate_ esatte.", + + "item.create.blueprint_and_quill.tooltip": "SCHEMATICA E PENNA D'OCA", + "item.create.blueprint_and_quill.tooltip.summary": "Utilizzato per salvare una struttura nel tuo mondo in un file .nbt.", + "item.create.blueprint_and_quill.tooltip.condition1": "Passo 1", + "item.create.blueprint_and_quill.tooltip.behaviour1": "Seleziona due punti d'angolo usando il Clic-Destro.", + "item.create.blueprint_and_quill.tooltip.condition2": "Passo 2", + "item.create.blueprint_and_quill.tooltip.behaviour2": "_Ctrl-Scorri_ sui volti per regolare le dimensioni. Clic-Destro di nuovo per salvare.", + "item.create.blueprint_and_quill.tooltip.control1": "Clic-Destro", + "item.create.blueprint_and_quill.tooltip.action1": "Seleziona un punto d'angolo / conferma il salvataggio.", + "item.create.blueprint_and_quill.tooltip.control2": "Ctrl Premuto", + "item.create.blueprint_and_quill.tooltip.action2": "Seleziona i punti a _mezz'aria_. _Scorri_ per regolare la distanza.", + "item.create.blueprint_and_quill.tooltip.control3": "Clic-Destro da Accovacciato", + "item.create.blueprint_and_quill.tooltip.action3": "_Resetta_ e rimuove la selezione.", + + "block.create.creative_crate.tooltip": "CREATORE CANNONESCHEMATICO", + "block.create.creative_crate.tooltip.summary": "Fornisce una scorta infinita di blocchi ai _Cannoneschematici_ adiacenti.", + + "block.create.schematicannon.tooltip": "CANNONESCHEMATICO", + "block.create.schematicannon.tooltip.summary": "Spara blocchi per ricreare una _Schematica_ distribuita nel Mondo. Usa gli oggetti degli inventari adiacenti e della _Polvere da sparo_ come combustibile.", + "block.create.schematicannon.tooltip.control1": "Clic-Destro su di esso", + "block.create.schematicannon.tooltip.action1": "Apre l'_Interfaccia_", + + "block.create.schematic_table.tooltip": "BANCO SCHEMATICO", + "block.create.schematic_table.tooltip.summary": "Scrive schematiche salvate su una _Schematica_ _Vuota_.", + "block.create.schematic_table.tooltip.condition1": "Quando viene fornita una Schematica Vuota", + "block.create.schematic_table.tooltip.behaviour1": "Carica un file selezionato dalla cartella Schematics.", + + "block.create.shaft.tooltip": "ALBERO", + "block.create.shaft.tooltip.summary": "_Rotazione_ _Relè_ in linea retta.", + + "block.create.cogwheel.tooltip": "RUOTA DENTATA", + "block.create.cogwheel.tooltip.summary": "_Rotazione_ _Relè_ in linea retta e su _Ruote_ _Dentate_ adiacenti.", + + "block.create.large_cogwheel.tooltip": "RUOTA DENTATA GRANDE", + "block.create.large_cogwheel.tooltip.summary": "Una versione più grande della _Ruota_ _Dentata_, consente di _modificare_ la _Velocità_ _di_ _Rotazione_ quando è collegato alla sua controparte più piccola.", + + "block.create.encased_shaft.tooltip": "ALBERO INCASSATO", + "block.create.encased_shaft.tooltip.summary": "_Rotazione_ _Relè_ in linea retta. Adatto per propagare la rotazione attraverso le pareti.", + + "block.create.gearbox.tooltip": "RIDUTTORE", + "block.create.gearbox.tooltip.summary": "_Rotazione_ _Relè_ in _quatro_ _direzioni_ Inverte le connessioni diritte.", + + "block.create.gearshift.tooltip": "CAMBIO", + "block.create.gearshift.tooltip.summary": "Un controllo per attivare / disattivare la direzione di rotazione per gli alberi collegati.", + "block.create.gearshift.tooltip.condition1": "Quando Alimentato", + "block.create.gearshift.tooltip.behaviour1": "_Inverte_ la rotazione in uscita.", + + "block.create.clutch.tooltip": "FRIZIONE", + "block.create.clutch.tooltip.summary": "Un controllo per innestare / disinnestare la rotazione per gli alberi collegati.", + "block.create.clutch.tooltip.condition1": "Quando Alimentato", + "block.create.clutch.tooltip.behaviour1": "_Interrompe_ il trasferimento della rotazione dall'altro lato.", + + "block.create.encased_belt.tooltip": "NASTRO INCASSATO", + "block.create.encased_belt.tooltip.summary": "_Rotazione_ _Relè_ attraverso il suo blocco attaccato ai _Nastri_ _Incassati_", + "block.create.encased_belt.tooltip.condition1": "Quando Connesso", + "block.create.encased_belt.tooltip.behaviour1": "I blocchi collegati avranno la _stessa_ _velocità_ _di_ _rotazione_ e direzione esatte. Non devono affrontare allo stesso modo.", + + "block.create.adjustable_pulley.tooltip": "PULEGGIA ANALOGICA", + "block.create.adjustable_pulley.tooltip.summary": "_Rotazione_ _Relè_ attraverso il suo blocco attaccato ai _Nastri_ _Incassati_. I nastri incassati attaccati _ruoteranno_ _più_ _velocemente_ in base al _segnale_ _analogico_ _di_ _redstone_ ricevuto da questo blocco.", + "block.create.adjustable_pulley.tooltip.condition1": "Controllo Redstone", + "block.create.adjustable_pulley.tooltip.behaviour1": "Senza un segnale, _non_ _accelererà_ i nastri collegati. Con un segnale a piena forza collegato al nastro, la velocità _raddoppia_.", + + "item.create.belt_connector.tooltip": "NASTRO MECCANICO", + "item.create.belt_connector.tooltip.summary": "Collega due o più _Alberi_ con un _Nastro_ _Meccanico_. Gli alberi collegati avranno la stessa velocità e direzione di rotazione esatte. Il Nastro può fungere da _Trasportatore_ per _Oggetti_ ed _Entità_.", + "item.create.belt_connector.tooltip.control1": "Clic-Destro sui Alberi", + "item.create.belt_connector.tooltip.action1": "Seleziona l'albero come una puleggia del Nastro. Entrambi gli Alberi selezionati devono _allinearsi_ _Verticalmente_, _Orizzontalmente_, o _Diagonalmente_ verso la direzione del Nastro.", + "item.create.belt_connector.tooltip.control2": "Clic-Destro da Accovacciato", + "item.create.belt_connector.tooltip.action2": "_Reimposta_ la prima posizione selezionata per il Nastro.", + + "item.create.goggles.tooltip": "OCCHIALI DA INGEGNERE", + "item.create.goggles.tooltip.summary": "Un paio di occhiali per migliorare la tua visione con utili _informazioni_ _cinetiche_.", + "item.create.goggles.tooltip.condition1": "Quando indossati", + "item.create.goggles.tooltip.behaviour1": "Mostra gli _indicatori_ _colorati_ corrispondenti al _Livello_ _di_ _Velocità_ di un componente cinetico posizionato, nonché all'_Impatto_ _dello_ _Stress_ e la capacità dei singoli componenti.", + "item.create.goggles.tooltip.condition2": "Quando si guarda il calibro", + "item.create.goggles.tooltip.behaviour2": "Mostra informazioni dettagliate sulla _Velocità_ o lo _Stress_ della rete a cui è collegato il misuratore.", + + "item.create.wrench.tooltip": "CHIAVE INGLESE", + "item.create.wrench.tooltip.summary": "Uno strumento utile per lavorare su congegni cinetici. Può essere usato per _Ruotare_, _Smontare_ e _Configurare_ i componenti.", + "item.create.wrench.tooltip.control1": "Clic-Destro su un blocco cinetico", + "item.create.wrench.tooltip.action1": "_Ruota_ _i_ _componenti_ verso o lontano dalla faccia con cui hai interagito.", + "item.create.wrench.tooltip.control2": "Clic-Destro da Accovacciato", + "item.create.wrench.tooltip.action2": "_Smonta_ _i_ _Componenti_ _Cinetici_ e li rimette nel _tuo_ _inventario_.", + + "block.create.creative_motor.tooltip": "MOTORE", + "block.create.creative_motor.tooltip.summary": "Una fonte configurabile di _Forza_ _di_ _Rotazione_.", + + "block.create.water_wheel.tooltip": "RUOTA D'ACQUA", + "block.create.water_wheel.tooltip.summary": "Fornisce un _Forza_ _di_ _Rotazione_ prelevata da correnti d'_Acqua_ _Adiacenti_.", + + "block.create.encased_fan.tooltip": "VENTILATORE INCASSATO", + "block.create.encased_fan.tooltip.summary": "Converte la _Forza_ _di_ _Rotazione_ in _Correnti_ _d'Aria_ e ritorno. Ha una varietà di usi.", + "block.create.encased_fan.tooltip.condition1": "Quando Alimentato da Redstone", + "block.create.encased_fan.tooltip.behaviour1": "Fornisce _forza_ _di_ _rotazione_ da qualsiasi _fonte_ _di_ _calore_ immediatamente al di sotto di sé. Il ventilatore deve essere rivolto verso il basso.", + "block.create.encased_fan.tooltip.condition2": "Quando in Ruotazione", + "block.create.encased_fan.tooltip.behaviour2": "_Spinge_ o _Tira_ Entità, a seconda della velocità di Rotazione in entrata.", + "block.create.encased_fan.tooltip.condition3": "Quando soffia attraverso blocchi speciali", + "block.create.encased_fan.tooltip.behaviour3": "_Liquidi_ e particelle di _Fuoco_ vengono emessi nel flusso d'aria. Questo può essere usato per _elaborare_ _oggetti_.", + + "block.create.nozzle.tooltip": "UGELLO", + "block.create.nozzle.tooltip.summary": "Attacca la parte anteriore di un _Ventilatore_ _Incassato_ per distribuire il suo effetto sulle Entità in _tutte_ _le_ _direzioni_.", + + "block.create.hand_crank.tooltip": "MANOVELLA", + "block.create.hand_crank.tooltip.summary": "Una semplice _fonte_ di _Forza_ _di_ _Rotazione_ che richiede l'interazione dei giocatori.", + "block.create.hand_crank.tooltip.condition1": "Quando usata", + "block.create.hand_crank.tooltip.behaviour1": "Fornisce una _Forza_ _di_ _Rotazione_ a un aggeggio attaccato. _Accovacciati_ _per_ _invertire_ la rotazione.", + + "block.create.cuckoo_clock.tooltip": "OROLOGIO A CUCÙ", + "block.create.cuckoo_clock.tooltip.summary": "Artigianato raffinato per _decorare_ uno spazio e _tener_ _traccia_ _del_ _tempo_.", + "block.create.cuckoo_clock.tooltip.condition1": "Quando Ruotato", + "block.create.cuckoo_clock.tooltip.behaviour1": "Mostra l'_ora_ _corrente_ e suona una melodia due volte al giorno. Si _attiva_ una volta a mezzogiorno e al crepuscolo, non appena i _giocatori_ _possono_ _dormire_.", + + "block.create.turntable.tooltip": "PIATTO", + "block.create.turntable.tooltip.summary": "Trasforma la _Forza_ _di_ _Rotazione_ in una Raffinata Cinetosi.", + + "block.create.millstone.tooltip": "MACINA", + "block.create.millstone.tooltip.summary": "Un componente cinetico adatto per la _rettifica_ dei _materiali_ inseriti. Può essere alimentato da una ruota dentata adiacente o collegandosi all'albero nella parte inferiore. I risultati devono essere estratti dal componente.", + "block.create.millstone.tooltip.condition1": "Quando Ruotato", + "block.create.millstone.tooltip.behaviour1": "Inizia ad applicare le _ricette_ di _fresatura_ a tutti gli elementi inseriti dal lato o dalla parte superiore del blocco.", + "block.create.millstone.tooltip.condition2": "Quando Toccato con Clic-Destro", + "block.create.millstone.tooltip.behaviour2": "Raccogli manualmente gli output.", + + "block.create.crushing_wheel.tooltip": "RUOTA DI FRANTUMAZIONE", + "block.create.crushing_wheel.tooltip.summary": "Grandi ruote girevoli che _rompono_ qualsiasi cosa.", + "block.create.crushing_wheel.tooltip.condition1": "Se collegata ad altre ruote di frantumazione", + "block.create.crushing_wheel.tooltip.behaviour1": "Forma una frantumatrice per la lavorazione di una varietà di cose. I denti delle ruote devono connettersi e muoversi con la _stessa_ _velocità_ in _direzioni_ _opposte_.", + + "block.create.mechanical_press.tooltip": "PRESSA MECCANICA", + "block.create.mechanical_press.tooltip.summary": "Un pistone potente per comprimere gli oggetti sottostanti. Richiede una _Forza_ _di_ _Rotazione_ costante.", + "block.create.mechanical_press.tooltip.condition1": "Quando alimentata da Redstone", + "block.create.mechanical_press.tooltip.behaviour1": "_Inizia_ a comprimere gli oggetti rilasciati al di sotto di esso.", + "block.create.mechanical_press.tooltip.condition2": "Quando sopra a un Nastro Meccanico", + "block.create.mechanical_press.tooltip.behaviour2": "Comprime _Automaticamente_ gli oggetti che passano sul Nastro.", + "block.create.mechanical_mixer.tooltip.condition3": "Quando sopra a una Bacinella", + "block.create.mechanical_mixer.tooltip.behaviour3": "Inizia a _Compattare_ _gli_ _Oggetti_ nella bacinella ogni volta che sono presenti tutti gli ingredienti necessari.", + + "block.create.basin.tooltip": "BACINELLA", + "block.create.basin.tooltip.summary": "Un pratico _contenitore_ _di_ _oggetti_ utilizzato nella lavorazione con il _Miscelatore_ _Meccanico_ e la _Pressa_ _Meccanica_. Supporta i _Comparatori_ _Redstone_.", + + "block.create.mechanical_mixer.tooltip": "MISCELATORE MECCANICO", + "block.create.mechanical_mixer.tooltip.summary": "Una frusta cinetica per applicare qualsiasi ricetta di creazione informe agli oggetti sottostanti. Richiede una _Forza_ _di_ _Rotazione_ costante e una _Bacinella_ posizionata sotto (con uno spazio in mezzo).", + "block.create.mechanical_mixer.tooltip.condition1": "Quando sopra a una Bacinella", + "block.create.mechanical_mixer.tooltip.behaviour1": "Inizia a mescolare gli oggetti nella bacinella ogni volta che sono presenti tutti gli ingredienti necessari.", + "block.create.mechanical_mixer.tooltip.condition2": "Se utilizzato con la Chiave Inglese", + "block.create.mechanical_mixer.tooltip.behaviour2": "Configura la quantità minima di _ingredienti_ _totali_ per le ricette applicate. Utilizzare questa opzione per _escludere_ _ricette_ _indesiderate_ con ingredienti simili o meno.", + + "block.create.mechanical_crafter.tooltip": "COSTRUTTORE MECCANICO", + "block.create.mechanical_crafter.tooltip.summary": "Un assemblatore cinetico per _automatizzare_ qualsiasi ricetta di _creazione_ _modellata_. Posiziona i _multipli_ _in_ _una_ _griglia_ corrispondente alla tua ricetta, e _disponi_ _i_ _loro_ _nastri_ per creare un _flusso_ che esce dalla griglia su uno degli costruttori.", + "block.create.mechanical_crafter.tooltip.condition1": "Quando ruotato", + "block.create.mechanical_crafter.tooltip.behaviour1": "_Inizia_ _il_ _processo_ _di_ _creazione_ non appena a tutti i costruttori della griglia è stato assegnato un oggetto.", + "block.create.mechanical_crafter.tooltip.control1": "Quando Strappato sul Davanti", + "block.create.mechanical_crafter.tooltip.action1": "_Cicla_ _la_ _direzione_ verso cui un singolo costruttore _sposta_ _i_ _suoi_ _oggetti_. Per formare una griglia di lavoro, _disporre_ _i_ _nastri_ _in_ _un_ _flusso_ che sposta tutti gli oggetti verso il costruttore finale. Il costruttore finale deve puntare lontano dalla griglia.", + "block.create.mechanical_crafter.tooltip.control2": "Quando Strappato sul Dietro", + "block.create.mechanical_crafter.tooltip.action2": "_Collega_ l'_inventario_ _di_ _input_ _ dei costruttori adiacenti. Usa questo per _combinare_ _gli_ _slot_ nella griglia di creazione e _risparmiare_ _sul_ _lavoro_ _di_ _input_.", + + "block.create.furnace_engine.tooltip": "MOTORE FORNACE", + "block.create.furnace_engine.tooltip.summary": "Una potente fonte di _Potenza_ _Rotazionale_ che richiede un _forno_ _funzionante_ per funzionare.", + "block.create.furnace_engine.tooltip.condition1": "Se Collegato alla Fornace Accesa", + "block.create.furnace_engine.tooltip.behaviour1": "_Inizia_ _a_ _alimentare_ un _Volano_ posto di fronte (a 1m di distanza). Utilizza un Forno Fusorio per velocità più elevate.", + + "block.create.flywheel.tooltip": "VOLANO", + "block.create.flywheel.tooltip.summary": "Una grande ruota di metallo per _imbrigliare_ _e_ _stabilizzare_ la forza generata da un _motore_ _collegato_. I volani si collegano ai motori se sono a _1m_ di distanza e ad un _angolo_ _di_ _90°_ l'uno dall'altro.", + "block.create.flywheel.tooltip.condition1": "Se collegato a un Motore in Funzione", + "block.create.flywheel.tooltip.behaviour1": "Fornisce la _Forza_ _di_ _Rotazione_ a un aggeggio connesso in base alla forza e alla velocità del generatore.", + + "block.create.portable_storage_interface.tooltip": "INTERFACCIA DI ARCHIVIAZIONE PORTATILE", + "block.create.portable_storage_interface.tooltip.summary": "Un punto di interscambio portatile per _spostare_ _oggetti_ da e verso una _struttura_ mossa da un pistone, supporto, carrello da miniera o puleggia.", + "block.create.portable_storage_interface.tooltip.condition1": "In Movimento", + "block.create.portable_storage_interface.tooltip.behaviour1": "Interagisce con i _traspositori_ fissi in modo tale che i traspositori _rivolti_ _lontano_ dall'interfaccia _estraggano_ _gli_ _oggetti_, e i traspositori che puntano l'interfaccia _inseriranno_ _gli_ _oggetti_ dall'inventario allegato. Il congegno si arresterà brevemente quando gli oggetti vengono scambiati.", + + "block.create.rotation_speed_controller.tooltip": "REGOLATORE DI VELOCITÀ DI ROTAZIONE", + "block.create.rotation_speed_controller.tooltip.summary": "Un _relè_ _configurabile_ in grado di accelerare o rallentare il componente selezionato a qualsiasi velocità desiderata.", + "block.create.rotation_speed_controller.tooltip.condition1": "Se collegato a una Ruota Dentata Grande", + "block.create.rotation_speed_controller.tooltip.behaviour1": "Inoltra la forza di rotazione in entrata alla ruota, cercando di far _corrispondere_ la _velocità_ con cui è configurata come obbiettivo. La ruota dentata deve essere fissata sulla parte superiore del controllo.", + + "block.create.mechanical_piston.tooltip": "PISTOME MECCANICO", + "block.create.mechanical_piston.tooltip.summary": "Una versione più avanzata del _Pistone_. Usa la _Forza_ _di_ _Rotazione_ per spostare con precisione le strutture attaccate. I _Pali_ _di_ _Estensione_ _del_ _Pistone_ nella parte posteriore definiscono la _Gamma_ di questo dispositivo. Senza estensioni, il pistone non si muoverà. Usa _Telai_ o _Blocchi_ _di_ _Slime_ per muovere più di una singola linea di blocchi.", + "block.create.mechanical_piston.tooltip.condition1": "Quando Ruotato", + "block.create.mechanical_piston.tooltip.behaviour1": "Inizia a spostare la struttura collegata. La Velocità e la direzione sono correlate alla Velocità di Rotazione in entrata.", + + "block.create.sticky_mechanical_piston.tooltip": "PISTOME MECCANICO APPICCICOSO", + "block.create.sticky_mechanical_piston.tooltip.summary": "Una versione più avanzata del _Pistone_ _Appiccicoso_. Usa la _Forza_ _di_ _Rotazione_ per spostare con precisione le strutture attaccate. I _Pali_ _di_ _Estensione_ _del_ _Pistone_ nella parte posteriore definiscono la _Gamma_ di questo dispositivo. Senza estensioni, il pistone non si muoverà. Usa _Telai_ o _Blocchi_ _di_ _Slime_ per muovere più di una singola linea di blocchi.", + "block.create.sticky_mechanical_piston.tooltip.condition1": "Quando Ruotato", + "block.create.sticky_mechanical_piston.tooltip.behaviour1": "Inizia a spostare la struttura collegata. La Velocità e la direzione sono correlate alla Velocità di Rotazione in entrata.", + + "block.create.piston_pole.tooltip": "PALO PISTOME", + "block.create.piston_pole.tooltip.summary": "Estende la gamma dei _Pistoni_ _Meccanici_.", + "block.create.piston_pole.tooltip.condition1": "Se collegato al Pistone Meccanico", + "block.create.piston_pole.tooltip.behaviour1": "Estende la gamma di un pistone di 1 blocco", + + "block.create.mechanical_bearing.tooltip": "SUPPORTO MECCANICO", + "block.create.mechanical_bearing.tooltip.summary": "Utilizzato per ruotare _strutture_ _grandi_ o sfruttare la _Forza_ _di_ _Rotazione_ dal vento.", + "block.create.mechanical_bearing.tooltip.condition1": "Quando Ruotato", + "block.create.mechanical_bearing.tooltip.behaviour1": "Inizia a ruotare i blocchi collegati. Usa _Telai_ o _Blocchi_ _di_ _Slime_ per spostare più di un singolo blocco.", + "block.create.mechanical_bearing.tooltip.condition2": "Quando Alimentato da Redstone", + "block.create.mechanical_bearing.tooltip.behaviour2": "Inizia a fornire _Forza_ _di_ _Rotazione_ generata dalla rotazione della struttura collegata. La struttura deve includere _Blocchi_ _di_ _Vela_ adatti (attualmente qualsiasi blocco di lana).", + + "block.create.clockwork_bearing.tooltip": "SUPPORTO DEL OROLOGIO", + "block.create.clockwork_bearing.tooltip.summary": "Una versione avanzata del _Supporto_ _Meccanico_ per ruotare fino a due _lancette_ in base al _tempo_ _di_ _gioco_ corrente.", + "block.create.clockwork_bearing.tooltip.condition1": "Quando Ruotato", + "block.create.clockwork_bearing.tooltip.behaviour1": "Inizia a ruotare la Struttura collegata verso l'_ora_ _corrente_. Se è presente una seconda struttura, fungerà da _lancetta_ _dei_ _minuti_.", + + "block.create.sequenced_gearshift.tooltip": "CAMBIO SEQUENZIALE", + "block.create.sequenced_gearshift.tooltip.summary": "Un _componente_ _di_ _utilità_ _programmabile_, che può cambiare il suo _throughput_ _rotazionale_ secondo un massimo di _5_ _istruzioni_ _consecutive_. Utilizzalo per alimentare i Supporti Meccanici, Pistoni o Pulegge con un maggiore controllo sui tempi e sulla velocità. Può diventare meno preciso a velocità più elevate.", + "block.create.sequenced_gearshift.tooltip.condition1": "Quando alimentato da Redstone", + "block.create.sequenced_gearshift.tooltip.behaviour1": "_Inizia_ _l'esecuzione_ delle istruzioni programmate in base alla velocità in input.", + "block.create.sequenced_gearshift.tooltip.condition2": "Quando Toccato con Clic-Destro", + "block.create.sequenced_gearshift.tooltip.behaviour2": "Apre l'_Interfaccia_ _di_ _Configurazione_", + + "block.create.cart_assembler.tooltip": "ASSEMBLATORE CARRELLO DA MINIERA", + "block.create.cart_assembler.tooltip.summary": "Monta una Struttura connessa su un _Carrello_ _da_ _miniera_ di _passaggio_.", + "block.create.cart_assembler.tooltip.condition1": "Quando Alimentato da Redstone", + "block.create.cart_assembler.tooltip.behaviour1": "Smonta le strutture montate nei _carrelli_ _da_ _miniera_ di _passaggio_ e le rimette nel mondo.", + + "block.create.rope_pulley.tooltip": "PULEGGIA DELLA CORDA", + "block.create.rope_pulley.tooltip.summary": "Sposta i blocchi e le strutture collegati in verticale. Usa _Telai_ o _Blocchi_ _di_ _Slime_ per spostare più di un singolo blocco.", + "block.create.rope_pulley.tooltip.condition1": "Quando Ruotato", + "block.create.rope_pulley.tooltip.behaviour1": "Inizia a spostare la struttura collegata. La velocità e la direzione sono correlate alla Velocità di Rotazione in input.", + + "block.create.translation_chassis.tooltip": "TELAIO LINEARE", + "block.create.translation_chassis.tooltip.summary": "Un blocco base configurabile che collega le strutture per il movimento.", + "block.create.translation_chassis.tooltip.condition1": "Quando Spostato", + "block.create.translation_chassis.tooltip.behaviour1": "_Sposta_ tutti i _Telai_ _attaccati_ con lo stesso orientamento e una colonna di Blocchi all'interno della sua gamma. I blocchi verranno tirati solo se la faccia del telaio è _Appiccicosa_ (Vedi con [Ctrl]).", + "block.create.translation_chassis.tooltip.condition2": "Con Chiave Inglese", + "block.create.translation_chassis.tooltip.behaviour2": "Configura la _gamma_ per questo telaio. Premi CTRL per modificare anche la gamma di tutti i blocchi telaio collegati.", + "block.create.translation_chassis.tooltip.control1": "Quando si fa Clic-Destro con la Palla di slime", + "block.create.translation_chassis.tooltip.action1": "Crea la faccia cliccata _Appiccicosa_. Quando viene spostato, il telaio tirerà i blocchi collegati, indipendentemente dalla direzione del movimento.", + + "block.create.rotation_chassis.tooltip": "TELAIO RADIALE", + "block.create.rotation_chassis.tooltip.summary": "Un blocco base configurabile che collega le strutture per il movimento.", + "block.create.rotation_chassis.tooltip.condition1": "Quando Spostato", + "block.create.rotation_chassis.tooltip.behaviour1": "_Sposta_ tutti i _Telai_ _collegati_ in una colonna, e un cilindro di blocchi attorno a se stesso. I blocchi attorno ad esso vengono spostati solo quando si trovano nella gamma e sono attaccati a un lato appiccicoso (Vedi con [Ctrl]).", + "block.create.rotation_chassis.tooltip.condition2": "Con Chiave Inglese", + "block.create.rotation_chassis.tooltip.behaviour2": "Configura la _gamma_ per questo telaio. Premi CTRL per modificare anche la gamma di tutti i blocchi telaio collegati.", + "block.create.rotation_chassis.tooltip.control1": "Quando si fa Clic-Destro con la Palla di slime", + "block.create.rotation_chassis.tooltip.action1": "Crea la faccia cliccata _Appiccicosa_. Quando viene spostato, il telaio tirerà i blocchi collegati, indipendentemente dalla direzione del movimento.", + + "block.create.drill.tooltip": "TRAPANO MECCANICO", + "block.create.drill.tooltip.summary": "Un dispositivo meccanico adatto per _rompere_ i _blocchi_. È mobile con _Pistoni_ o _Supporti_ _meccanici_.", + "block.create.drill.tooltip.condition1": "Quando Ruotato", + "block.create.drill.tooltip.behaviour1": "Funziona come un Rompi blocchi _stazionario_. Fa anche _male_ _alle_ _entità_ nella sua area effettiva", + "block.create.drill.tooltip.condition2": "In Movimento", + "block.create.drill.tooltip.behaviour2": "Rompe i blocchi con cui il trapano si scontra.", + + "block.create.harvester.tooltip": "MIETITRICE MECCANICA", + "block.create.harvester.tooltip.summary": "Una mietitrice meccanica adatta per l'automazione delle colture di medie dimensioni. È mobile con _Pistoni_ o _Supporti_ _Meccanici_.", + "block.create.harvester.tooltip.condition1": "In Movimento", + "block.create.harvester.tooltip.behaviour1": "_Raccoglie_ tutte le _colture_ _mature_ con cui la lama si scontra e ripristina il loro stato iniziale di crescita.", + + "block.create.saw.tooltip": "SEGA MECCANICA", + "block.create.saw.tooltip.summary": "Adatto per _tagliare_ _alberi_ in modo efficace e per _tagliare_ _blocchi_ nelle loro controparti carpentate. È mobile con _Pistoni_ o _Supporti_ _Meccanici_.", + "block.create.saw.tooltip.condition1": "Di fronte", + "block.create.saw.tooltip.behaviour1": "Applica le _Ricette_ di _Segatura_ e _Lavorazione_ _della_ _Pietra_ agli oggetti rilasciati o inseriti al suo interno. Quando sono possibili gli output, le scorre ciclicamente a meno che non sia assegnato un _filtro_.", + "block.create.saw.tooltip.condition2": "Di fronte in orizzontale", + "block.create.saw.tooltip.behaviour2": "_Rompe_ i _tronchi_ di fronte a se. Se il troco supportava un albero da solo, l'albero crollerebbe lontano dalla sega.", + "block.create.saw.tooltip.condition3": "In Movimento", + "block.create.saw.tooltip.behaviour3": "_Taglia_ tutti gli _alberi_ con cui la sega si scontra.", + + "block.create.stockswitch.tooltip": "INTERRUTTORE ACCUMULATORE", + "block.create.stockswitch.tooltip.summary": "Attiva / disattiva un segnale Redstone in base allo _Spazio_ _di_ _Stoccaggio_ nel Contenitore collegato.", + "block.create.stockswitch.tooltip.condition1": "Quando inferiore al limite inferiore", + "block.create.stockswitch.tooltip.behaviour1": "Smette di fornire il _Segnale_ _Redstone_", + "block.create.stockswitch.tooltip.condition2": "Quando supera il Limite Superiore.", + "block.create.stockswitch.tooltip.behaviour2": "Inizia a fornire un _Segnale_ _Redstone_ fino al raggiungimento del limite inferiore.", + "block.create.stockswitch.tooltip.control1": "Quando Toccato con Clic-Destro", + "block.create.stockswitch.tooltip.action1": "Apre l'_Interfaccia_ _di_ _Configurazione_.", + + "block.create.redstone_bridge.tooltip": "COLLEGAMENTO REDSTONE", + "block.create.redstone_bridge.tooltip.summary": "Endpoint per connessioni _Wireless_ _di_ _Redstone_. Le _Frequenze_ possono essere assegnate utilizzando qualsiasi oggetto. La gamma del segnale è limitata, sebbene ragionevolmente lontana.", + "block.create.redstone_bridge.tooltip.condition1": "Quando Alimentato", + "block.create.redstone_bridge.tooltip.behaviour1": "La ricezione di collegamenti della stessa _Frequenza_ produrrà un segnale Redstone.", + "block.create.redstone_bridge.tooltip.control1": "Quando Clic-Destro su un oggetto", + "block.create.redstone_bridge.tooltip.action1": "Imposta la _Frequenza_ su quell'oggetto. È possibile utilizzare un totale di _due_ _oggetti_ _differenti_ in combinazione per definire una frequenza.", + "block.create.redstone_bridge.tooltip.control2": "Clic-Destro da Accovacciato", + "block.create.redstone_bridge.tooltip.action2": "Alterna tra la modalità _Ricevitore_ e _Trasmettitore_.", + + "block.create.contact.tooltip": "CONTATTO REDSTONE", + "block.create.contact.tooltip.summary": "Emette solo un segnale di pietrarossa in coppia. È mobile con _Pistoni_ o _Supporti_ _Meccanici_.", + "block.create.contact.tooltip.condition1": "Di fronte ad altri Contatti", + "block.create.contact.tooltip.behaviour1": "Fornisce un _Segnale_ _Redstone_.", + "block.create.contact.tooltip.condition2": "In Movimento", + "block.create.contact.tooltip.behaviour2": "Attiva tutti i contatti fissi che passa.", + + "block.create.flexcrate.tooltip": "BAULE REGOLABILE", + "block.create.flexcrate.tooltip.summary": "Questo _Contenitore_ _di_ _Stoccaggio_ consente il controllo manuale sulla sua capacità. Può contenere fino a _16_ _Pile_ di qualsiasi oggetto. Supporta _Comparatori_ _Redstone_.", + "block.create.flexcrate.tooltip.control1": "Quando Cliccato con Clic-Destro", + "block.create.flexcrate.tooltip.action1": "Apre l'_Interfaccia_.", + + "block.create.extractor.tooltip": "ESTRATTORE", + "block.create.extractor.tooltip.summary": "_Prende_ _Oggetti_ da un _Inventario _ allegato e li lascia cadere a terra. Non lascerà cadere gli oggetti a meno che lo spazio non sia libero. Può essere assegnata una pila di oggetti come _filtro_.", + "block.create.extractor.tooltip.condition1": "Quando alimentato da Redstone", + "block.create.extractor.tooltip.behaviour1": "_Ferma_ l'Estrattore.", + "block.create.extractor.tooltip.condition2": "Attiva Tiraggio del Nastro", + "block.create.extractor.tooltip.behaviour2": "Gli estrattori possono estrarre oggetti _da_ _nastri_ rinforzati con un _involucro_ _di_ _ottone_. Quando l'estrattore è bloccato, il _nastro_ _si_ _arresterà_.", + "block.create.extractor.tooltip.control1": "Clic-Destro sullo Spazio del Filtro", + "block.create.extractor.tooltip.action1": "Assegna la _pila_ attualmente _trattenuta_ come _Filtro_. L'estrattore estrarrà esclusivamente il _tipo_ di oggetto e il _conteggio_ della pila come filtro.", + + "block.create.transposer.tooltip": "TRASPOSITORE", + "block.create.transposer.tooltip.summary": "_Prende_ _oggetti_ da un _inventario_ allegato e li inserisce immediatamente nell'_inventario_ di destinazione. Può essere assegnata una pila di oggetti come _filtro_.", + "block.create.transposer.tooltip.condition1": "Quando Alimentato da Redstone", + "block.create.transposer.tooltip.behaviour1": "_Ferma_ il Traspositore.", + "block.create.transposer.tooltip.condition2": "Attiva Tiraggio del Nastro", + "block.create.transposer.tooltip.behaviour2": "I Traspositori possono estrarre oggetti _dai_ _nastri_ rinforzati con un _involucro_ _di_ _ottone_. Quando viene eseguito il backup del traspositore, il _nastro_ _si_ _arresterà_.", + "block.create.transposer.tooltip.control1": "Clic-Destro sullo Spazio del Filtro", + "block.create.transposer.tooltip.action1": "Assegna la _pila_ attualmente _trattenuta_ come _Filtro_. L'estrattore estrarrà esclusivamente il _tipo_ di oggetto e il _conteggio_ della pila come filtro.", + + "block.create.deployer.tooltip": "INSTALLATORE", + "block.create.deployer.tooltip.summary": "_Punzoni_, _Usi_ e _Attivazioni_. Questa macchina proverà a _imitare_ un _giocatore_ il più possibile. Può _Prendere_ e _depositare_ _oggetti_ nell'_Inventario_ adiacente. Può essere assegnata una pila di oggetti come _filtro_.", + "block.create.deployer.tooltip.condition1": "Quando Ruotato", + "block.create.deployer.tooltip.behaviour1": "Allunga il braccio e si _attiva_ nello spazio di un blocco _2m_ _davanti_ a sé.", + "block.create.deployer.tooltip.condition2": "Clic-Destro con la Chiave Inglese", + "block.create.deployer.tooltip.behaviour2": "Attiva / disattiva la modalità di perforazione. In _modalità_ _pugno_, l'Installatore tenterà di usare il suo oggetto per _rompere_ _blocchi_ o _ferire_ _entità_.", + + "block.create.linked_extractor.tooltip": "ESTRATTORE CONNESSO", + "block.create.linked_extractor.tooltip.summary": "_Prende_ _gli_ _oggetti_ da un _Inventario_ attaccato e li lascia cadere a terra. Non lascerà cadere gli oggetti a meno che lo spazio non sia libero. Può essere assegnata una pila di oggetti come _filtro_. Può essere controllato a distanza tramite un _Collegamento_ _Redstone_.", + "block.create.linked_extractor.tooltip.condition1": "Quando il Collegamento Redstone è attivo", + "block.create.linked_extractor.tooltip.behaviour1": "_Ferma_ l'Estrattore.", + "block.create.linked_extractor.tooltip.control1": "Clic-Destro sullo Spazio del Filtro", + "block.create.linked_extractor.tooltip.action1": "Assegna la _pila_ attualmente _trattenuta_ come _Filtro_. L'estrattore estrarrà esclusivamente il _tipo_ di oggetto e il _conteggio_ della pila come filtro.", + "block.create.linked_extractor.tooltip.control2": "Clic-Destro sullo Spazio di Frequenza", + "block.create.linked_extractor.tooltip.action2": "Assegna l'_oggetto_ attualmente _trattenuto_ come parte della Frequenza ascoltata. Ogni volta che viene alimentato un _Collegamento_ _Redstone_ della stessa frequenza di trasmissione, questo estrattore si mette in pausa.", + + "block.create.linked_transposer.tooltip": "TRASPOSITORE CONNESSO", + "block.create.linked_transposer.tooltip.summary": "_Prende_ _oggetti_ da un _Inventario_ allegato e li inserisce immediatamente nell'_Inventario_ di destinazione. Può essere assegnata una pila di oggetti come _filtro_. Può essere controllato a distanza tramite un _Collegamento_ _Redstone_.", + "block.create.linked_transposer.tooltip.condition1": "Quando il Collegamento Redstone è Attivo", + "block.create.linked_transposer.tooltip.behaviour1": "_Ferma_ il Traspositore.", + "block.create.linked_transposer.tooltip.control1": "Clic-Destro sullo Spazio del Filtro", + "block.create.linked_transposer.tooltip.action1": "Assegna la _pila_ attualmente _tenuta_ come _Filtro_. Il Traspositore estrae solo gli oggetti che corrispondono al tipo di oggetto e al conteggio della pila di filtri.", + "block.create.linked_transposer.tooltip.control2": "Clic-Destro sullo Spazio di Frequenza", + "block.create.linked_transposer.tooltip.action2": "Assegna l'_oggetto_ attualmente _tenuto_ come parte della Frequenza ascoltata. Ogni volta che viene alimentato un _Collegamento_ _Redstone_ della stessa frequenza di trasmissione, questo Traspositore si ferma.", + + "block.create.belt_funnel.tooltip": "IMBUTO", + "block.create.belt_funnel.tooltip.summary": "_Raccoglie_ _gli_ _oggetti_ _in_ _arrivo_ e li inserisce nell'_inventario_ allegato, se possibile. Può raccogliere oggetti nel _mondo_ e oggetti su un _nastro_.", + "block.create.belt_funnel.tooltip.condition1": "Tirare il Nastro passivamente", + "block.create.belt_funnel.tooltip.behaviour1": "Gli imbuti possono estrarre gli oggetti _dai_ _nastri_ quando vengono posizionati sopra di essi, lateralmente o alla fine. Quando viene eseguito il backup di un imbuto laterale, gli oggetti sul _nastro_ _non_ _si_ _arrestano_.", + + "block.create.belt_tunnel.tooltip": "TUNNEL TRASPORTATORE", + "block.create.belt_tunnel.tooltip.summary": "Un'opzione estetica per far passare i tuoi _Nastri_ _Meccanici_ attraverso i muri. I Nastri devono essere rinforzati con l'_Involucro_ _di_ _Ottone_. I tunnel possono _sincronizzarsi_ con _i_ _loro_ _vicini_, lasciando passare gli oggetti solo se tutti i tunnel del gruppo hanno uno in attesa. [Ctrl]", + "block.create.belt_tunnel.tooltip.control1": "Clic-Destro con la Chiave Inglese sul Davanti", + "block.create.belt_tunnel.tooltip.action1": "Attiva / Disattiva il _comportamento_ _sincronizzato_. I tunnel sincronizzati contengono oggetti fino a quando anche i loro vicini non ne hanno uno.", + "block.create.belt_tunnel.tooltip.control2": "Clic-Destro con la Chiave Inglese sul Lato", + "block.create.belt_tunnel.tooltip.action2": "_Regola_ _le_ _finestre_ se il tunnel ha una finestra su quella faccia.", + + "block.create.brass_casing.tooltip": "INVOLUCRO DI OTTONE", + "block.create.brass_casing.tooltip.summary": "Involucro delle macchine robusto con una varietà di usi. Di sicuro per la decorazione.", + "block.create.brass_casing.tooltip.condition1": "Se utilizzato su un Nastro Meccanico", + "block.create.brass_casing.tooltip.behaviour1": "_Rinforza_ _i_ _nastri_ con una base in ottone. I nastri rinforzati possono supportare i _Tunnel_ _Trasportatori_, _Estrattori_, _Imbuti_ e _Traspositori_ interagendo con i nastri dai lati e sotto.", + + "block.create.entity_detector.tooltip": "OSSERVATORE A CINGHIA", + "block.create.entity_detector.tooltip.summary": "Rileva oggetti ed entità che passano su un _Nastro_ _Meccanico_ di fronte. Usa una _Chiave_ _Inglese_ per scorrere il suo comportamento. I non oggetti verranno sempre gestiti in modalità rilevamento indipendentemente dall'impostazione.", + "block.create.entity_detector.tooltip.condition1": "Modalità di Rilevamento", + "block.create.entity_detector.tooltip.behaviour1": "Fornisce un segnale redstone _mentre_ un _oggetto_ _corrispondente_ si _trova_ nel segmento del nastro osservato.", + "block.create.entity_detector.tooltip.condition2": "Modalità a Impulsi", + "block.create.entity_detector.tooltip.behaviour2": "Emette un _impulso_ quando un _oggetto_ _corrispondente_ _passa_ al centro del segmento del nastro osservato.", + "block.create.entity_detector.tooltip.condition3": "Modalità di Espulsione", + "block.create.entity_detector.tooltip.behaviour3": "_Espelle_ _gli_ _oggetti_ _corrispondenti_ dal lato. Se il nastro bersaglio o lo spazio è _occupato_, l'oggetto verrà _tenuto_ _in_ _posizione_.", + "block.create.entity_detector.tooltip.condition4": "Modalità Divisa", + "block.create.entity_detector.tooltip.behaviour4": "_Divide_ una _pila_ _di_ _oggetti_ _corrispondenti_ ed _espelle_ _metà_ di essa dal lato.", + + "block.create.pulse_repeater.tooltip": "RIPETITORE DI IMPULSI", + "block.create.pulse_repeater.tooltip.summary": "Un semplice circuito per tagliare i segnali redstone di passaggio ad una lunghezza di _1_ _tick_.", + + "block.create.flexpeater.tooltip": "RIPETITORE REGOLABILE", + "block.create.flexpeater.tooltip.summary": "Un _Ripetitore_ _Redstone_ avanzato con un _Ritardo_ _configurabile_ fino a 30 minuti.", + + "block.create.flexpulsepeater.tooltip": "RIPETITORE DI IMPULSI REGOLABILE", + "block.create.flexpulsepeater.tooltip.summary": "Un _Ripetitore_ _di_ _Impulsi_ con un _Ritardo_ _configurabile_ fino a 30 minuti.", + + "block.create.analog_lever.tooltip": "LEVA ANALOGICA", + "block.create.analog_lever.tooltip.summary": "Una leva con un _controllo_ _più_ _preciso_ sulla _potenza_ _del_ _segnale_ emesso.", + + "block.create.toggle_latch.tooltip": "LEVA ALIMENTATA ALTERATA", + "block.create.toggle_latch.tooltip.summary": "Una leva che può essere attivata/disattivata da un _Impulso_ _Redstone_.", + + "block.create.redstone_latch.tooltip": "LEVA ALIMENTATA", + "block.create.redstone_latch.tooltip.summary": "Una leva che può essere controllata dai _Segnali_ _Redstone. Un segnale sul _retro_ _la_ _abilita_, un _segnale_ _laterale_ _la_ _resetterà_ .", + + "block.create.speed_gauge.tooltip": "TACHIMETRO", + "block.create.speed_gauge.tooltip.summary": "Misura e visualizza la _velocità_ _di_ _rotazione_ dei componenti cinetici collegati. Supporta _Comparatori_ _Redstone_.", + "block.create.speed_gauge.tooltip.condition1": "Quando Ruotato", + "block.create.speed_gauge.tooltip.behaviour1": "Indica un colore corrispondente al livello di velocità. Il _Verde_ indica una rotazione Lenta, _Blu_ Moderata e _Viola_ Veloce. Alcuni componenti meccanici richiedono un livello di velocità sufficiente per funzionare correttamente.", + + "block.create.stress_gauge.tooltip": "STRESSOMETRO", + "block.create.stress_gauge.tooltip.summary": "Misura e visualizza lo _stress_ _complessivo_ della rete cinetica collegata. Supporta _Comparatori_ _Redstone_.", + "block.create.stress_gauge.tooltip.condition1": "Quando Ruotato", + "block.create.stress_gauge.tooltip.behaviour1": "Indica un colore corrispondente al livello di stress. Le _reti_ _troppo_ _stressate_ cesseranno di muoversi. Lo stress può essere alleviato aggiungendo più _fonti_ _di_ _rotazione_ alla rete.", + + "tool.create.sand_paper.tooltip": "CARTA VETRATA", + "tool.create.sand_paper.tooltip.summary": "Una carta ruvida che può essere utilizzata per _levigare_ _materiali_ o affilare i tuoi _strumenti_.", + "tool.create.sand_paper.tooltip.condition1": "Quando Usata", + "tool.create.sand_paper.tooltip.behaviour1": "Applica la lucidatura agli oggetti _tenuti_ _in_ _mano_ o distesi a _terra_ quando _li_ _guardi_", + + "item.create.refined_radiance.tooltip": "RADIANCE RAFFINATA", + "item.create.refined_radiance.tooltip.summary": "Un Materiale Cromatico forgiato dalla _luce_ _assorbita_.", + + "item.create.shadow_steel.tooltip": "ACCIAIO OSCURO", + "item.create.shadow_steel.tooltip.summary": "Un Materiale Cromatico forgiato _nel_ _vuoto_.", + + "item.create.slot_cover.tooltip": "RIVESTIMENTO SLOT CREAZIONE", + "item.create.slot_cover.tooltip.summary": "Utilizzato per coprire uno slot vuoto in un _Costruttore_ _Meccanico_ in una ricetta. I Costruttori non devono necessariamente formare una griglia quadrata completa. Questo è utile quando ci sono ricette in cui gli _ingredienti_ _sono_ _in_ _diagonale_ tra loro.", + + "tool.create.shadow_steel.tooltip": "STRUMENTI DI ACCIAIO OSCURO", + "tool.create.shadow_steel.tooltip.summary": "Uno strumento veloce e potente che _distrugge_ _i_ _drop_ da qualsiasi blocco o entità. I mob uccisi possono far cadere _più_ _esperienza_ in base al modificatore di _Looting_ di questo strumento.", + + "tool.create.blazing.tooltip": "STRUMENTI FIAMMEGGIANTI", + "tool.create.blazing.tooltip.summary": "Questo strumento _scioglierà_ _i_ _blocchi_ _rotti_ e _incendirà_ _le_ _creature_ _attaccate_. Non perderà la Durabilità durante l'utilizzo nel l'_Inferno_ .", + + "tool.create.rose_quartz.tooltip": "STRUMENTI DI QUARZO ROSA", + "tool.create.rose_quartz.tooltip.summary": "Questo strumento ti offre una _maggiore_ _portata_ per _rompere_ _blocchi_ o _posizionare_ _blocchi_ dalla mano.", + + "itemGroup.create": "Create" +} diff --git a/src/main/resources/assets/create/lang/ja_jp.lang b/src/main/resources/assets/create/lang/ja_jp.json similarity index 100% rename from src/main/resources/assets/create/lang/ja_jp.lang rename to src/main/resources/assets/create/lang/ja_jp.json diff --git a/src/main/resources/assets/create/models/item/furnace_minecart_contraption.json b/src/main/resources/assets/create/models/item/furnace_minecart_contraption.json new file mode 100644 index 000000000..73fb1ceca --- /dev/null +++ b/src/main/resources/assets/create/models/item/furnace_minecart_contraption.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "create:item/minecart_contraption" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/minecart_contraption.json b/src/main/resources/assets/create/models/item/minecart_contraption.json new file mode 100644 index 000000000..73fb1ceca --- /dev/null +++ b/src/main/resources/assets/create/models/item/minecart_contraption.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "create:item/minecart_contraption" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/item/minecart_contraption.png b/src/main/resources/assets/create/textures/item/minecart_contraption.png new file mode 100644 index 0000000000000000000000000000000000000000..747ff905828c8c717ea6a11cc53cd87cca7087d8 GIT binary patch literal 582 zcmV-M0=fN(P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ozGLK~y+Tt&`C! zWKkT)zhg!_T5X%Tb|SnO8ZA+lRuN`O%FEU^t&~SE@=hrY5B?U9Qc4rU8Z}}cFk~{k zNUWJVvsPnfMB)2$?`^J;C*L~voO}9xKfmv}oom4xa@Tx((3Xgv-n?2{q|GML$nlWP zfupVKhY6N16ICyAl-T9Htki~7`W|ZP3hjM^*bdDXBry`uJUB8X9cip|l*0bOF6;Ul z1zUkRxLdphNlZsrURpr!&k-D*syI)kWe{?fNJA<6jKlC^0Ym`Z9}{W$#|FD56(WluL(C|_`)#>Gt8_&C|$<>ipC z>gn#3LPAG-y0E?$LTmds!@Rm0z*abnY&Iho%E|}zFMc_Fb(8U1ifnS6&Fw!ZwpbT}l{Qv*} literal 0 HcmV?d00001 diff --git a/src/main/resources/data/create/recipes/crafting_shapeless/minecart.json b/src/main/resources/data/create/recipes/crafting_shapeless/minecart.json new file mode 100644 index 000000000..38820a23b --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shapeless/minecart.json @@ -0,0 +1,17 @@ +{ + "type": "crafting_shapeless", + "ingredients": [ + [ + { + "item": "create:minecart_contraption" + }, + { + "item": "create:furnace_minecart_contraption" + } + ] + ], + "result": { + "item": "minecraft:minecart", + "count": 1 + } +} \ No newline at end of file From 8bfc4445b09248969b8feacdbc71e2d03625064a Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 1 May 2020 15:21:00 +0200 Subject: [PATCH 10/11] Minecart Issues - Fixed displaced coords between contraptions and their mounts, should fix cart structures from disappearing when loaded near chunk borders - Contraptions no longer render with default yaw if their mount is out of render distance - Fixed ploughs and other actors not activating properly when other actors had just stalled the contraption - Fixed ploughs leaving behind breaking overlays when stopped/disassembled - Fixed ploughs, drills and saws throwing entities back by unreasonable distances - Drills now break columns of falling blocks from top to bottom while moved --- .../BlockBreakingMovementBehaviour.java | 31 ++++++++++--- .../actors/PloughMovementBehaviour.java | 2 +- .../contraptions/ContraptionEntity.java | 45 ++++++++----------- .../ContraptionEntityRenderer.java | 3 ++ 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java index 438c17094..6cdb097b7 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java @@ -1,12 +1,14 @@ package com.simibubi.create.modules.contraptions.components.actors; import com.simibubi.create.foundation.utility.BlockHelper; +import com.simibubi.create.foundation.utility.Debug; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import net.minecraft.block.BlockState; import net.minecraft.block.FallingBlock; +import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity; @@ -64,7 +66,12 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { if (damageSource != null && !world.isRemote) entity.attackEntityFrom(damageSource, damage); if (throwsEntities() && (world.isRemote == (entity instanceof PlayerEntity))) { - entity.setMotion(entity.getMotion().add(context.motion.add(0, context.motion.length() / 4f, 0))); + Vec3d motionBoost = context.motion.add(0, context.motion.length() / 4f, 0); + int maxBoost = 4; + if (motionBoost.length() > maxBoost) { + motionBoost = motionBoost.subtract(motionBoost.normalize().scale(motionBoost.length() - maxBoost)); + } + entity.setMotion(entity.getMotion().add(motionBoost)); entity.velocityChanged = true; } } @@ -160,11 +167,21 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress); if (destroyProgress >= 10) { - BlockHelper.destroyBlock(context.world, breakingPos, 1f, stack -> this.dropItem(context, stack)); - context.stall = false; - onBlockBroken(context, breakingPos, stateToBreak); - ticksUntilNextProgress = -1; world.sendBlockBreakProgress(id, breakingPos, -1); + + // break falling blocks from top to bottom + BlockPos ogPos = breakingPos; + BlockState stateAbove = world.getBlockState(breakingPos.up()); + while (stateAbove.getBlock() instanceof FallingBlock) { + breakingPos = breakingPos.up(); + stateAbove = world.getBlockState(breakingPos.up()); + } + stateToBreak = world.getBlockState(breakingPos); + + context.stall = false; + BlockHelper.destroyBlock(context.world, breakingPos, 1f, stack -> this.dropItem(context, stack)); + onBlockBroken(context, ogPos, stateToBreak); + ticksUntilNextProgress = -1; data.remove("Progress"); data.remove("TicksUntilNextProgress"); data.remove("BreakingPos"); @@ -183,8 +200,8 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour { } protected void onBlockBroken(MovementContext context, BlockPos pos, BlockState brokenState) { - BlockState above = context.world.getBlockState(pos.up()); - if (!(above.getBlock() instanceof FallingBlock)) + // Check for falling blocks + if (!(brokenState.getBlock() instanceof FallingBlock)) return; CompoundNBT data = context.data; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java index 24b57f619..12fd4ea93 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/PloughMovementBehaviour.java @@ -32,7 +32,6 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public void visitNewPosition(MovementContext context, BlockPos pos) { super.visitNewPosition(context, pos); - World world = context.world; if (world.isRemote) return; @@ -72,6 +71,7 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public void stopMoving(MovementContext context) { + super.stopMoving(context); if (context.temporaryData instanceof PloughFakePlayer) ((PloughFakePlayer) context.temporaryData).remove(); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index d29371dde..2cb92b8c7 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -26,7 +26,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.item.BoatEntity; -import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.entity.item.minecart.FurnaceMinecartEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -54,7 +53,6 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; -import net.minecraft.world.server.ServerWorld; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; @@ -104,8 +102,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD contraption.gatherStoredItems(); return entity; } - - public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle, Direction facing) { + + public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle, + Direction facing) { ContraptionEntity entity = createMounted(world, contraption, initialAngle); entity.forcedAngle = facing.getHorizontalAngle(); entity.forceYaw(entity.forcedAngle); @@ -279,12 +278,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD Vec3d actorPosition = new Vec3d(blockInfo.pos); actorPosition = actorPosition.add(actor.getActiveAreaOffset(context)); actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch); - actorPosition = actorPosition.add(rotationOffset).add(posX, posY, posZ); + actorPosition = actorPosition.add(rotationOffset).add(getAnchorVec()); boolean newPosVisited = false; BlockPos gridPosition = new BlockPos(actorPosition); - if (!stalledPreviously) { + if (!context.stall) { Vec3d previousPosition = context.position; if (previousPosition != null) { context.motion = actorPosition.subtract(previousPosition); @@ -314,13 +313,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } } } - } } context.rotation = rotationVec; context.position = actorPosition; - if (actor.isActive(context)) { if (newPosVisited && !context.stall) { actor.visitNewPosition(context, gridPosition); @@ -349,6 +346,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD setPosition(posX + x, posY + y, posZ + z); } + private Vec3d getAnchorVec() { + if (contraption != null && contraption.getType() == AllContraptionTypes.MOUNTED) + return new Vec3d(posX - .5, posY, posZ - .5); + return getPositionVec(); + } + public void rotateTo(double roll, double yaw, double pitch) { rotate(getShortestAngleDiff(this.roll, roll), getShortestAngleDiff(this.yaw, yaw), getShortestAngleDiff(this.pitch, pitch)); @@ -367,25 +370,13 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override public void setPosition(double x, double y, double z) { - Entity e = getRidingEntity(); - if (e != null && e instanceof AbstractMinecartEntity) { - Entity riding = e; - while (riding.getRidingEntity() != null) - riding = riding.getRidingEntity(); - x = riding.posX - .5; - z = riding.posZ - .5; - } - - this.posX = x; - this.posY = y; - this.posZ = z; - - if (this.isAddedToWorld() && !this.world.isRemote && world instanceof ServerWorld) - ((ServerWorld) this.world).chunkCheck(this); // Forge - Process chunk registration after moving. + super.setPosition(x, y, z); if (contraption != null) { AxisAlignedBB cbox = contraption.getBoundingBox(); - if (cbox != null) - this.setBoundingBox(cbox.offset(x, y, z)); + if (cbox != null) { + Vec3d actualVec = getAnchorVec(); + this.setBoundingBox(cbox.offset(actualVec)); + } } } @@ -478,7 +469,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD compound.put("Controller", NBTUtil.writeBlockPos(controllerPos)); if (forcedAngle != -1) compound.putFloat("ForcedYaw", forcedAngle); - + compound.putFloat("InitialAngle", initialAngle); compound.putBoolean("Stalled", isStalled()); } @@ -502,7 +493,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public void disassemble() { if (getContraption() != null) { - BlockPos offset = new BlockPos(getPositionVec().add(.5, .5, .5)); + BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5)); Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1)); getContraption().addBlocksToWorld(world, offset, rotation); preventMovedEntitiesFromGettingStuck(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java index d0ff0a69b..c4b18112f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java @@ -34,6 +34,8 @@ public class ContraptionEntityRenderer extends EntityRenderer return; if (entity.getContraption() == null) return; + if (entity.getContraption().getType() == AllContraptionTypes.MOUNTED && entity.getRidingEntity() == null) + return; GlStateManager.pushMatrix(); long randomBits = (long) entity.getEntityId() * 493286711L; @@ -74,6 +76,7 @@ public class ContraptionEntityRenderer extends EntityRenderer GlStateManager.translatef((float) cartX, (float) cartY, (float) cartZ); } + GlStateManager.translatef(-.5f, 0, -.5f); } Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO); From aea5918636da1abe9497a1d4f30559f5b82a0605 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 2 May 2020 00:19:29 +0200 Subject: [PATCH 11/11] Port new code to 1.15 (help) - Shoddily eliminated compilation errors with new code from 0.2.3 --- .../behaviour/ValueBoxRenderer.java | 4 +- .../scrollvalue/ScrollValueRenderer.java | 6 +- .../block/render/WrappedBakedModel.java | 3 - .../foundation/utility/DirectionHelper.java | 7 +- .../utility/IndependentShadowRenderer.java | 1 - .../foundation/utility/SuperByteBuffer.java | 2 +- .../utility/outliner/AABBOutline.java | 64 +++----- .../utility/outliner/BlockClusterOutline.java | 3 - .../utility/outliner/ChasingAABBOutline.java | 4 - .../foundation/utility/outliner/Outline.java | 59 +++---- .../utility/outliner/OutlineParticle.java | 25 ++- .../utility/render/StructureRenderer.java | 44 ++--- .../contraptions/WrenchItemRenderer.java | 1 - .../BlockBreakingMovementBehaviour.java | 2 - .../contraptions/BlockMovementTraits.java | 2 +- .../ContraptionEntityRenderer.java | 1 + .../bearing/BearingTileEntityRenderer.java | 1 - .../contraptions/glue/SuperGlueEntity.java | 51 ++---- .../contraptions/glue/SuperGlueRenderer.java | 86 +++++----- .../mounted/MinecartContraptionItem.java | 12 +- .../MechanicalPistonTileEntityRenderer.java | 1 - .../MechanicalCrafterTileEntityRenderer.java | 1 - .../deployer/DeployerTileEntity.java | 2 +- .../particle/RotationIndicatorParticle.java | 1 - .../relays/encased/GearshiftBlock.java | 3 +- .../deforester/DeforesterItemRenderer.java | 1 - .../symmetry/SymmetryWandScreen.java | 2 - .../curiosities/zapper/ZapperScreen.java | 6 - .../TerrainzapperItemRenderer.java | 1 - .../tunnel/BeltTunnelTileEntityRenderer.java | 1 - .../block/diodes/PulseRepeaterBlock.java | 1 - .../block/SchematicTableScreen.java | 1 - .../schematics/client/SchematicRenderer.java | 153 +++++++++--------- .../client/SchematicTransformation.java | 15 +- .../schematics/client/tools/FlipTool.java | 67 ++++---- .../schematics/client/tools/RotateTool.java | 50 +++--- 36 files changed, 295 insertions(+), 389 deletions(-) diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java index bd0305919..56c8ae779 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java @@ -75,8 +75,8 @@ public class ValueBoxRenderer { } box.render(highlighted); - GlStateManager.disableBlend(); - GlStateManager.disableAlphaTest(); + RenderSystem.disableBlend(); + RenderSystem.disableAlphaTest(); } public static void renderText(ValueBox box, FontRenderer font, String text) { diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java index 5003574da..a98ed0e44 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java @@ -1,5 +1,7 @@ package com.simibubi.create.foundation.behaviour.scrollvalue; +import com.mojang.blaze3d.platform.GlStateManager.DestFactor; +import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; @@ -62,8 +64,8 @@ public class ScrollValueRenderer { render(world, pos, face, behaviour, highlight); TessellatorHelper.cleanUpAfterDrawing(); - GlStateManager.enableAlphaTest(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + RenderSystem.enableAlphaTest(); + RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); } protected static void render(ClientWorld world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour, diff --git a/src/main/java/com/simibubi/create/foundation/block/render/WrappedBakedModel.java b/src/main/java/com/simibubi/create/foundation/block/render/WrappedBakedModel.java index b2f38b2e9..8a2f84f63 100644 --- a/src/main/java/com/simibubi/create/foundation/block/render/WrappedBakedModel.java +++ b/src/main/java/com/simibubi/create/foundation/block/render/WrappedBakedModel.java @@ -3,12 +3,9 @@ package com.simibubi.create.foundation.block.render; import java.util.List; import java.util.Random; -import org.apache.commons.lang3.tuple.Pair; - import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.block.BlockState; -import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; diff --git a/src/main/java/com/simibubi/create/foundation/utility/DirectionHelper.java b/src/main/java/com/simibubi/create/foundation/utility/DirectionHelper.java index 6737e216a..e9bd8eea0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/DirectionHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/DirectionHelper.java @@ -1,6 +1,11 @@ package com.simibubi.create.foundation.utility; -import static net.minecraft.util.Direction.*; +import static net.minecraft.util.Direction.DOWN; +import static net.minecraft.util.Direction.EAST; +import static net.minecraft.util.Direction.NORTH; +import static net.minecraft.util.Direction.SOUTH; +import static net.minecraft.util.Direction.UP; +import static net.minecraft.util.Direction.WEST; import net.minecraft.util.Direction; diff --git a/src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java b/src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java index df906964c..5f112388f 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java @@ -9,7 +9,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.entity.MobEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java index f2100d5a9..b0abacbe0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java @@ -10,10 +10,10 @@ import com.simibubi.create.foundation.block.render.SpriteShiftEntry; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder.DrawState; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.Vector4f; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java index 514f92707..e07f0cb79 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java @@ -1,9 +1,8 @@ package com.simibubi.create.foundation.utility.outliner; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.foundation.utility.ColorHelper; -import com.simibubi.create.foundation.utility.GlHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; @@ -26,13 +25,9 @@ public class AABBOutline extends Outline { @Override public void render(BufferBuilder buffer) { - begin(); - Vec3d color = ColorHelper.getRGB(0xFFFFFF); float alpha = 1f; renderBB(bb, buffer, color, alpha, !disableCull); - - draw(); } public void setTextures(AllSpecialTextures faceTexture, AllSpecialTextures highlightTexture) { @@ -44,7 +39,7 @@ public class AABBOutline extends Outline { this.highlightedFace = face; } - public void renderBB(AxisAlignedBB bb, BufferBuilder buffer, Vec3d color, float alpha, boolean doCulling) { + public void renderBB(AxisAlignedBB bb, IVertexBuilder builder, Vec3d color, float alpha, boolean doCulling) { Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); boolean inside = bb.contains(projectedView); bb = bb.grow(inside ? -1 / 128d : 1 / 128d); @@ -58,46 +53,37 @@ public class AABBOutline extends Outline { Vec3d xYZ = new Vec3d(bb.minX, bb.maxY, bb.maxZ); Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ); - if (doCulling) { - GlStateManager.enableCull(); - if (inside) - GlStateManager.disableCull(); - } - - renderFace(Direction.NORTH, xYz, XYz, Xyz, xyz, buffer); - renderFace(Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, buffer); - renderFace(Direction.EAST, XYz, XYZ, XyZ, Xyz, buffer); - renderFace(Direction.WEST, xYZ, xYz, xyz, xyZ, buffer); - renderFace(Direction.UP, xYZ, XYZ, XYz, xYz, buffer); - renderFace(Direction.DOWN, xyz, Xyz, XyZ, xyZ, buffer); - - if (doCulling) - GlStateManager.enableCull(); + renderFace(Direction.NORTH, xYz, XYz, Xyz, xyz, builder); + renderFace(Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, builder); + renderFace(Direction.EAST, XYz, XYZ, XyZ, Xyz, builder); + renderFace(Direction.WEST, xYZ, xYz, xyz, xyZ, builder); + renderFace(Direction.UP, xYZ, XYZ, XYz, xYz, builder); + renderFace(Direction.DOWN, xyz, Xyz, XyZ, xyZ, builder); Vec3d start = xyz; AllSpecialTextures.BLANK.bind(); - renderAACuboidLine(start, Xyz, color, alpha, buffer); - renderAACuboidLine(start, xYz, color, alpha, buffer); - renderAACuboidLine(start, xyZ, color, alpha, buffer); + renderAACuboidLine(start, Xyz, color, alpha, builder); + renderAACuboidLine(start, xYz, color, alpha, builder); + renderAACuboidLine(start, xyZ, color, alpha, builder); start = XyZ; - renderAACuboidLine(start, xyZ, color, alpha, buffer); - renderAACuboidLine(start, XYZ, color, alpha, buffer); - renderAACuboidLine(start, Xyz, color, alpha, buffer); + renderAACuboidLine(start, xyZ, color, alpha, builder); + renderAACuboidLine(start, XYZ, color, alpha, builder); + renderAACuboidLine(start, Xyz, color, alpha, builder); start = XYz; - renderAACuboidLine(start, xYz, color, alpha, buffer); - renderAACuboidLine(start, Xyz, color, alpha, buffer); - renderAACuboidLine(start, XYZ, color, alpha, buffer); + renderAACuboidLine(start, xYz, color, alpha, builder); + renderAACuboidLine(start, Xyz, color, alpha, builder); + renderAACuboidLine(start, XYZ, color, alpha, builder); start = xYZ; - renderAACuboidLine(start, XYZ, color, alpha, buffer); - renderAACuboidLine(start, xyZ, color, alpha, buffer); - renderAACuboidLine(start, xYz, color, alpha, buffer); + renderAACuboidLine(start, XYZ, color, alpha, builder); + renderAACuboidLine(start, xyZ, color, alpha, builder); + renderAACuboidLine(start, xYz, color, alpha, builder); } - protected void renderFace(Direction direction, Vec3d p1, Vec3d p2, Vec3d p3, Vec3d p4, BufferBuilder buffer) { + protected void renderFace(Direction direction, Vec3d p1, Vec3d p2, Vec3d p3, Vec3d p4, IVertexBuilder builder) { if (direction == highlightedFace && highlightedTexture != null) highlightedTexture.bind(); else if (faceTexture != null) @@ -110,13 +96,7 @@ public class AABBOutline extends Outline { Axis axis = direction.getAxis(); float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); - - GlHelper.enableTextureRepeat(); - GlStateManager.depthMask(false); - putQuadUV(p1, p2, p3, p4, 0, 0, maxU, maxV, new Vec3d(1, 1, 1), 1, buffer); - flush(); - GlStateManager.depthMask(true); - GlHelper.disableTextureRepeat(); + putQuadUV(p1, p2, p3, p4, 0, 0, maxU, maxV, new Vec3d(1, 1, 1), 1, builder); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java index 131a24c10..93ec30de6 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java @@ -28,7 +28,6 @@ public class BlockClusterOutline extends Outline { @Override public void render(BufferBuilder buffer) { - begin(); Vec3d color = ColorHelper.getRGB(0xDDDDDD); AllSpecialTextures.SELECTION.bind(); @@ -41,7 +40,6 @@ public class BlockClusterOutline extends Outline { renderFace(pos, direction, color, alpha * .25f, 1 / 64d, buffer); } - flush(); AllSpecialTextures.BLANK.bind(); for (MergeEntry edge : cluster.visibleEdges) { @@ -51,7 +49,6 @@ public class BlockClusterOutline extends Outline { renderAACuboidLine(start, new Vec3d(edge.pos.offset(direction)), color, 1, buffer); } - draw(); } public void setAlpha(float alpha) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java index 5f6a69d59..750bca759 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java @@ -30,14 +30,10 @@ public class ChasingAABBOutline extends AABBOutline { @Override public void render(BufferBuilder buffer) { - begin(); - Vec3d color = ColorHelper.getRGB(0xFFFFFF); float alpha = 1f; renderBB(interpolateBBs(prevBB, bb, Minecraft.getInstance().getRenderPartialTicks()), buffer, color, alpha, true); - - draw(); } private static AxisAlignedBB interpolateBBs(AxisAlignedBB current, AxisAlignedBB target, float pt) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java index 02030782e..8237582a6 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java @@ -1,12 +1,9 @@ package com.simibubi.create.foundation.utility.outliner; -import org.lwjgl.opengl.GL11; - +import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; @@ -18,21 +15,7 @@ public abstract class Outline { public abstract void render(BufferBuilder buffer); - protected void begin() { - BufferBuilder buffer = Tessellator.getInstance().getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); - } - - protected void draw() { - Tessellator.getInstance().draw(); - } - - protected void flush() { - draw(); - begin(); - } - - public void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, BufferBuilder buffer) { + public void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, IVertexBuilder builder) { Vec3d diff = end.subtract(start); if (diff.x + diff.y + diff.z < 0) { Vec3d temp = start; @@ -60,17 +43,17 @@ public abstract class Outline { Vec3d a4 = plane.add(start); Vec3d b4 = plane.add(end); - putQuad(b4, b3, b2, b1, rgb, alpha, buffer); - putQuad(a1, a2, a3, a4, rgb, alpha, buffer); + putQuad(b4, b3, b2, b1, rgb, alpha, builder); + putQuad(a1, a2, a3, a4, rgb, alpha, builder); - putQuad(a1, b1, b2, a2, rgb, alpha, buffer); - putQuad(a2, b2, b3, a3, rgb, alpha, buffer); - putQuad(a3, b3, b4, a4, rgb, alpha, buffer); - putQuad(a4, b4, b1, a1, rgb, alpha, buffer); + putQuad(a1, b1, b2, a2, rgb, alpha, builder); + putQuad(a2, b2, b3, a3, rgb, alpha, builder); + putQuad(a3, b3, b4, a4, rgb, alpha, builder); + putQuad(a4, b4, b1, a1, rgb, alpha, builder); } protected void renderFace(BlockPos pos, Direction face, Vec3d rgb, float alpha, double scaleOffset, - BufferBuilder buffer) { + IVertexBuilder builder) { Vec3d center = VecHelper.getCenterOf(pos); Vec3d offset = new Vec3d(face.getDirectionVec()); Vec3d plane = VecHelper.planeByNormal(offset); @@ -88,27 +71,27 @@ public abstract class Outline { plane = VecHelper.rotate(plane, deg, axis); Vec3d a4 = plane.add(center); - putQuad(a1, a2, a3, a4, rgb, alpha, buffer); + putQuad(a1, a2, a3, a4, rgb, alpha, builder); } - public void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, BufferBuilder buffer) { - putQuadUV(v1, v2, v3, v4, 0, 0, 1, 1, rgb, alpha, buffer); + public void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, IVertexBuilder builder) { + putQuadUV(v1, v2, v3, v4, 0, 0, 1, 1, rgb, alpha, builder); } - public void putQuadUV(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU, float minV, float maxU, - float maxV, Vec3d rgb, float alpha, BufferBuilder buffer) { - putVertex(v1, rgb, minU, minV, alpha, buffer); - putVertex(v2, rgb, maxU, minV, alpha, buffer); - putVertex(v3, rgb, maxU, maxV, alpha, buffer); - putVertex(v4, rgb, minU, maxV, alpha, buffer); + public void putQuadUV(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU, float minV, float maxU, float maxV, + Vec3d rgb, float alpha, IVertexBuilder builder) { + putVertex(v1, rgb, minU, minV, alpha, builder); + putVertex(v2, rgb, maxU, minV, alpha, builder); + putVertex(v3, rgb, maxU, maxV, alpha, builder); + putVertex(v4, rgb, minU, maxV, alpha, builder); } - protected void putVertex(Vec3d pos, Vec3d rgb, float u, float v, float alpha, BufferBuilder buffer) { + protected void putVertex(Vec3d pos, Vec3d rgb, float u, float v, float alpha, IVertexBuilder builder) { int i = 15 << 20 | 15 << 4; int j = i >> 16 & '\uffff'; int k = i & '\uffff'; - buffer.pos(pos.x, pos.y, pos.z).tex(u, v).color((float) rgb.x, (float) rgb.y, (float) rgb.z, alpha) - .lightmap(j, k).endVertex(); + builder.vertex(pos.x, pos.y, pos.z).texture(u, v).color((float) rgb.x, (float) rgb.y, (float) rgb.z, alpha) + .light(j, k).endVertex(); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java index 83bc63d22..024284a3f 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/OutlineParticle.java @@ -1,13 +1,12 @@ package com.simibubi.create.foundation.utility.outliner; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.vertex.IVertexBuilder; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.particle.IParticleRenderType; import net.minecraft.client.particle.Particle; import net.minecraft.client.renderer.ActiveRenderInfo; -import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -24,7 +23,8 @@ public class OutlineParticle extends Particle { public static OutlineParticle create(O outline) { Minecraft mc = Minecraft.getInstance(); ClientPlayerEntity player = mc.player; - OutlineParticle effect = new OutlineParticle<>(outline, mc.world, player.posX, player.posY, player.posZ); + OutlineParticle effect = + new OutlineParticle<>(outline, mc.world, player.getX(), player.getY(), player.getZ()); mc.particles.addEffect(effect); return effect; } @@ -34,18 +34,13 @@ public class OutlineParticle extends Particle { } @Override - public void renderParticle(BufferBuilder buffer, ActiveRenderInfo entityIn, float partialTicks, float rotationX, - float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { - GlStateManager.pushMatrix(); - Vec3d view = entityIn.getProjectedView(); - GlStateManager.translated(-view.x, -view.y, -view.z); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - - GlStateManager.enableBlend(); - getOutline().render(buffer); - GlStateManager.disableBlend(); - - GlStateManager.popMatrix(); + public void buildGeometry(IVertexBuilder builder, ActiveRenderInfo renderInfo, float p_225606_3_) { + Vec3d view = renderInfo.getProjectedView(); +// GlStateManager.translated(-view.x, -view.y, -view.z); +// TODO +// GlStateManager.enableBlend(); +// getOutline().render(buffer); +// GlStateManager.disableBlend(); } @Override diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java b/src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java index 48916d775..dd26d6b16 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/StructureRenderer.java @@ -2,15 +2,20 @@ package com.simibubi.create.foundation.utility.render; import java.util.Iterator; -import com.mojang.blaze3d.platform.GLX; -import com.mojang.blaze3d.platform.GlStateManager; +import org.lwjgl.opengl.GL13; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.Create; import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.WrappedWorld; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.crash.ReportedException; import net.minecraft.tileentity.TileEntity; @@ -23,20 +28,17 @@ public class StructureRenderer { protected static LightingWorld lightingWorld; public static void renderTileEntities(World world, Vec3d position, Vec3d rotation, - Iterable customRenderTEs) { - TileEntityRendererDispatcher dispatcher = TileEntityRendererDispatcher.instance; + Iterable customRenderTEs, MatrixStack ms, IRenderTypeBuffer buffer) { float pt = Minecraft.getInstance().getRenderPartialTicks(); - World prevDispatcherWorld = dispatcher.world; if (lightingWorld == null) lightingWorld = new LightingWorld(world); lightingWorld.setWorld(world); lightingWorld.setTransform(position, rotation); - dispatcher.setWorld(lightingWorld); for (Iterator iterator = customRenderTEs.iterator(); iterator.hasNext();) { TileEntity tileEntity = iterator.next(); - if (dispatcher.getRenderer(tileEntity) == null) { + if (TileEntityRendererDispatcher.instance.getRenderer(tileEntity) == null) { iterator.remove(); continue; } @@ -45,20 +47,20 @@ public class StructureRenderer { BlockPos pos = tileEntity.getPos(); if (!tileEntity.hasFastRenderer()) { - RenderHelper.enableStandardItemLighting(); - int i = lightingWorld.getCombinedLight(pos, 0); - int j = i % 65536; - int k = i / 65536; - GLX.glMultiTexCoord2f(GLX.GL_TEXTURE1, (float) j, (float) k); - GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); + RenderHelper.enable(); + int i = WorldRenderer.getLightmapCoordinates(lightingWorld, pos); + int j = LightTexture.getBlockLightCoordinates(i); + int k = LightTexture.getSkyLightCoordinates(i); + RenderSystem.glMultiTexCoord2f(GL13.GL_TEXTURE1, (float) j, (float) k); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); } + RenderSystem.disableCull(); World prevTileWorld = tileEntity.getWorld(); - tileEntity.setWorld(lightingWorld); - GlStateManager.disableCull(); - dispatcher.render(tileEntity, pos.getX(), pos.getY(), pos.getZ(), pt, -1, true); - GlStateManager.enableCull(); - tileEntity.setWorld(prevTileWorld); + tileEntity.setLocation(lightingWorld, pos); + TileEntityRendererDispatcher.instance.render(tileEntity, pt, ms, buffer); + tileEntity.setLocation(prevTileWorld, pos); + RenderSystem.enableCull(); } catch (ReportedException e) { if (AllConfigs.CLIENT.explainRenderErrors.get()) { @@ -72,8 +74,6 @@ public class StructureRenderer { continue; } } - - dispatcher.setWorld(prevDispatcherWorld); } private static class LightingWorld extends WrappedWorld { @@ -95,8 +95,8 @@ public class StructureRenderer { } @Override - public int getCombinedLight(BlockPos pos, int minLight) { - return super.getCombinedLight(transformPos(pos), minLight); + public int getBaseLightLevel(BlockPos pos, int minLight) { + return super.getBaseLightLevel(transformPos(pos), minLight); } private BlockPos transformPos(BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/WrenchItemRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/WrenchItemRenderer.java index ee4e86e91..5aa3b2276 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/WrenchItemRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/WrenchItemRenderer.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.contraptions; import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java index 6cdb097b7..cfaa5a87f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/actors/BlockBreakingMovementBehaviour.java @@ -1,14 +1,12 @@ package com.simibubi.create.modules.contraptions.components.actors; import com.simibubi.create.foundation.utility.BlockHelper; -import com.simibubi.create.foundation.utility.Debug; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import net.minecraft.block.BlockState; import net.minecraft.block.FallingBlock; -import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java index 96e7419cb..b2ed5c4c6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java @@ -12,9 +12,9 @@ import com.simibubi.create.modules.contraptions.components.contraptions.chassis. import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock; -import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock; import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock; +import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity; import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock; import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java index a8b265b80..9b062e6c1 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntityRenderer.java @@ -1,6 +1,7 @@ package com.simibubi.create.modules.contraptions.components.contraptions; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.foundation.utility.VecHelper; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingTileEntityRenderer.java index 1956152de..c8252b30b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingTileEntityRenderer.java @@ -7,7 +7,6 @@ import com.simibubi.create.foundation.utility.SuperByteBuffer; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; -import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java index e21d2cb27..d55e0bd64 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueEntity.java @@ -64,7 +64,8 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat } @Override - protected void registerData() {} + protected void registerData() { + } public int getWidthPixels() { return 12; @@ -104,12 +105,10 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat protected void updateBoundingBox() { if (this.getFacingDirection() != null) { - this.posX = - (double) this.hangingPosition.getX() + 0.5 - (double) this.getFacingDirection().getXOffset() * 0.5; - this.posY = - (double) this.hangingPosition.getY() + 0.5 - (double) this.getFacingDirection().getYOffset() * 0.5; - this.posZ = - (double) this.hangingPosition.getZ() + 0.5 - (double) this.getFacingDirection().getZOffset() * 0.5; + double x = hangingPosition.getX() + 0.5 - facingDirection.getXOffset() * 0.5; + double y = hangingPosition.getY() + 0.5 - facingDirection.getYOffset() * 0.5; + double z = hangingPosition.getZ() + 0.5 - facingDirection.getZOffset() * 0.5; + this.setPos(x, y, z); double d1 = (double) this.getWidthPixels(); double d2 = (double) this.getHeightPixels(); double d3 = (double) this.getWidthPixels(); @@ -130,16 +129,12 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat d1 = d1 / 32.0D; d2 = d2 / 32.0D; d3 = d3 / 32.0D; - this.setBoundingBox(new AxisAlignedBB(this.posX - d1, this.posY - d2, this.posZ - d3, this.posX + d1, - this.posY + d2, this.posZ + d3)); + this.setBoundingBox(new AxisAlignedBB(x - d1, y - d2, z - d3, x + d1, y + d2, z + d3)); } } @Override public void tick() { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; if (this.validationTimer++ == 10 && !this.world.isRemote) { this.validationTimer = 0; if (isAlive() && !this.onValidSurface()) { @@ -216,24 +211,6 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat return AllItems.SUPER_GLUE.asStack(); } - @Override - @OnlyIn(Dist.CLIENT) - public int getBrightnessForRender() { - BlockPos blockpos = hangingPosition; - BlockPos blockpos2 = blockpos.offset(this.getFacingDirection().getOpposite()); - - PlayerEntity player = Minecraft.getInstance().player; - boolean holdingGlue = AllItems.SUPER_GLUE.typeOf(player.getHeldItemMainhand()) - || AllItems.SUPER_GLUE.typeOf(player.getHeldItemOffhand()); - boolean visible = world.isAirBlock(blockpos) || world.isAirBlock(blockpos2); - - int minLight = holdingGlue && !visible ? 8 : 0; - int light = this.world.isBlockPresent(blockpos) ? this.world.getCombinedLight(blockpos, minLight) : 15; - int light2 = this.world.isBlockPresent(blockpos2) ? this.world.getCombinedLight(blockpos2, minLight) : 15; - - return Math.max(light, light2); - } - @Override public void applyEntityCollision(Entity entityIn) { super.applyEntityCollision(entityIn); @@ -290,11 +267,11 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat } @Override - public ItemEntity entityDropItem(ItemStack stack, float offsetY) { + public ItemEntity entityDropItem(ItemStack stack, float yOffset) { + float xOffset = (float) this.getFacingDirection().getXOffset() * 0.15F; + float zOffset = (float) this.getFacingDirection().getZOffset() * 0.15F; ItemEntity itementity = - new ItemEntity(this.world, this.posX + (double) ((float) this.getFacingDirection().getXOffset() * 0.15F), - this.posY + (double) offsetY, - this.posZ + (double) ((float) this.getFacingDirection().getZOffset() * 0.15F), stack); + new ItemEntity(this.world, this.getX() + xOffset, this.getY() + yOffset, this.getZ() + zOffset, stack); itementity.setDefaultPickupDelay(); this.world.addEntity(itementity); return itementity; @@ -356,10 +333,12 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat } @Override - public void onStruckByLightning(LightningBoltEntity lightningBolt) {} + public void onStruckByLightning(LightningBoltEntity lightningBolt) { + } @Override - public void recalculateSize() {} + public void recalculateSize() { + } public static EntityType.Builder build(EntityType.Builder builder) { @SuppressWarnings("unchecked") diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java index 2e595f9d0..45d7cd36b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/glue/SuperGlueRenderer.java @@ -1,19 +1,17 @@ package com.simibubi.create.modules.contraptions.components.contraptions.glue; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllItems; import com.simibubi.create.Create; import com.simibubi.create.config.AllConfigs; -import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererManager; -import net.minecraft.client.renderer.model.PositionTextureVertex; -import net.minecraft.client.renderer.model.TexturedQuad; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; @@ -29,8 +27,8 @@ public class SuperGlueRenderer extends EntityRenderer { private ResourceLocation regular = new ResourceLocation(Create.ID, "textures/entity/super_glue/slime.png"); private ResourceLocation ghostly = new ResourceLocation(Create.ID, "textures/entity/super_glue/ghostly.png"); - private TexturedQuad quad1; - private TexturedQuad quad2; + private Vec3d[] quad1; + private Vec3d[] quad2; public SuperGlueRenderer(EntityRendererManager renderManager) { super(renderManager); @@ -38,15 +36,17 @@ public class SuperGlueRenderer extends EntityRenderer { } @Override - protected ResourceLocation getEntityTexture(SuperGlueEntity entity) { + public ResourceLocation getEntityTexture(SuperGlueEntity entity) { return isVisible(entity) ? regular : ghostly; } - @Override - public void doRender(SuperGlueEntity entity, double x, double y, double z, float entityYaw, float partialTicks) { - Direction facing = entity.getFacingDirection(); - PlayerEntity player = Minecraft.getInstance().player; + @Override // TODO what are these floats for? + public void render(SuperGlueEntity entity, float p_225623_2_, float p_225623_3_, MatrixStack ms, + IRenderTypeBuffer buffer, int light) { + super.render(entity, p_225623_2_, p_225623_3_, ms, buffer, light); + IVertexBuilder builder = buffer.getBuffer(RenderType.getEntityCutout(getEntityTexture(entity))); + PlayerEntity player = Minecraft.getInstance().player; boolean visible = isVisible(entity); boolean holdingGlue = AllItems.SUPER_GLUE.typeOf(player.getHeldItemMainhand()) || AllItems.SUPER_GLUE.typeOf(player.getHeldItemOffhand()); @@ -55,27 +55,22 @@ public class SuperGlueRenderer extends EntityRenderer { if (!visible && !holdingGlue) return; - GlStateManager.pushMatrix(); - GlStateManager.translated(x, y, z); - GlStateManager.rotated(AngleHelper.horizontalAngle(facing), 0, 1, 0); - GlStateManager.rotated(AngleHelper.verticalAngle(facing), 1, 0, 0); +// GlStateManager.pushMatrix(); TODO find equivalent +// GlStateManager.translated(x, y, z); +// GlStateManager.rotated(AngleHelper.horizontalAngle(facing), 0, 1, 0); +// GlStateManager.rotated(AngleHelper.verticalAngle(facing), 1, 0, 0); +// if (!visible) { +// GlStateManager.color4f(1, 1, 1, 0.375f); +// GlStateManager.enableBlend(); +// GlStateManager.disableDepthTest(); +// } + + // TODO use quad1 & quad2 to render the glue texture - BufferBuilder buffer = Tessellator.getInstance().getBuffer(); - bindEntityTexture(entity); - - if (!visible) { - GlStateManager.color4f(1, 1, 1, 0.375f); - GlStateManager.enableBlend(); - GlStateManager.disableDepthTest(); - } - - quad1.draw(buffer, 1); - quad2.draw(buffer, 1); - - GlStateManager.disableBlend(); - GlStateManager.enableDepthTest(); - GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.popMatrix(); +// GlStateManager.disableBlend(); +// GlStateManager.enableDepthTest(); +// GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); +// GlStateManager.popMatrix(); } private boolean isVisible(SuperGlueEntity entity) { @@ -108,18 +103,21 @@ public class SuperGlueRenderer extends EntityRenderer { Vec3d a4 = plane.add(start); Vec3d b4 = plane.add(end); - PositionTextureVertex v11 = new PositionTextureVertex(a1, 1, 0); - PositionTextureVertex v12 = new PositionTextureVertex(a2, 1, 1); - PositionTextureVertex v13 = new PositionTextureVertex(a3, 0, 1); - PositionTextureVertex v14 = new PositionTextureVertex(a4, 0, 0); + quad1 = new Vec3d[] { a1, a2, a3, a4 }; + quad2 = new Vec3d[] { b1, b2, b3, b4 }; - PositionTextureVertex v21 = new PositionTextureVertex(b1, 1, 0); - PositionTextureVertex v22 = new PositionTextureVertex(b2, 1, 1); - PositionTextureVertex v23 = new PositionTextureVertex(b3, 0, 1); - PositionTextureVertex v24 = new PositionTextureVertex(b4, 0, 0); - - quad1 = new TexturedQuad(new PositionTextureVertex[] { v14, v11, v12, v13 }, 0, 0, 16, 16, 16, 16); - quad2 = new TexturedQuad(new PositionTextureVertex[] { v21, v24, v23, v22 }, 0, 0, 16, 16, 16, 16); +// PositionTextureVertex v11 = new PositionTextureVertex(a1, 1, 0); +// PositionTextureVertex v12 = new PositionTextureVertex(a2, 1, 1); +// PositionTextureVertex v13 = new PositionTextureVertex(a3, 0, 1); +// PositionTextureVertex v14 = new PositionTextureVertex(a4, 0, 0); +// +// PositionTextureVertex v21 = new PositionTextureVertex(b1, 1, 0); +// PositionTextureVertex v22 = new PositionTextureVertex(b2, 1, 1); +// PositionTextureVertex v23 = new PositionTextureVertex(b3, 0, 1); +// PositionTextureVertex v24 = new PositionTextureVertex(b4, 0, 0); +// +// quad1 = new TexturedQuad(new PositionTextureVertex[] { v14, v11, v12, v13 }, 0, 0, 16, 16, 16, 16); +// quad2 = new TexturedQuad(new PositionTextureVertex[] { v21, v24, v23, v22 }, 0, 0, 16, 16, 16, 16); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MinecartContraptionItem.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MinecartContraptionItem.java index d2a0feea6..896c8e9de 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MinecartContraptionItem.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MinecartContraptionItem.java @@ -138,8 +138,8 @@ public class MinecartContraptionItem extends Item { } } - public static void addContraptionToMinecart(World world, ItemStack itemstack, - AbstractMinecartEntity abstractminecartentity, @Nullable Direction newFacing) { + public static void addContraptionToMinecart(World world, ItemStack itemstack, AbstractMinecartEntity cart, + @Nullable Direction newFacing) { CompoundNBT tag = itemstack.getOrCreateTag(); if (tag.contains("Contraption")) { CompoundNBT contraptionTag = tag.getCompound("Contraption"); @@ -152,9 +152,8 @@ public class MinecartContraptionItem extends Item { else contraption = ContraptionEntity.createMounted(world, mountedContraption, initialAngle); - contraption.startRiding(abstractminecartentity); - contraption.setPosition(abstractminecartentity.posX, abstractminecartentity.posY, - abstractminecartentity.posZ); + contraption.startRiding(cart); + contraption.setPosition(cart.getX(), cart.getY(), cart.getZ()); world.addEntity(contraption); } } @@ -165,7 +164,8 @@ public class MinecartContraptionItem extends Item { } @Override - public void fillItemGroup(ItemGroup group, NonNullList items) {} + public void fillItemGroup(ItemGroup group, NonNullList items) { + } @SubscribeEvent public static void wrenchCanBeUsedToPickUpMinecartContraptions(PlayerInteractEvent.EntityInteract event) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntityRenderer.java index ba99c37db..4f7813301 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/MechanicalPistonTileEntityRenderer.java @@ -6,7 +6,6 @@ import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import net.minecraft.block.BlockState; -import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.state.properties.BlockStateProperties; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java index 67df7f724..577bb20b5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/crafter/MechanicalCrafterTileEntityRenderer.java @@ -19,7 +19,6 @@ import com.simibubi.create.modules.contraptions.components.crafter.RecipeGridHan import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; -import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.WorldRenderer; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java index 0087f8eda..204b5c8b1 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java @@ -42,8 +42,8 @@ import net.minecraft.util.math.RayTraceContext.FluidMode; import net.minecraft.util.math.Vec3d; import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java b/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java index c2b967fa4..fd83dcf91 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/particle/RotationIndicatorParticle.java @@ -13,7 +13,6 @@ import net.minecraft.client.particle.IParticleFactory; import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.SimpleAnimatedParticle; import net.minecraft.client.renderer.ActiveRenderInfo; -import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java index ef370c071..c9e17daea 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/GearshiftBlock.java @@ -20,6 +20,7 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.TickPriority; import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; public class GearshiftBlock extends EncasedShaftBlock implements ITE { @@ -81,7 +82,7 @@ public class GearshiftBlock extends EncasedShaftBlock implements ITE usedBlockRenderLayers = new HashSet<>(RenderType.getBlockLayers().size()); + private final Set startedBufferBuilders = new HashSet<>(RenderType.getBlockLayers().size()); private boolean active; private boolean changed; private SchematicWorld schematic; - private AABBOutline outline; private BlockPos anchor; public SchematicRenderer() { @@ -71,95 +73,98 @@ public class SchematicRenderer { changed = false; } - public void render() { + public void render(MatrixStack ms, IRenderTypeBuffer buffer) { + // TODO 1.15 buffered render if (!active) return; - GlStateManager.disableCull(); - GlStateManager.enableAlphaTest(); - GlStateManager.depthMask(true); + final Entity entity = Minecraft.getInstance().getRenderViewEntity(); + + if (entity == null) { + return; + } + + ActiveRenderInfo renderInfo = Minecraft.getInstance().gameRenderer.getActiveRenderInfo(); + Vec3d view = renderInfo.getProjectedView(); + double renderPosX = view.x; + double renderPosY = view.y; + double renderPosZ = view.z; + + RenderSystem.enableAlphaTest(); + RenderSystem.enableBlend(); Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); - for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) - if (usedBlockRenderLayers[blockRenderLayerId]) - drawBuffer(bufferCache.getBuilder(blockRenderLayerId)); - - GlStateManager.pushMatrix(); - Vec3d position = new Vec3d(anchor); - Vec3d rotation = Vec3d.ZERO; - StructureRenderer.renderTileEntities(schematic, position, rotation, schematic.getTileEntities()); - GlStateManager.popMatrix(); + for (RenderType layer : RenderType.getBlockLayers()) { + if (!usedBlockRenderLayers.contains(layer)) { + continue; + } + final BufferBuilder bufferBuilder = bufferCache.get(layer); + RenderSystem.pushMatrix(); + RenderSystem.translated(-renderPosX, -renderPosY, -renderPosZ); + drawBuffer(bufferBuilder); + RenderSystem.popMatrix(); + } + RenderSystem.disableAlphaTest(); + RenderSystem.disableBlend(); } private void redraw(Minecraft minecraft) { - Arrays.fill(usedBlockRenderLayers, false); - Arrays.fill(startedBufferBuilders, false); + usedBlockRenderLayers.clear(); + startedBufferBuilders.clear(); + + final SchematicWorld blockAccess = schematic; + final BlockRendererDispatcher blockRendererDispatcher = minecraft.getBlockRendererDispatcher(); - SchematicWorld blockAccess = schematic; - blockAccess.renderMode = true; - BlockRendererDispatcher blockRendererDispatcher = minecraft.getBlockRendererDispatcher(); List blockstates = new LinkedList<>(); - BlockPos min = blockAccess.getBounds().getOrigin(); - BlockPos max = min.add(blockAccess.getBounds().getSize()); - outline = new AABBOutline(new AxisAlignedBB(min, max)); - outline.setTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED); - for (BlockPos localPos : BlockPos.getAllInBoxMutable(min, max)) { + for (BlockPos localPos : BlockPos.getAllInBoxMutable(blockAccess.getBounds().getOrigin(), + blockAccess.getBounds().getOrigin().add(blockAccess.getBounds().getSize()))) { BlockPos pos = localPos.add(anchor); BlockState state = blockAccess.getBlockState(pos); - - for (BlockRenderLayer blockRenderLayer : BlockRenderLayer.values()) { - if (!state.getBlock().canRenderInLayer(state, blockRenderLayer)) + for (RenderType blockRenderLayer : RenderType.getBlockLayers()) { + if (!RenderTypeLookup.canRenderInLayer(state, blockRenderLayer)) { continue; + } ForgeHooksClient.setRenderLayer(blockRenderLayer); - - final int blockRenderLayerId = blockRenderLayer.ordinal(); - final BufferBuilder bufferBuilder = bufferCache.getBuilder(blockRenderLayerId); - if (!startedBufferBuilders[blockRenderLayerId]) { - startedBufferBuilders[blockRenderLayerId] = true; - bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + final BufferBuilder bufferBuilder = bufferCache.get(blockRenderLayer); + if (startedBufferBuilders.add(blockRenderLayer)) { + // Copied from RenderChunk + { + bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + } } - usedBlockRenderLayers[blockRenderLayerId] |= blockRendererDispatcher.renderBlock(state, pos, - blockAccess, bufferBuilder, minecraft.world.rand, EmptyModelData.INSTANCE); + // Block transformations + if (state.getBlock() instanceof BedBlock) { + state = Blocks.QUARTZ_SLAB.getDefaultState(); + } + + if (blockRendererDispatcher.renderModel(state, pos, blockAccess, new MatrixStack(), bufferBuilder, true, + minecraft.world.rand, EmptyModelData.INSTANCE)) { + usedBlockRenderLayers.add(blockRenderLayer); + } blockstates.add(state); } ForgeHooksClient.setRenderLayer(null); } - + // finishDrawing - blockAccess.renderMode = false; - for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) { - if (!startedBufferBuilders[blockRenderLayerId]) + for (RenderType layer : RenderType.getBlockLayers()) { + if (!startedBufferBuilders.contains(layer)) { continue; - bufferCache.getBuilder(blockRenderLayerId).finishDrawing(); + } + bufferCache.get(layer).finishDrawing(); } } - // Coppied from the Tesselator's vboUploader - Draw everything but don't - // reset the buffer private static void drawBuffer(final BufferBuilder bufferBuilder) { - if (bufferBuilder.getVertexCount() <= 0) - return; + Pair pair = bufferBuilder.popData(); + BufferBuilder.DrawState state = pair.getFirst(); - VertexFormat vertexformat = bufferBuilder.getVertexFormat(); - int size = vertexformat.getSize(); - ByteBuffer bytebuffer = bufferBuilder.getByteBuffer(); - List list = vertexformat.getElements(); - - for (int index = 0; index < list.size(); ++index) { - VertexFormatElement vertexformatelement = list.get(index); - Usage usage = vertexformatelement.getUsage(); - bytebuffer.position(vertexformat.getOffset(index)); - usage.preDraw(vertexformat, index, size, bytebuffer); - } - - GlStateManager.drawArrays(bufferBuilder.getDrawMode(), 0, bufferBuilder.getVertexCount()); - - for (int index = 0; index < list.size(); ++index) { - VertexFormatElement vertexformatelement = list.get(index); - Usage usage = vertexformatelement.getUsage(); - usage.postDraw(vertexformat, index, size, bytebuffer); + if (state.getCount() > 0) { + state.getVertexFormat().startDrawing(MemoryUtil.memAddress(pair.getSecond())); + RenderSystem.drawArrays(state.getMode(), 0, state.getCount()); + state.getVertexFormat().endDrawing(); } } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java index 008b4c8ee..20eb873b6 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/SchematicTransformation.java @@ -1,6 +1,6 @@ package com.simibubi.create.modules.schematics.client; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingAngle; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; import com.simibubi.create.foundation.utility.VecHelper; @@ -51,16 +51,17 @@ public class SchematicTransformation { float pt = Minecraft.getInstance().getRenderPartialTicks(); // Translation - GlStateManager.translated(x.get(pt), y.get(pt), z.get(pt)); + RenderSystem.translated(x.get(pt), y.get(pt), z.get(pt)); Vec3d rotationOffset = getRotationOffset(true); // Rotation & Mirror - GlStateManager.translated(xOrigin + rotationOffset.x, 0, zOrigin + rotationOffset.z); - GlStateManager.rotated(rotation.get(pt), 0, 1, 0); - GlStateManager.translated(-rotationOffset.x, 0, -rotationOffset.z); - GlStateManager.scaled(scaleFrontBack.get(pt), 1, scaleLeftRight.get(pt)); - GlStateManager.translated(-xOrigin, 0, -zOrigin); + + RenderSystem.translated(xOrigin + rotationOffset.x, 0, zOrigin + rotationOffset.z); + RenderSystem.rotatef(rotation.get(pt), 0, 1, 0); + RenderSystem.translated(-rotationOffset.x, 0, -rotationOffset.z); + RenderSystem.scaled(scaleFrontBack.get(pt), 1, scaleLeftRight.get(pt)); + RenderSystem.translated(-xOrigin, 0, -zOrigin); } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java index 7718c4297..59635bff3 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/FlipTool.java @@ -1,18 +1,12 @@ package com.simibubi.create.modules.schematics.client.tools; -import org.lwjgl.opengl.GL11; - +import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.foundation.utility.ColorHelper; -import com.simibubi.create.foundation.utility.GlHelper; import com.simibubi.create.foundation.utility.VecHelper; -import com.simibubi.create.foundation.utility.outliner.AABBOutline; -import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.AxisAlignedBB; @@ -51,8 +45,8 @@ public class FlipTool extends PlacementToolBase { } @Override - public void renderToolLocal() { - super.renderToolLocal(); + public void renderToolLocal(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { + super.renderToolLocal(ms, buffer, light, overlay); if (!schematicSelected || !selectedFace.getAxis().isHorizontal()) return; @@ -78,32 +72,33 @@ public class FlipTool extends PlacementToolBase { plane = plane.mul(-1, 1, -1); Vec3d v4 = plane.add(center); - BufferBuilder buffer = Tessellator.getInstance().getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); - AABBOutline outline = schematicHandler.getOutline(); - AllSpecialTextures.BLANK.bind(); - outline.renderAACuboidLine(v1, v2, color, 1, buffer); - outline.renderAACuboidLine(v2, v3, color, 1, buffer); - outline.renderAACuboidLine(v3, v4, color, 1, buffer); - outline.renderAACuboidLine(v4, v1, color, 1, buffer); - - Tessellator.getInstance().draw(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); - - GlHelper.enableTextureRepeat(); - GlStateManager.depthMask(false); - Vec3d uDiff = v2.subtract(v1); - Vec3d vDiff = v4.subtract(v1); - float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); - float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); - - GlStateManager.enableCull(); - AllSpecialTextures.HIGHLIGHT_CHECKERED.bind(); - outline.putQuadUV(v1, v2, v3, v4, 0, 0, maxU, maxV, color, 1, buffer); - outline.putQuadUV(v2, v1, v4, v3, 0, 0, maxU, maxV, color, 1, buffer); - Tessellator.getInstance().draw(); - GlStateManager.popMatrix(); - GlHelper.disableTextureRepeat(); +// BufferBuilder buffer = Tessellator.getInstance().getBuffer();TODO 1.15 +// buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); +// +// AABBOutline outline = schematicHandler.getOutline(); +// AllSpecialTextures.BLANK.bind(); +// outline.renderAACuboidLine(v1, v2, color, 1, builder); +// outline.renderAACuboidLine(v2, v3, color, 1, builder); +// outline.renderAACuboidLine(v3, v4, color, 1, builder); +// outline.renderAACuboidLine(v4, v1, color, 1, builder); +// +// Tessellator.getInstance().draw(); +// buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); +// +// GlHelper.enableTextureRepeat(); +// GlStateManager.depthMask(false); +// Vec3d uDiff = v2.subtract(v1); +// Vec3d vDiff = v4.subtract(v1); +// float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); +// float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); +// +// GlStateManager.enableCull(); +// AllSpecialTextures.HIGHLIGHT_CHECKERED.bind(); +// outline.putQuadUV(v1, v2, v3, v4, 0, 0, maxU, maxV, color, 1, builder); +// outline.putQuadUV(v2, v1, v4, v3, 0, 0, maxU, maxV, color, 1, builder); +// Tessellator.getInstance().draw(); +// GlStateManager.popMatrix(); +// GlHelper.disableTextureRepeat(); } } diff --git a/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java b/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java index 91d2fc51f..0e150bc21 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java +++ b/src/main/java/com/simibubi/create/modules/schematics/client/tools/RotateTool.java @@ -1,16 +1,8 @@ package com.simibubi.create.modules.schematics.client.tools; -import org.lwjgl.opengl.GL11; +import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.foundation.utility.ColorHelper; - -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.Vec3d; +import net.minecraft.client.renderer.IRenderTypeBuffer; public class RotateTool extends PlacementToolBase { @@ -22,26 +14,26 @@ public class RotateTool extends PlacementToolBase { } @Override - public void renderToolLocal() { - super.renderToolLocal(); + public void renderToolLocal(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { + super.renderToolLocal(ms, buffer, light, overlay); - GlStateManager.pushMatrix(); - RenderHelper.disableStandardItemLighting(); - GlStateManager.enableBlend(); - - Vec3d color = ColorHelper.getRGB(0x4d80e4); - AxisAlignedBB bounds = schematicHandler.getBounds(); - double height = bounds.getYSize() + Math.max(20, bounds.getYSize()); - - Vec3d center = bounds.getCenter().add(schematicHandler.getTransformation().getRotationOffset(false)); - Vec3d start = center.subtract(0, height / 2, 0); - Vec3d end = center.add(0, height / 2, 0); - - BufferBuilder buffer = Tessellator.getInstance().getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); - schematicHandler.getOutline().renderAACuboidLine(start, end, color, 1, buffer); - Tessellator.getInstance().draw(); - GlStateManager.popMatrix(); +// GlStateManager.pushMatrix();TODO 1.15 +// RenderHelper.disableStandardItemLighting(); +// GlStateManager.enableBlend(); +// +// Vec3d color = ColorHelper.getRGB(0x4d80e4); +// AxisAlignedBB bounds = schematicHandler.getBounds(); +// double height = bounds.getYSize() + Math.max(20, bounds.getYSize()); +// +// Vec3d center = bounds.getCenter().add(schematicHandler.getTransformation().getRotationOffset(false)); +// Vec3d start = center.subtract(0, height / 2, 0); +// Vec3d end = center.add(0, height / 2, 0); +// +// BufferBuilder buffer = Tessellator.getInstance().getBuffer(); +// buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); +// schematicHandler.getOutline().renderAACuboidLine(start, end, color, 1, buffer); +// Tessellator.getInstance().draw(); +// GlStateManager.popMatrix(); } }