From 4cbf424f4d6eaa84cc45ca55856e71926aa496d5 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 9 May 2020 00:09:10 +0200 Subject: [PATCH] The Bugs win - Condensed mechanical crafting into one JEI page category, scaling down slots if necessary - Fixed ploughs trying to break water blocks - Fixed stationary contraptions getting nudged around by expiring farmland blocks - Shulker boxes can now be used as portable storage on contraptions - Added vertical rotation support to buttons, levers - Fixed certain directional blocks flipping around inconsistently when contraptions rotate by 180 degress - Random safety checks - Vertical belts no longer pop when rotated horizontally - Fixed inconsistent funnel activation when items are inserted on the same segment - Fixed adjustable pulley popping off due to floating point precision issues - Fixed toggle latch acting strangely with input signals - Schematicannons can now place belts safely - Removed invalid Schematic item from creative tab --- .../simibubi/create/compat/jei/CreateJEI.java | 78 ++++---- .../category/MechanicalCraftingCategory.java | 164 ++++++++++++---- .../category/animations/AnimatedCrafter.java | 30 +-- .../create/data/CreateAdvancements.java | 5 - .../contraptions/RotationPropagator.java | 3 +- .../actors/PloughMovementBehaviour.java | 8 +- .../contraptions/ContraptionEntity.java | 30 ++- .../contraptions/MountedStorage.java | 3 + .../contraptions/StructureTransform.java | 182 +++++++++++------- .../deployer/DeployerTileEntity.java | 15 +- .../contraptions/relays/belt/BeltBlock.java | 38 +++- .../relays/belt/BeltTileEntity.java | 8 +- .../relays/belt/item/BeltConnectorItem.java | 22 ++- .../relays/belt/transport/BeltInventory.java | 50 ++--- .../encased/AdjustablePulleyTileEntity.java | 2 + .../block/StockswitchTileEntity.java | 4 +- .../logistics/block/diodes/LatchBlock.java | 32 +-- .../inventories/FlexcrateTileEntity.java | 4 +- .../schematics/block/LaunchedItem.java | 62 +++++- .../block/SchematicannonTileEntity.java | 53 ++++- .../schematics/item/SchematicItem.java | 5 + .../create/advancements/expert_lane_1.json | 35 ---- 22 files changed, 546 insertions(+), 287 deletions(-) delete mode 100644 src/main/resources/data/create/advancements/expert_lane_1.json 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 ff99bd785..118c775ed 100644 --- a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java +++ b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java @@ -24,7 +24,6 @@ import com.simibubi.create.compat.jei.category.SawingCategory; import com.simibubi.create.compat.jei.category.SmokingViaFanCategory; import com.simibubi.create.compat.jei.category.SplashingCategory; 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.logistics.block.inventories.FlexcrateScreen; @@ -66,8 +65,7 @@ public class CreateJEI implements IModPlugin { private PackingCategory packingCategory; private PolishingCategory polishingCategory; private MysteriousItemConversionCategory mysteryConversionCategory; - private MechanicalCraftingCategory smallMechanicalCraftingCategory; - private MechanicalCraftingCategory largeMechanicalCraftingCategory; + private MechanicalCraftingCategory mechanicalCraftingCategory; @Override public ResourceLocation getPluginUid() { @@ -88,8 +86,7 @@ public class CreateJEI implements IModPlugin { packingCategory = new PackingCategory(); polishingCategory = new PolishingCategory(); mysteryConversionCategory = new MysteriousItemConversionCategory(); - smallMechanicalCraftingCategory = new MechanicalCraftingCategory(false); - largeMechanicalCraftingCategory = new MechanicalCraftingCategory(true); + mechanicalCraftingCategory = new MechanicalCraftingCategory(); } @Override @@ -99,10 +96,11 @@ public class CreateJEI implements IModPlugin { @Override public void registerCategories(IRecipeCategoryRegistration registration) { - registration.addRecipeCategories(millingCategory, crushingCategory, splashingCategory, pressingCategory, - smokingCategory, blastingCategory, blockzapperCategory, mixingCategory, sawingCategory, - blockCuttingCategory, packingCategory, polishingCategory, mysteryConversionCategory, - smallMechanicalCraftingCategory, largeMechanicalCraftingCategory); + registration + .addRecipeCategories(millingCategory, crushingCategory, splashingCategory, pressingCategory, + smokingCategory, blastingCategory, blockzapperCategory, mixingCategory, sawingCategory, + blockCuttingCategory, packingCategory, polishingCategory, mysteryConversionCategory, + mechanicalCraftingCategory); } @Override @@ -132,33 +130,28 @@ public class CreateJEI implements IModPlugin { packingCategory.getUid()); registration.addRecipes(findRecipes(AllRecipes.SANDPAPER_POLISHING), polishingCategory.getUid()); registration.addRecipes(MysteriousItemConversionCategory.getRecipes(), mysteryConversionCategory.getUid()); - - registration.addRecipes(findRecipes( - r -> (r instanceof MechanicalCraftingRecipe) && MechanicalCraftingCategory.isSmall((ShapedRecipe) r)), - smallMechanicalCraftingCategory.getUid()); - registration.addRecipes( - findRecipes( - r -> (r.getType() == IRecipeType.CRAFTING || r.getType() == AllRecipes.MECHANICAL_CRAFTING.type) - && (r instanceof ShapedRecipe) && !(r instanceof MechanicalCraftingRecipe) - && MechanicalCraftingCategory.isSmall((ShapedRecipe) r)), - smallMechanicalCraftingCategory.getUid()); - registration.addRecipes(findRecipes( - r -> (r.getType() == IRecipeType.CRAFTING || r.getType() == AllRecipes.MECHANICAL_CRAFTING.type) - && (r instanceof ShapedRecipe) && !MechanicalCraftingCategory.isSmall((ShapedRecipe) r)), - largeMechanicalCraftingCategory.getUid()); - + registration.addRecipes(findRecipes(r -> (r.getType() == AllRecipes.MECHANICAL_CRAFTING.type)), + mechanicalCraftingCategory.getUid()); + registration.addRecipes(findRecipes(r -> (r.getType() == IRecipeType.CRAFTING + && r.getType() != AllRecipes.MECHANICAL_CRAFTING.type) && (r instanceof ShapedRecipe)), + mechanicalCraftingCategory.getUid()); } @Override public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { ItemStack fan = new ItemStack(AllBlocks.ENCASED_FAN.get()); - ItemStack splashingFan = fan.copy() + ItemStack splashingFan = fan + .copy() .setDisplayName(new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.splashing.fan"))); - ItemStack smokingFan = fan.copy().setDisplayName( - new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.smokingViaFan.fan"))); - ItemStack blastingFan = fan.copy().setDisplayName( - new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan"))); + ItemStack smokingFan = fan + .copy() + .setDisplayName( + new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.smokingViaFan.fan"))); + ItemStack blastingFan = fan + .copy() + .setDisplayName( + new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan"))); registration.addRecipeCatalyst(new ItemStack(AllBlocks.MILLSTONE.get()), millingCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(AllBlocks.CRUSHING_WHEEL.get()), crushingCategory.getUid()); @@ -176,10 +169,9 @@ public class CreateJEI implements IModPlugin { registration.addRecipeCatalyst(new ItemStack(AllBlocks.BASIN.get()), packingCategory.getUid()); registration.addRecipeCatalyst(AllItems.SAND_PAPER.asStack(), polishingCategory.getUid()); registration.addRecipeCatalyst(AllItems.RED_SAND_PAPER.asStack(), polishingCategory.getUid()); - registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()), - smallMechanicalCraftingCategory.getUid()); - registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()), - largeMechanicalCraftingCategory.getUid()); + registration + .addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()), + mechanicalCraftingCategory.getUid()); } @Override @@ -193,18 +185,30 @@ public class CreateJEI implements IModPlugin { } private static List> findRecipes(Predicate> pred) { - return Minecraft.getInstance().world.getRecipeManager().getRecipes().stream().filter(pred) + return Minecraft.getInstance().world + .getRecipeManager() + .getRecipes() + .stream() + .filter(pred) .collect(Collectors.toList()); } private static List> findRecipesByType(IRecipeType type) { - return Minecraft.getInstance().world.getRecipeManager().getRecipes().stream().filter(r -> r.getType() == type) + return Minecraft.getInstance().world + .getRecipeManager() + .getRecipes() + .stream() + .filter(r -> r.getType() == type) .collect(Collectors.toList()); } private static List> findRecipesById(ResourceLocation id) { - return Minecraft.getInstance().world.getRecipeManager().getRecipes().stream() - .filter(r -> r.getSerializer().getRegistryName().equals(id)).collect(Collectors.toList()); + return Minecraft.getInstance().world + .getRecipeManager() + .getRecipes() + .stream() + .filter(r -> r.getSerializer().getRegistryName().equals(id)) + .collect(Collectors.toList()); } private static List> findRecipesByTypeExcluding(IRecipeType type, IRecipeType excludingType) { 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 9d6406833..7cc21a0ea 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 @@ -1,39 +1,103 @@ package com.simibubi.create.compat.jei.category; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllBlocks; import com.simibubi.create.ScreenResources; 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.ingredient.IGuiItemStackGroup; +import mezz.jei.api.ingredients.IIngredientRenderer; import mezz.jei.api.ingredients.IIngredients; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Rarity; import net.minecraft.item.crafting.Ingredient; import net.minecraft.item.crafting.ShapedRecipe; import net.minecraft.util.NonNullList; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; public class MechanicalCraftingCategory extends CreateRecipeCategory { - private AnimatedCrafter crafter; - private boolean large; + private final class CrafterIngredientRenderer implements IIngredientRenderer { - public MechanicalCraftingCategory(boolean large) { - super("mechanical_crafting" + (large ? "_large" : ""), itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()), - emptyBackground(large ? 177 : 177, large ? 235 : 81)); - this.large = large; - crafter = new AnimatedCrafter(large); + private ShapedRecipe recipe; + + public CrafterIngredientRenderer(ShapedRecipe recipe) { + this.recipe = recipe; + } + + @Override + public void render(int xPosition, int yPosition, ItemStack ingredient) { + GlStateManager.pushMatrix(); + GlStateManager.translated(xPosition, yPosition, 0); + float scale = getScale(recipe); + GlStateManager.scaled(scale, scale, scale); + + if (ingredient != null) { + GlStateManager.enableDepthTest(); + RenderHelper.enableGUIStandardItemLighting(); + Minecraft minecraft = Minecraft.getInstance(); + FontRenderer font = getFontRenderer(minecraft, ingredient); + ItemRenderer itemRenderer = minecraft.getItemRenderer(); + itemRenderer.renderItemAndEffectIntoGUI(null, ingredient, 0, 0); + itemRenderer.renderItemOverlayIntoGUI(font, ingredient, 0, 0, null); + GlStateManager.disableBlend(); + RenderHelper.disableStandardItemLighting(); + } + GlStateManager.popMatrix(); + } + + @Override + public List getTooltip(ItemStack ingredient, ITooltipFlag tooltipFlag) { + Minecraft minecraft = Minecraft.getInstance(); + PlayerEntity player = minecraft.player; + List list; + try { + list = ingredient + .getTooltip(player, tooltipFlag) + .stream() + .map(ITextComponent::getFormattedText) + .collect(Collectors.toList()); + } catch (RuntimeException | LinkageError e) { + return new ArrayList<>(); + } + + Rarity rarity; + try { + rarity = ingredient.getRarity(); + } catch (RuntimeException | LinkageError e) { + rarity = Rarity.COMMON; + } + + for (int k = 0; k < list.size(); ++k) { + if (k == 0) { + list.set(k, rarity.color + list.get(k)); + } else { + list.set(k, TextFormatting.GRAY + list.get(k)); + } + } + + return list; + } } - public static boolean isSmall(ShapedRecipe recipe) { - return Math.max((recipe).getWidth(), (recipe).getHeight()) <= 4; - } + private AnimatedCrafter crafter = new AnimatedCrafter(); - @Override - public String getTitle() { - return Lang.translate("recipe.mechanical_crafting"); + public MechanicalCraftingCategory() { + super("mechanical_crafting", itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()), emptyBackground(177, 107)); } @Override @@ -47,45 +111,79 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory recipeIngredients = recipe.getIngredients(); - itemStacks.init(0, false, large ? 136 : 141, large ? 196 : 50); + itemStacks.init(0, false, 133, 80); itemStacks.set(0, recipe.getRecipeOutput().getStack()); - int x = getGridX(recipe); - int y = getGridY(recipe); + int x = getXPadding(recipe); + int y = getYPadding(recipe); + float scale = getScale(recipe); int size = recipeIngredients.size(); + IIngredientRenderer renderer = new CrafterIngredientRenderer(recipe); + for (int i = 0; i < size; i++) { - itemStacks.init(i + 1, true, x + (i % recipe.getWidth()) * 19, y + (i / recipe.getWidth()) * 19); + float f = 19 * scale; + int slotSize = (int) (16 * scale); + int xPosition = (int) (x + 1 + (i % recipe.getWidth()) * f); + int yPosition = (int) (y + 1 + (i / recipe.getWidth()) * f); + itemStacks.init(i + 1, true, renderer, xPosition, yPosition, slotSize, slotSize, 0, 0); itemStacks.set(i + 1, Arrays.asList(recipeIngredients.get(i).getMatchingStacks())); } } - public int getGridY(ShapedRecipe recipe) { - return 3 + (int) (((large ? 9 : 4) - recipe.getRecipeHeight()) * 19 / 2f); + static int maxSize = 100; + + public static float getScale(ShapedRecipe recipe) { + int w = recipe.getWidth(); + int h = recipe.getHeight(); + return Math.min(1, maxSize / (19f * Math.max(w, h))); } - public int getGridX(ShapedRecipe recipe) { - return 3 + (int) (((large ? 9 : 4) - recipe.getRecipeWidth()) * 19 / 2f); + public static int getYPadding(ShapedRecipe recipe) { + return 3 + 50 - (int) (getScale(recipe) * recipe.getHeight() * 19 * .5); + } + + public static int getXPadding(ShapedRecipe recipe) { + return 3 + 50 - (int) (getScale(recipe) * recipe.getWidth() * 19 * .5); } @Override public void draw(ShapedRecipe recipe, double mouseX, double mouseY) { - int x = getGridX(recipe); - int y = getGridY(recipe); + GlStateManager.pushMatrix(); + float scale = getScale(recipe); + GlStateManager.translated(getXPadding(recipe), getYPadding(recipe), 0); for (int row = 0; row < recipe.getHeight(); row++) for (int col = 0; col < recipe.getWidth(); col++) - if (!recipe.getIngredients().get(row * recipe.getWidth() + col).hasNoMatchingItems()) - ScreenResources.JEI_SLOT.draw(x + col * 19, y + row * 19); + if (!recipe.getIngredients().get(row * recipe.getWidth() + col).hasNoMatchingItems()) { + GlStateManager.pushMatrix(); + GlStateManager.translated((int) col * 19 * scale, (int) row * 19 * scale, 0); + GlStateManager.scaled(scale, scale, scale); + ScreenResources.JEI_SLOT.draw(0, 0); + GlStateManager.popMatrix(); + } - ScreenResources.JEI_SLOT.draw(large ? 136 : 141, large ? 196 : 50); - if (large) - ScreenResources.JEI_ARROW.draw(86, 200); - else - ScreenResources.JEI_DOWN_ARROW.draw(136, 32); + GlStateManager.popMatrix(); - ScreenResources.JEI_SHADOW.draw(large ? 20 : 84, large ? 223 : 68); - crafter.draw(large ? 105 : 185, large ? 189 : -1); + ScreenResources.JEI_SLOT.draw(133, 80); + ScreenResources.JEI_DOWN_ARROW.draw(128, 59); + ScreenResources.JEI_SHADOW.draw(116, 36); + crafter.draw(219, 8); + + GlStateManager.pushMatrix(); + GlStateManager.translated(0, 0, 200); + + RenderHelper.disableStandardItemLighting(); + int amount = 0; + for (Ingredient ingredient : recipe.getIngredients()) { + if (Ingredient.EMPTY == ingredient) + continue; + amount++; + } + Minecraft.getInstance().fontRenderer + .drawStringWithShadow(amount + "", 142, 39, 0xFFFFFF); + RenderHelper.enableStandardItemLighting(); + GlStateManager.popMatrix(); } @Override diff --git a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrafter.java b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrafter.java index 89fd71bf6..a82103447 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrafter.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrafter.java @@ -12,12 +12,6 @@ import net.minecraft.util.Direction; public class AnimatedCrafter extends AnimatedKinetics { - boolean four; - - public AnimatedCrafter(boolean four) { - this.four = four; - } - @Override public int getWidth() { return 50; @@ -40,23 +34,7 @@ public class AnimatedCrafter extends AnimatedKinetics { ScreenElementRenderer.renderModel(() -> cogwheel(true)); ScreenElementRenderer.renderBlock(this::body); - GlStateManager.translatef(0, 50, 0); - ScreenElementRenderer.renderModel(() -> cogwheel(false)); - ScreenElementRenderer.renderBlock(this::body); - - if (four) { - GlStateManager.translatef(50, -50, 0); - ScreenElementRenderer.renderModel(() -> cogwheel(false)); - ScreenElementRenderer.renderBlock(this::body); - GlStateManager.translatef(0, 50, 0); - ScreenElementRenderer.renderModel(() -> cogwheel(true)); - ScreenElementRenderer.renderBlock(this::body); - - } else { - GlStateManager.translatef(0, 50, 0); - ScreenElementRenderer.renderModel(() -> cogwheel(true)); - ScreenElementRenderer.renderBlock(this::body); - } + GlStateManager.translatef(50, 0, 0); GlStateManager.popMatrix(); } @@ -71,8 +49,10 @@ public class AnimatedCrafter extends AnimatedKinetics { } private BlockState body() { - return AllBlocks.MECHANICAL_CRAFTER.get().getDefaultState().with(MechanicalCrafterBlock.HORIZONTAL_FACING, - Direction.WEST); + return AllBlocks.MECHANICAL_CRAFTER + .get() + .getDefaultState() + .with(MechanicalCrafterBlock.HORIZONTAL_FACING, Direction.WEST); } } diff --git a/src/main/java/com/simibubi/create/data/CreateAdvancements.java b/src/main/java/com/simibubi/create/data/CreateAdvancements.java index 4c1599ffd..41efa9741 100644 --- a/src/main/java/com/simibubi/create/data/CreateAdvancements.java +++ b/src/main/java/com/simibubi/create/data/CreateAdvancements.java @@ -251,11 +251,6 @@ public class CreateAdvancements implements IDataProvider { private void andesiteExpertLane(Consumer t, Advancement root) { String id = Create.ID; - - Advancement expert_lane_1 = advancement("expert_lane_1", Blocks.ANDESITE, TaskType.SILENT_GATE) - .withParent(root) - .withCriterion("0", itemGathered(AllBlocks.ANDESITE_CASING.get())) - .register(t, id + ":expert_lane_1"); } // Datagen diff --git a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java index 55f24ce90..a3eab379b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java @@ -248,7 +248,8 @@ public class RotationPropagator { // Do not overpower you own network -> cycle if (!currentTE.hasNetwork() || currentTE.network.equals(neighbourTE.network)) { - if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour)) + float epsilon = Math.abs(speedOfNeighbour) / 256f / 256f; + if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour) + epsilon) world.destroyBlock(pos, true); continue; } 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 12fd4ea93..81fd2b07d 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 @@ -7,6 +7,7 @@ import com.simibubi.create.modules.contraptions.components.actors.PloughBlock.Pl import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import net.minecraft.block.BlockState; +import net.minecraft.block.FlowingFluidBlock; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.item.Items; @@ -25,8 +26,8 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public boolean isActive(MovementContext context) { - return !VecHelper.isVecPointingTowards(context.relativeMotion, - context.state.get(HORIZONTAL_FACING).getOpposite()); + return !VecHelper + .isVecPointingTowards(context.relativeMotion, context.state.get(HORIZONTAL_FACING).getOpposite()); } @Override @@ -66,7 +67,8 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour { @Override public boolean canBreak(World world, BlockPos breakingPos, BlockState state) { - return state.getCollisionShape(world, breakingPos).isEmpty(); + return state.getCollisionShape(world, breakingPos).isEmpty() + && !(state.getBlock() instanceof FlowingFluidBlock); } @Override 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 2cb92b8c7..56c7623f6 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 @@ -298,11 +298,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD BearingContraption bc = (BearingContraption) getContraption(); Direction facing = bc.getFacing(); Vec3d activeAreaOffset = actor.getActiveAreaOffset(context); - if (activeAreaOffset.mul(VecHelper.planeByNormal(new Vec3d(facing.getDirectionVec()))) + if (activeAreaOffset + .mul(VecHelper.planeByNormal(new Vec3d(facing.getDirectionVec()))) .equals(Vec3d.ZERO)) { if (VecHelper.onSameAxis(blockInfo.pos, BlockPos.ZERO, facing.getAxis())) { - context.motion = new Vec3d(facing.getDirectionVec()).scale( - facing.getAxis().getCoordinate(roll - prevRoll, yaw - prevYaw, pitch - prevPitch)); + context.motion = new Vec3d(facing.getDirectionVec()) + .scale(facing + .getAxis() + .getCoordinate(roll - prevRoll, yaw - prevYaw, pitch - prevPitch)); context.relativeMotion = context.motion; int timer = context.data.getInt("StationaryTimer"); if (timer > 0) { @@ -333,8 +336,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD setMotion(Vec3d.ZERO); if (getController() != null) getController().onStall(); - AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), - new ContraptionStallPacket(getEntityId(), posX, posY, posZ, yaw, pitch, roll)); + AllPackets.channel + .send(PacketDistributor.TRACKING_ENTITY.with(() -> this), + new ContraptionStallPacket(getEntityId(), posX, posY, posZ, yaw, pitch, roll)); } dataManager.set(STALLED, contraption.stalled); } else { @@ -463,8 +467,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (contraption != null) compound.put("Contraption", contraption.writeNBT()); if (!stationary && motionBeforeStall != null) - compound.put("CachedMotion", - newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z)); + compound + .put("CachedMotion", + newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z)); if (controllerPos != null) compound.put("Controller", NBTUtil.writeBlockPos(controllerPos)); if (forcedAngle != -1) @@ -542,8 +547,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } if (horizontalMag(vec3d1) > horizontalMag(vec3d)) { - vec3d = vec3d1.add(collideBoundingBoxHeuristically(e, new Vec3d(0.0D, -vec3d1.y + vec.y, 0.0D), - axisalignedbb.offset(vec3d1), e.world, iselectioncontext, reuseablestream)); + vec3d = vec3d1 + .add(collideBoundingBoxHeuristically(e, new Vec3d(0.0D, -vec3d1.y + vec.y, 0.0D), + axisalignedbb.offset(vec3d1), e.world, iselectioncontext, reuseablestream)); } } @@ -593,6 +599,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD // Make sure nothing can move contraptions out of the way public void setMotion(Vec3d motionIn) {} + @Override + public void setPositionAndUpdate(double x, double y, double z) { + if (!stationary) + super.setPositionAndUpdate(x, y, z); + } + @Override public PushReaction getPushReaction() { return PushReaction.IGNORE; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MountedStorage.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MountedStorage.java index e2056fba1..3a1eccd0f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MountedStorage.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/MountedStorage.java @@ -9,6 +9,7 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.ChestType; import net.minecraft.tileentity.BarrelTileEntity; import net.minecraft.tileentity.ChestTileEntity; +import net.minecraft.tileentity.ShulkerBoxTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraftforge.items.CapabilityItemHandler; @@ -107,6 +108,8 @@ public class MountedStorage { TileEntityType type = te.getType(); if (type == AllTileEntities.FLEXCRATE.type) return true; + if (te instanceof ShulkerBoxTileEntity) + return true; if (te instanceof ChestTileEntity) return true; if (te instanceof BarrelTileEntity) 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 3277964a8..1b3109e36 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 @@ -1,7 +1,9 @@ package com.simibubi.create.modules.contraptions.components.contraptions; +import static net.minecraft.block.HorizontalFaceBlock.FACE; import static net.minecraft.state.properties.BlockStateProperties.AXIS; import static net.minecraft.state.properties.BlockStateProperties.FACING; +import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.VecHelper; @@ -10,10 +12,13 @@ import com.simibubi.create.modules.contraptions.components.contraptions.chassis. import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.HorizontalFaceBlock; import net.minecraft.block.SlabBlock; import net.minecraft.block.StairsBlock; import net.minecraft.state.BooleanProperty; +import net.minecraft.state.properties.AttachFace; import net.minecraft.state.properties.Half; import net.minecraft.state.properties.SlabType; import net.minecraft.util.Direction; @@ -73,90 +78,133 @@ public class StructureTransform { * horizontal axes */ public BlockState apply(BlockState state) { - if (rotationAxis == Axis.Y) - state = state.rotate(rotation); - else { - if (state.getBlock() instanceof AbstractChassisBlock) - return rotateChassis(state); + return state.rotate(rotation); - if (state.getBlock() instanceof StairsBlock) { - if (state.get(StairsBlock.FACING).getAxis() != rotationAxis) { - for (int i = 0; i < rotation.ordinal(); i++) { - Direction direction = state.get(StairsBlock.FACING); - Half half = state.get(StairsBlock.HALF); - if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ half == Half.BOTTOM - ^ direction.getAxis() == Axis.Z) - state = state.cycle(StairsBlock.HALF); - else - state = state.with(StairsBlock.FACING, direction.getOpposite()); - } - } else { - if (rotation == Rotation.CLOCKWISE_180) { - state = state.cycle(StairsBlock.HALF); - } - } + Block block = state.getBlock(); + + if (block instanceof AbstractChassisBlock) + return rotateChassis(state); + + if (block instanceof HorizontalFaceBlock) { + Direction stateFacing = state.get(HorizontalFaceBlock.HORIZONTAL_FACING); + AttachFace stateFace = state.get(FACE); + Direction forcedAxis = rotationAxis == Axis.Z ? Direction.EAST : Direction.SOUTH; + + if (stateFacing.getAxis() == rotationAxis && stateFace == AttachFace.WALL) return state; + + for (int i = 0; i < rotation.ordinal(); i++) { + stateFace = state.get(FACE); + stateFacing = state.get(HorizontalFaceBlock.HORIZONTAL_FACING); + + boolean b = state.get(FACE) == AttachFace.CEILING; + state = state.with(HORIZONTAL_FACING, b ? forcedAxis : forcedAxis.getOpposite()); + + if (stateFace != AttachFace.WALL) { + state = state.with(FACE, AttachFace.WALL); + continue; + } + + if (stateFacing.getAxisDirection() == AxisDirection.POSITIVE) { + state = state.with(FACE, AttachFace.FLOOR); + continue; + } + state = state.with(FACE, AttachFace.CEILING); } - if (AllBlocks.BELT.typeOf(state)) { - if (state.get(BeltBlock.HORIZONTAL_FACING).getAxis() != rotationAxis) { - for (int i = 0; i < rotation.ordinal(); i++) { - Slope slope = state.get(BeltBlock.SLOPE); - Direction direction = state.get(BeltBlock.HORIZONTAL_FACING); + return state; + } - // Rotate diagonal - if (slope != Slope.HORIZONTAL && slope != Slope.VERTICAL) { - if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ slope == Slope.DOWNWARD - ^ direction.getAxis() == Axis.Z) { - state = - state.with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD : Slope.UPWARD); - } else { - state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite()); - } + if (block instanceof StairsBlock) { + if (state.get(StairsBlock.FACING).getAxis() != rotationAxis) { + for (int i = 0; i < rotation.ordinal(); i++) { + Direction direction = state.get(StairsBlock.FACING); + Half half = state.get(StairsBlock.HALF); + if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ half == Half.BOTTOM + ^ direction.getAxis() == Axis.Z) + state = state.cycle(StairsBlock.HALF); + else + state = state.with(StairsBlock.FACING, direction.getOpposite()); + } + } else { + if (rotation == Rotation.CLOCKWISE_180) { + state = state.cycle(StairsBlock.HALF); + } + } + return state; + } - // Rotate horizontal/vertical + if (AllBlocks.BELT.typeOf(state)) { + if (state.get(BeltBlock.HORIZONTAL_FACING).getAxis() != rotationAxis) { + for (int i = 0; i < rotation.ordinal(); i++) { + Slope slope = state.get(BeltBlock.SLOPE); + Direction direction = state.get(BeltBlock.HORIZONTAL_FACING); + + // Rotate diagonal + if (slope != Slope.HORIZONTAL && slope != Slope.VERTICAL) { + if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ slope == Slope.DOWNWARD + ^ direction.getAxis() == Axis.Z) { + state = state.with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD : Slope.UPWARD); } else { - if (slope == Slope.HORIZONTAL ^ direction.getAxis() == Axis.Z) { - state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite()); - } - state = state.with(BeltBlock.SLOPE, - slope == Slope.HORIZONTAL ? Slope.VERTICAL : Slope.HORIZONTAL); - } - } - } else { - if (rotation == Rotation.CLOCKWISE_180) { - Slope slope = state.get(BeltBlock.SLOPE); - Direction direction = state.get(BeltBlock.HORIZONTAL_FACING); - if (slope == Slope.UPWARD || slope == Slope.DOWNWARD) { - state = state.with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD - : slope == Slope.DOWNWARD ? Slope.UPWARD : slope); - } else if (slope == Slope.VERTICAL) { state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite()); } + + // Rotate horizontal/vertical + } else { + if (slope == Slope.HORIZONTAL ^ direction.getAxis() == Axis.Z) { + state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite()); + } + state = + state.with(BeltBlock.SLOPE, slope == Slope.HORIZONTAL ? Slope.VERTICAL : Slope.HORIZONTAL); + } + } + } else { + if (rotation == Rotation.CLOCKWISE_180) { + Slope slope = state.get(BeltBlock.SLOPE); + Direction direction = state.get(BeltBlock.HORIZONTAL_FACING); + if (slope == Slope.UPWARD || slope == Slope.DOWNWARD) { + state = state + .with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD + : slope == Slope.DOWNWARD ? Slope.UPWARD : slope); + } else if (slope == Slope.VERTICAL) { + state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite()); } } - return state; } + return state; + } + + if (state.has(FACING)) { + Direction newFacing = transformFacing(state.get(FACING)); + if (state.has(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) { + if (rotationAxis == newFacing.getAxis() && rotation.ordinal() % 2 == 1) + state = state.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE); + } + state = state.with(FACING, newFacing); + + } else if (state.has(AXIS)) { + state = state.with(AXIS, transformAxis(state.get(AXIS))); + + } else if (rotation == Rotation.CLOCKWISE_180) { if (state.has(FACING)) { - Direction newFacing = transformFacing(state.get(FACING)); - if (state.has(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) { - if (rotationAxis == newFacing.getAxis() && rotation.ordinal() % 2 == 1) - state = state.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE); - } - state = state.with(FACING, newFacing); - - } else if (state.has(AXIS)) { - state = state.with(AXIS, transformAxis(state.get(AXIS))); - - } else if (rotation == Rotation.CLOCKWISE_180) { - state = state.rotate(rotation); - if (state.has(SlabBlock.TYPE) && state.get(SlabBlock.TYPE) != SlabType.DOUBLE) - state = state.with(SlabBlock.TYPE, - state.get(SlabBlock.TYPE) == SlabType.BOTTOM ? SlabType.TOP : SlabType.BOTTOM); + Direction stateFacing = state.get(FACING); + if (stateFacing.getAxis() == rotationAxis) + return state; } + if (state.has(HORIZONTAL_FACING)) { + Direction stateFacing = state.get(HORIZONTAL_FACING); + if (stateFacing.getAxis() == rotationAxis) + return state; + } + + state = state.rotate(rotation); + if (state.has(SlabBlock.TYPE) && state.get(SlabBlock.TYPE) != SlabType.DOUBLE) + state = state + .with(SlabBlock.TYPE, + state.get(SlabBlock.TYPE) == SlabType.BOTTOM ? SlabType.TOP : SlabType.BOTTOM); } return state; 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..58fe235c0 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 @@ -51,8 +51,11 @@ import net.minecraftforge.items.ItemHandlerHelper; public class DeployerTileEntity extends KineticTileEntity { - private static final List> EXTRACTING_LOCATIONS = Arrays.asList(Direction.values()) - .stream().map(d -> Pair.of(BlockPos.ZERO.offset(d), d.getOpposite())).collect(Collectors.toList()); + private static final List> EXTRACTING_LOCATIONS = Arrays + .asList(Direction.values()) + .stream() + .map(d -> Pair.of(BlockPos.ZERO.offset(d), d.getOpposite())) + .collect(Collectors.toList()); private FilteringBehaviour filtering; private ExtractingBehaviour extracting; @@ -373,8 +376,9 @@ public class DeployerTileEntity extends KineticTileEntity { reach = tag.getFloat("Reach"); if (tag.contains("Particle")) { ItemStack particleStack = ItemStack.read(tag.getCompound("Particle")); - SandPaperItem.spawnParticles(VecHelper.getCenterOf(pos).add(getMovementVector().scale(2f)), particleStack, - this.world); + SandPaperItem + .spawnParticles(VecHelper.getCenterOf(pos).add(getMovementVector().scale(2f)), particleStack, + this.world); } super.readClientUpdate(tag); @@ -402,7 +406,8 @@ public class DeployerTileEntity extends KineticTileEntity { @Override public void remove() { super.remove(); - invHandler.invalidate(); + if (invHandler != null) + invHandler.invalidate(); } public void changeMode() { 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 7c1ae4708..8f274e8f9 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 @@ -50,6 +50,7 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Hand; import net.minecraft.util.IStringSerializable; +import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.MathHelper; @@ -59,6 +60,7 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; +import net.minecraft.world.WorldType; import net.minecraft.world.storage.loot.LootParameters; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -342,10 +344,11 @@ public class BeltBlock extends HorizontalKineticBlock double d7 = d4 * d1 + x1; double d8 = d5 * d2 + y1; double d9 = d6 * d3 + z1; - manager.addEffect( - (new DiggingParticle(world, (double) pos.getX() + d7, (double) pos.getY() + d8, - (double) pos.getZ() + d9, d4 - 0.5D, d5 - 0.5D, d6 - 0.5D, state)) - .setBlockPos(pos)); + manager + .addEffect( + (new DiggingParticle(world, (double) pos.getX() + d7, (double) pos.getY() + d8, + (double) pos.getZ() + d9, d4 - 0.5D, d5 - 0.5D, d6 - 0.5D, state)) + .setBlockPos(pos)); } } } @@ -397,7 +400,7 @@ public class BeltBlock extends HorizontalKineticBlock } public static void initBelt(World world, BlockPos pos) { - if (world.isRemote) + if (world.isRemote || world.getWorldType() == WorldType.DEBUG_ALL_BLOCK_STATES) return; BlockState state = world.getBlockState(pos); @@ -430,7 +433,9 @@ public class BeltBlock extends HorizontalKineticBlock for (BlockPos beltPos : beltChain) { TileEntity tileEntity = world.getTileEntity(beltPos); - if (tileEntity instanceof BeltTileEntity) { + BlockState currentState = world.getBlockState(beltPos); + + if (tileEntity instanceof BeltTileEntity && AllBlocks.BELT.typeOf(currentState)) { BeltTileEntity te = (BeltTileEntity) tileEntity; te.setController(currentPos); te.beltLength = beltChain.size(); @@ -439,7 +444,6 @@ public class BeltBlock extends HorizontalKineticBlock te.markDirty(); te.sendData(); - BlockState currentState = world.getBlockState(beltPos); boolean isVertical = currentState.get(BeltBlock.SLOPE) == Slope.VERTICAL; if (currentState.get(CASING) && isVertical) { @@ -540,10 +544,10 @@ public class BeltBlock extends HorizontalKineticBlock int limit = 1000; BlockPos current = controllerPos; while (limit-- > 0 && current != null) { - positions.add(current); BlockState state = world.getBlockState(current); if (!AllBlocks.BELT.typeOf(state)) break; + positions.add(current); current = nextSegmentPosition(state, current, true); } @@ -607,7 +611,7 @@ public class BeltBlock extends HorizontalKineticBlock public Class getTileEntityClass() { return BeltTileEntity.class; } - + @Override public ItemRequirement getRequiredItems(BlockState state) { List required = new ArrayList<>(); @@ -622,4 +626,20 @@ public class BeltBlock extends HorizontalKineticBlock return new ItemRequirement(ItemUseType.CONSUME, required); } + @Override + public BlockState rotate(BlockState state, Rotation rot) { + BlockState rotate = super.rotate(state, rot); + + if (state.get(SLOPE) != Slope.VERTICAL) + return rotate; + if (state.get(HORIZONTAL_FACING).getAxisDirection() != rotate.get(HORIZONTAL_FACING).getAxisDirection()) { + if (state.get(PART) == Part.START) + return rotate.with(PART, Part.END); + if (state.get(PART) == Part.END) + return rotate.with(PART, Part.START); + } + + return rotate; + } + } 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 18b546483..6cc9fda13 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 @@ -73,6 +73,8 @@ public class BeltTileEntity extends KineticTileEntity { // Init belt if (beltLength == 0) BeltBlock.initBelt(world, pos); + if (!AllBlocks.BELT.typeOf(world.getBlockState(pos))) + return; // Initialize Belt Attachments if (world != null && trackerUpdateTag != null) { @@ -306,8 +308,8 @@ public class BeltTileEntity extends KineticTileEntity { public Direction getMovementFacing() { Axis axis = getBeltFacing().getAxis(); - return Direction.getFacingFromAxisDirection(axis, - getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE); + return Direction + .getFacingFromAxisDirection(axis, getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE); } protected Direction getBeltFacing() { @@ -344,7 +346,7 @@ public class BeltTileEntity extends KineticTileEntity { if (simulate) return true; - transportedStack.beltPosition = index + .5f - Math.signum(getSpeed()) / 16f; + transportedStack.beltPosition = index + .5f - Math.signum(getDirectionAwareBeltMovementSpeed()) / 16f; Direction movementFacing = getMovementFacing(); if (!side.getAxis().isVertical()) { 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 92f64ae5f..fd53a3ede 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 @@ -92,15 +92,16 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther { return ActionResultType.SUCCESS; } - private void createBelts(World world, BlockPos start, BlockPos end) { + public static void createBelts(World world, BlockPos start, BlockPos end) { BeltBlock.Slope slope = getSlopeBetween(start, end); Direction facing = getFacingFromTo(start, end); BlockPos diff = end.subtract(start); if (diff.getX() == diff.getZ()) - facing = Direction.getFacingFromAxis(facing.getAxisDirection(), - world.getBlockState(start).get(BlockStateProperties.AXIS) == Axis.X ? Axis.Z : Axis.X); + facing = Direction + .getFacingFromAxis(facing.getAxisDirection(), + world.getBlockState(start).get(BlockStateProperties.AXIS) == Axis.X ? Axis.Z : Axis.X); List beltsToCreate = getBeltChainBetween(start, end, slope, facing); BlockState beltBlock = AllBlocks.BELT.get().getDefaultState(); @@ -110,12 +111,17 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther { boolean pulley = AllBlocks.SHAFT.typeOf(world.getBlockState(pos)); if (part == Part.MIDDLE && pulley) part = Part.PULLEY; - world.setBlockState(pos, beltBlock.with(BeltBlock.SLOPE, slope).with(BeltBlock.PART, part) - .with(BeltBlock.HORIZONTAL_FACING, facing), 3); + world + .setBlockState(pos, + beltBlock + .with(BeltBlock.SLOPE, slope) + .with(BeltBlock.PART, part) + .with(BeltBlock.HORIZONTAL_FACING, facing), + 3); } } - private Direction getFacingFromTo(BlockPos start, BlockPos end) { + private static Direction getFacingFromTo(BlockPos start, BlockPos end) { Axis beltAxis = start.getX() == end.getX() ? Axis.Z : Axis.X; BlockPos diff = end.subtract(start); AxisDirection axisDirection = AxisDirection.POSITIVE; @@ -129,7 +135,7 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther { return Direction.getFacingFromAxis(axisDirection, beltAxis); } - private Slope getSlopeBetween(BlockPos start, BlockPos end) { + private static Slope getSlopeBetween(BlockPos start, BlockPos end) { BlockPos diff = end.subtract(start); if (diff.getY() != 0) { @@ -140,7 +146,7 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther { return Slope.HORIZONTAL; } - private List getBeltChainBetween(BlockPos start, BlockPos end, Slope slope, Direction direction) { + private static List getBeltChainBetween(BlockPos start, BlockPos end, Slope slope, Direction direction) { List positions = new LinkedList<>(); int limit = 1000; BlockPos current = start; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/transport/BeltInventory.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/transport/BeltInventory.java index abf85f488..41196d14b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/transport/BeltInventory.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/transport/BeltInventory.java @@ -118,18 +118,18 @@ public class BeltInventory { float diffToEnd = beltMovementPositive ? belt.beltLength - currentPos : -currentPos; float limitedMovement = beltMovementPositive ? Math.min(movement, diffToEnd) : Math.max(movement, diffToEnd); - float nextOffset = current.beltPosition + limitedMovement; - if (!onClient) { + + if (!onClient && segmentBefore != -1) { // Don't move if belt attachments want to continue processing - if (segmentBefore != -1 && current.locked) { + if (current.locked) { BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore); if (beltSegment != null) { - + // wait in case belt isnt initialized yet if (current.locked && beltSegment.trackerUpdateTag != null) continue; - + current.locked = false; List attachments = beltSegment.attachmentTracker.attachments; for (BeltAttachmentState attachmentState : attachments) { @@ -146,22 +146,24 @@ public class BeltInventory { } // See if any new belt processing catches the item - int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f)); - for (int segment = upcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset - : segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) { - BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore); - if (beltSegment == null) - break; - for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) { - ItemStack stackBefore = current.stack.copy(); - if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) { - current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f); - current.locked = true; - belt.sendData(); - continue Items; + if (current.beltPosition > .5f || beltMovementPositive) { + int firstUpcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f)); + for (int segment = firstUpcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset + : segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) { + BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segment); + if (beltSegment == null) + break; + for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) { + ItemStack stackBefore = current.stack.copy(); + if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) { + current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f); + current.locked = true; + belt.sendData(); + continue Items; + } + if (!stackBefore.equals(current.stack, true)) + belt.sendData(); } - if (!stackBefore.equals(current.stack, true)) - belt.sendData(); } } } @@ -202,8 +204,9 @@ public class BeltInventory { if (segment == -1) continue; if (!world.isRemote) - world.updateComparatorOutputLevel(BeltHelper.getPositionForOffset(belt, segment), - belt.getBlockState().getBlock()); + world + .updateComparatorOutputLevel(BeltHelper.getPositionForOffset(belt, segment), + belt.getBlockState().getBlock()); } } @@ -392,7 +395,8 @@ public class BeltInventory { public void read(CompoundNBT nbt) { getItems().clear(); - nbt.getList("Items", NBT.TAG_COMPOUND) + nbt + .getList("Items", NBT.TAG_COMPOUND) .forEach(inbt -> getItems().add(TransportedItemStack.read((CompoundNBT) inbt))); beltMovementPositive = nbt.getBoolean("PositiveOrder"); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/AdjustablePulleyTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/AdjustablePulleyTileEntity.java index 1deacba3e..755894047 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/AdjustablePulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/AdjustablePulleyTileEntity.java @@ -33,6 +33,8 @@ public class AdjustablePulleyTileEntity extends KineticTileEntity { } public void neighborChanged() { + if (!hasWorld()) + return; int power = world.getRedstonePowerFromNeighbors(pos); if (power != signal) signalChanged = true; diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/StockswitchTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/StockswitchTileEntity.java index 3922b79c1..c4b51bdb6 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/StockswitchTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/StockswitchTileEntity.java @@ -117,7 +117,9 @@ public class StockswitchTileEntity extends SyncedTileEntity { if (!invState.hasTileEntity()) return false; TileEntity invTE = world.getTileEntity(invPos); - + if (invTE == null) + return false; + observedInventory = invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); if (observedInventory.isPresent()) { updateCurrentLevel(); diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java index 241e68a62..67caa78ea 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java @@ -4,6 +4,8 @@ import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.RedstoneWireBlock; import net.minecraft.state.BooleanProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.util.Direction; @@ -28,13 +30,9 @@ public class LatchBlock extends ToggleLatchBlock { @Override protected void updateState(World worldIn, BlockPos pos, BlockState state) { boolean back = state.get(POWERED); - boolean shouldBack = this.shouldBePowered(worldIn, pos, state); + boolean shouldBack = shouldBePowered(worldIn, pos, state); boolean side = state.get(POWERED_SIDE); - - Direction direction = state.get(HORIZONTAL_FACING); - Direction left = direction.rotateY(); - Direction right = direction.rotateYCCW(); - boolean shouldSide = worldIn.isSidePowered(pos, left) || worldIn.isSidePowered(pos, right); + boolean shouldSide = isPoweredOnSides(worldIn, pos, state); TickPriority tickpriority = TickPriority.HIGH; if (this.isFacingTowardsRepeater(worldIn, pos, state)) @@ -48,16 +46,28 @@ public class LatchBlock extends ToggleLatchBlock { worldIn.getPendingBlockTicks().scheduleTick(pos, this, this.getDelay(state), tickpriority); } + protected boolean isPoweredOnSides(World worldIn, BlockPos pos, BlockState state) { + Direction direction = state.get(HORIZONTAL_FACING); + Direction left = direction.rotateY(); + Direction right = direction.rotateYCCW(); + + for (Direction d : new Direction[] { left, right }) { + BlockPos blockpos = pos.offset(d); + int i = worldIn.getRedstonePower(blockpos, d); + if (i > 0) + return true; + BlockState blockstate = worldIn.getBlockState(blockpos); + return blockstate.getBlock() == Blocks.REDSTONE_WIRE ? blockstate.get(RedstoneWireBlock.POWER) > 0 : false; + } + return false; + } + @Override public void tick(BlockState state, World worldIn, BlockPos pos, Random random) { boolean back = state.get(POWERED); boolean shouldBack = this.shouldBePowered(worldIn, pos, state); boolean side = state.get(POWERED_SIDE); - - Direction direction = state.get(HORIZONTAL_FACING); - Direction left = direction.rotateY(); - Direction right = direction.rotateYCCW(); - boolean shouldSide = worldIn.isBlockPowered(pos.offset(left)) || worldIn.isBlockPowered(pos.offset(right)); + boolean shouldSide = isPoweredOnSides(worldIn, pos, state); BlockState stateIn = state; if (back != shouldBack) { diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateTileEntity.java index 234d63c48..665971392 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/inventories/FlexcrateTileEntity.java @@ -93,7 +93,7 @@ public class FlexcrateTileEntity extends CrateTileEntity implements INamedContai return getOtherCrate(); return this; } - + public void onSplit() { FlexcrateTileEntity other = getOtherCrate(); if (other == null) @@ -181,7 +181,7 @@ public class FlexcrateTileEntity extends CrateTileEntity implements INamedContai public LazyOptional getCapability(Capability capability, Direction facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { FlexcrateTileEntity mainCrate = getMainCrate(); - if (mainCrate != null && mainCrate.invHandler.isPresent()) + if (mainCrate != null && mainCrate.invHandler != null && mainCrate.invHandler.isPresent()) return mainCrate.invHandler.cast(); } return super.getCapability(capability, facing); diff --git a/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java b/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java index 629c02af0..f283eb3fe 100644 --- a/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java +++ b/src/main/java/com/simibubi/create/modules/schematics/block/LaunchedItem.java @@ -2,6 +2,12 @@ package com.simibubi.create.modules.schematics.block; import java.util.Optional; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; +import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem; +import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock; + import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -9,6 +15,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; @@ -28,8 +35,7 @@ public abstract class LaunchedItem { return (int) (Math.max(10, MathHelper.sqrt(MathHelper.sqrt(target.distanceSq(start))) * 4f)); } - LaunchedItem() { - } + LaunchedItem() {} private LaunchedItem(BlockPos target, ItemStack stack, int ticksLeft, int total) { this.target = target; @@ -60,8 +66,8 @@ public abstract class LaunchedItem { } public static LaunchedItem fromNBT(CompoundNBT c) { - LaunchedItem launched = - c.contains("BlockState") ? new LaunchedItem.ForBlockState() : new LaunchedItem.ForEntity(); + LaunchedItem launched = c.contains("Length") ? new LaunchedItem.ForBelt() + : c.contains("BlockState") ? new LaunchedItem.ForBlockState() : new LaunchedItem.ForEntity(); launched.readNBT(c); return launched; } @@ -78,8 +84,7 @@ public abstract class LaunchedItem { public static class ForBlockState extends LaunchedItem { public BlockState state; - ForBlockState() { - } + ForBlockState() {} public ForBlockState(BlockPos start, BlockPos target, ItemStack stack, BlockState state) { super(start, target, stack); @@ -105,18 +110,59 @@ public abstract class LaunchedItem { if (state.has(BlockStateProperties.EXTENDED)) state = state.with(BlockStateProperties.EXTENDED, false); + if (AllBlocks.BELT.typeOf(state)) { + world.setBlockState(target, state, 2); + return; + } + world.setBlockState(target, state, 18); state.getBlock().onBlockPlacedBy(world, target, state, null, stack); } } + public static class ForBelt extends ForBlockState { + public int length; + + public ForBelt() {} + + @Override + public CompoundNBT serializeNBT() { + CompoundNBT serializeNBT = super.serializeNBT(); + serializeNBT.putInt("Length", length); + return serializeNBT; + } + + @Override + void readNBT(CompoundNBT nbt) { + length = nbt.getInt("Length"); + super.readNBT(nbt); + } + + public ForBelt(BlockPos start, BlockPos target, ItemStack stack, BlockState state, int length) { + super(start, target, stack, state); + this.length = length; + } + + @Override + void place(World world) { + // todo place belt + boolean isStart = state.get(BeltBlock.PART) == Part.START; + BlockPos offset = BeltBlock.nextSegmentPosition(state, BlockPos.ZERO, isStart); + int i = length - 1; + Axis axis = state.get(BeltBlock.HORIZONTAL_FACING).rotateY().getAxis(); + world.setBlockState(target, AllBlocks.SHAFT.getDefault().with(ShaftBlock.AXIS, axis)); + BeltConnectorItem + .createBelts(world, target, target.add(offset.getX() * i, offset.getY() * i, offset.getZ() * i)); + } + + } + public static class ForEntity extends LaunchedItem { public Entity entity; private CompoundNBT deferredTag; - ForEntity() { - } + ForEntity() {} public ForEntity(BlockPos start, BlockPos target, ItemStack stack, Entity entity) { super(start, target, 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 3ebed6948..e67d8b78f 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 @@ -13,6 +13,11 @@ import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; +import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; +import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock; import com.simibubi.create.modules.schematics.ItemRequirement; import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType; import com.simibubi.create.modules.schematics.MaterialChecklist; @@ -41,11 +46,13 @@ import net.minecraft.state.properties.DoubleBlockHalf; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; +import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; +import net.minecraft.world.gen.feature.template.PlacementSettings; import net.minecraft.world.gen.feature.template.Template; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -456,7 +463,14 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC ItemStack icon = requirement.isEmpty() || requiredItems.isEmpty() ? ItemStack.EMPTY : requiredItems.get(0); if (entityMode) launchEntity(target, icon, blockReader.getEntities().get(printingEntityIndex)); - else + else if (AllBlocks.BELT.typeOf(blockState)) { + TileEntity te = blockReader.getTileEntity(currentPos.add(schematicAnchor)); + blockState = stripBeltIfNotLast(blockState); + if (te instanceof BeltTileEntity && AllBlocks.BELT.typeOf(blockState)) + launchBelt(target, blockState, ((BeltTileEntity) te).beltLength); + else + launchBlock(target, icon, blockState); + } else launchBlock(target, icon, blockState); printerCooldown = config().schematicannonDelay.get(); @@ -465,6 +479,33 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC missingItem = null; } + public BlockState stripBeltIfNotLast(BlockState blockState) { + // is highest belt? + boolean isLastSegment = false; + Direction facing = blockState.get(BeltBlock.HORIZONTAL_FACING); + Slope slope = blockState.get(BeltBlock.SLOPE); + boolean positive = facing.getAxisDirection() == AxisDirection.POSITIVE; + boolean start = blockState.get(BeltBlock.PART) == Part.START; + boolean end = blockState.get(BeltBlock.PART) == Part.END; + + switch (slope) { + case DOWNWARD: + isLastSegment = start; + break; + case UPWARD: + isLastSegment = end; + break; + case HORIZONTAL: + case VERTICAL: + default: + isLastSegment = positive && end || !positive && start; + } + if (!isLastSegment) + blockState = (blockState.get(BeltBlock.PART) == Part.MIDDLE) ? Blocks.AIR.getDefaultState() + : AllBlocks.SHAFT.getDefault().with(ShaftBlock.AXIS, facing.rotateY().getAxis()); + return blockState; + } + public double getFuelUsageRate() { return hasCreativeCrate ? 0 : config().schematicannonFuelUsage.get() / 100f; } @@ -504,7 +545,8 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC schematicAnchor = anchor; blockReader = new SchematicWorld(schematicAnchor, world); - activeTemplate.addBlocksToWorld(blockReader, schematicAnchor, SchematicItem.getSettings(blueprint)); + PlacementSettings settings = SchematicItem.getSettings(blueprint); + activeTemplate.addBlocksToWorld(blockReader, schematicAnchor, settings); schematicLoaded = true; state = State.PAUSED; statusMsg = "ready"; @@ -766,6 +808,13 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC sendUpdate = true; } + protected void launchBelt(BlockPos target, BlockState state, int length) { + blocksPlaced++; + ItemStack connector = AllItems.BELT_CONNECTOR.asStack(); + flyingBlocks.add(new LaunchedItem.ForBelt(this.getPos(), target, connector, state, length)); + playFiringSound(); + } + protected void launchBlock(BlockPos target, ItemStack stack, BlockState state) { if (state.getBlock() != Blocks.AIR) blocksPlaced++; 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 c53bc74fa..a7f42a22f 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 @@ -17,6 +17,7 @@ import com.simibubi.create.modules.schematics.client.SchematicEditScreen; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.nbt.CompoundNBT; @@ -26,6 +27,7 @@ import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.util.Mirror; +import net.minecraft.util.NonNullList; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; @@ -61,6 +63,9 @@ public class SchematicItem extends Item { return blueprint; } + @Override + public void fillItemGroup(ItemGroup group, NonNullList items) {} + @Override @OnlyIn(value = Dist.CLIENT) public void addInformation(ItemStack stack, World worldIn, List tooltip, ITooltipFlag flagIn) { diff --git a/src/main/resources/data/create/advancements/expert_lane_1.json b/src/main/resources/data/create/advancements/expert_lane_1.json deleted file mode 100644 index aeca3d781..000000000 --- a/src/main/resources/data/create/advancements/expert_lane_1.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "create:andesite_casing", - "display": { - "icon": { - "item": "minecraft:andesite" - }, - "title": { - "translate": "advancement.create.expert_lane_1" - }, - "description": { - "translate": "advancement.create.expert_lane_1.desc" - }, - "frame": "challenge", - "show_toast": false, - "announce_to_chat": false, - "hidden": false - }, - "criteria": { - "0": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { - "item": "create:andesite_casing" - } - ] - } - } - }, - "requirements": [ - [ - "0" - ] - ] -} \ No newline at end of file