mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-13 05:54:17 +01:00
Hot belt replace
- The Wrench can now be used to shorten or divide Mechanical Belts - Belt Connectors can now be used to extend or merge Mechanical Belts
This commit is contained in:
parent
b05506ad46
commit
aa3d656445
@ -13,6 +13,7 @@ import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.processing.EmptyingByBasin;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltSlicer.Feedback;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity.CasingType;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltTunnelInteractionHandler;
|
||||
@ -96,7 +97,8 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
|
||||
@Override
|
||||
protected boolean areStatesKineticallyEquivalent(BlockState oldState, BlockState newState) {
|
||||
return super.areStatesKineticallyEquivalent(oldState, newState) && oldState.getValue(PART) == newState.getValue(PART);
|
||||
return super.areStatesKineticallyEquivalent(oldState, newState)
|
||||
&& oldState.getValue(PART) == newState.getValue(PART);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -104,7 +106,7 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
if (face.getAxis() != getRotationAxis(state))
|
||||
return false;
|
||||
return getTileEntityOptional(world, pos).map(BeltTileEntity::hasPulley)
|
||||
.orElse(false);
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -122,15 +124,6 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
return AllItems.BELT_CONNECTOR.asStack();
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME
|
||||
*
|
||||
* @Override
|
||||
* public Material getMaterial(BlockState state) {
|
||||
* return state.get(CASING) ? Material.WOOD : Material.WOOL;
|
||||
* }
|
||||
*/
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, net.minecraft.loot.LootContext.Builder builder) {
|
||||
@ -241,6 +234,9 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
if (player.isShiftKeyDown() || !player.mayBuild())
|
||||
return ActionResultType.PASS;
|
||||
ItemStack heldItem = player.getItemInHand(handIn);
|
||||
|
||||
boolean isWrench = AllItems.WRENCH.isIn(heldItem);
|
||||
boolean isConnector = AllItems.BELT_CONNECTOR.isIn(heldItem);
|
||||
boolean isShaft = AllBlocks.SHAFT.isIn(heldItem);
|
||||
boolean isDye = Tags.Items.DYES.contains(heldItem.getItem());
|
||||
boolean hasWater = EmptyingByBasin.emptyItem(world, heldItem, true)
|
||||
@ -255,6 +251,11 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
if (isConnector)
|
||||
return BeltSlicer.useConnector(state, world, pos, player, handIn, hit, new Feedback());
|
||||
if (isWrench)
|
||||
return BeltSlicer.useWrench(state, world, pos, player, handIn, hit, new Feedback());
|
||||
|
||||
BeltTileEntity belt = BeltHelper.getSegmentTE(world, pos);
|
||||
if (belt == null)
|
||||
return ActionResultType.PASS;
|
||||
@ -274,7 +275,7 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
});
|
||||
if (success.isTrue())
|
||||
world.playSound(null, pos, SoundEvents.ITEM_PICKUP, SoundCategory.PLAYERS, .2f,
|
||||
1f + Create.RANDOM.nextFloat());
|
||||
1f + Create.RANDOM.nextFloat());
|
||||
}
|
||||
|
||||
if (isShaft) {
|
||||
@ -329,7 +330,7 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
return ActionResultType.FAIL;
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -378,7 +379,8 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
return BeltShapes.getCollisionShape(state);
|
||||
return shape;
|
||||
|
||||
}).orElse(shape);
|
||||
})
|
||||
.orElse(shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -499,8 +501,8 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction side, BlockState p_196271_3_, IWorld world,
|
||||
BlockPos pos, BlockPos p_196271_6_) {
|
||||
public BlockState updateShape(BlockState state, Direction side, BlockState p_196271_3_, IWorld world, BlockPos pos,
|
||||
BlockPos p_196271_6_) {
|
||||
if (side.getAxis()
|
||||
.isHorizontal())
|
||||
updateTunnelConnections(world, pos.above());
|
||||
@ -552,29 +554,6 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||
}
|
||||
|
||||
public static boolean canAccessFromSide(Direction facing, BlockState belt) {
|
||||
// if (facing == null)
|
||||
// return true;
|
||||
// if (!belt.get(BeltBlock.CASING))
|
||||
// return false;
|
||||
// BeltPart part = belt.get(BeltBlock.PART);
|
||||
// if (part != BeltPart.MIDDLE && facing.getAxis() == belt.get(HORIZONTAL_FACING)
|
||||
// .rotateY()
|
||||
// .getAxis())
|
||||
// return false;
|
||||
//
|
||||
// BeltSlope slope = belt.get(BeltBlock.SLOPE);
|
||||
// if (slope != BeltSlope.HORIZONTAL) {
|
||||
// if (slope == BeltSlope.DOWNWARD && part == BeltPart.END)
|
||||
// return true;
|
||||
// if (slope == BeltSlope.UPWARD && part == BeltPart.START)
|
||||
// return true;
|
||||
// Direction beltSide = belt.get(HORIZONTAL_FACING);
|
||||
// if (slope == BeltSlope.DOWNWARD)
|
||||
// beltSide = beltSide.getOpposite();
|
||||
// if (beltSide == facing)
|
||||
// return false;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.relays.belt;
|
||||
import com.simibubi.create.AllTags.AllItemTags;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@ -75,7 +76,8 @@ public class BeltHelper {
|
||||
verticalMovement = verticalMovement * (Math.min(offset, controller.beltLength - .5f) - .5f);
|
||||
Vector3d vec = VecHelper.getCenterOf(controller.getBlockPos());
|
||||
Vector3d horizontalMovement = Vector3d.atLowerCornerOf(controller.getBeltFacing()
|
||||
.getNormal()).scale(offset - .5f);
|
||||
.getNormal())
|
||||
.scale(offset - .5f);
|
||||
|
||||
if (slope == BeltSlope.VERTICAL)
|
||||
horizontalMovement = Vector3d.ZERO;
|
||||
@ -85,4 +87,16 @@ public class BeltHelper {
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static Vector3d getBeltVector(BlockState state) {
|
||||
BeltSlope slope = state.getValue(BeltBlock.SLOPE);
|
||||
int verticality = slope == BeltSlope.DOWNWARD ? -1 : slope == BeltSlope.UPWARD ? 1 : 0;
|
||||
Vector3d horizontalMovement = Vector3d.atLowerCornerOf(state.getValue(BeltBlock.HORIZONTAL_FACING)
|
||||
.getNormal());
|
||||
if (slope == BeltSlope.VERTICAL)
|
||||
return new Vector3d(0, state.getValue(BeltBlock.HORIZONTAL_FACING)
|
||||
.getAxisDirection()
|
||||
.getStep(), 0);
|
||||
return new Vector3d(0, verticality, 0).add(horizontalMovement);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -301,8 +301,8 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
||||
|
||||
protected int getPackedLight(BeltTileEntity controller, float beltPos) {
|
||||
int segment = (int) Math.floor(beltPos) * 2;
|
||||
|
||||
if (controller.light == null || segment >= controller.light.length) return 0;
|
||||
if (controller.light == null || segment >= controller.light.length || segment < 0)
|
||||
return 0;
|
||||
|
||||
return (controller.light[segment + 1] << 20) | (controller.light[segment] << 4);
|
||||
}
|
||||
|
@ -0,0 +1,472 @@
|
||||
package com.simibubi.create.content.contraptions.relays.belt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity.CasingType;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorItem;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.DyeColor;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
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.RayTraceResult;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.Constants.BlockFlags;
|
||||
|
||||
public class BeltSlicer {
|
||||
|
||||
public static class Feedback {
|
||||
int color = 0xffffff;
|
||||
AxisAlignedBB bb;
|
||||
String langKey;
|
||||
TextFormatting formatting = TextFormatting.WHITE;
|
||||
}
|
||||
|
||||
public static ActionResultType useWrench(BlockState state, World world, BlockPos pos, PlayerEntity player,
|
||||
Hand handIn, BlockRayTraceResult hit, Feedback feedBack) {
|
||||
BeltTileEntity controllerTE = BeltHelper.getControllerTE(world, pos);
|
||||
if (controllerTE == null)
|
||||
return ActionResultType.PASS;
|
||||
if (state.getValue(BeltBlock.CASING) && hit.getDirection() != Direction.UP)
|
||||
return ActionResultType.PASS;
|
||||
if (state.getValue(BeltBlock.PART) == BeltPart.PULLEY && hit.getDirection()
|
||||
.getAxis() != Axis.Y)
|
||||
return ActionResultType.PASS;
|
||||
|
||||
int beltLength = controllerTE.beltLength;
|
||||
if (beltLength == 2)
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
BlockPos beltVector = new BlockPos(BeltHelper.getBeltVector(state));
|
||||
BeltPart part = state.getValue(BeltBlock.PART);
|
||||
List<BlockPos> beltChain = BeltBlock.getBeltChain(world, controllerTE.getBlockPos());
|
||||
boolean creative = player.isCreative();
|
||||
|
||||
// Shorten from End
|
||||
if (hoveringEnd(state, hit)) {
|
||||
if (world.isClientSide)
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
for (BlockPos blockPos : beltChain) {
|
||||
BeltTileEntity belt = BeltHelper.getSegmentTE(world, blockPos);
|
||||
if (belt == null)
|
||||
continue;
|
||||
belt.detachKinetics();
|
||||
belt.invalidateItemHandler();
|
||||
belt.beltLength = 0;
|
||||
}
|
||||
|
||||
BeltInventory inventory = controllerTE.inventory;
|
||||
BlockPos next = part == BeltPart.END ? pos.subtract(beltVector) : pos.offset(beltVector);
|
||||
BlockState replacedState = world.getBlockState(next);
|
||||
BeltTileEntity segmentTE = BeltHelper.getSegmentTE(world, next);
|
||||
KineticTileEntity.switchToBlockState(world, next,
|
||||
state.setValue(BeltBlock.CASING, segmentTE != null && segmentTE.casing != CasingType.NONE));
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3 | BlockFlags.IS_MOVING);
|
||||
world.removeBlockEntity(pos);
|
||||
world.levelEvent(2001, pos, Block.getId(state));
|
||||
|
||||
if (!creative && AllBlocks.BELT.has(replacedState)
|
||||
&& replacedState.getValue(BeltBlock.PART) == BeltPart.PULLEY)
|
||||
player.inventory.placeItemBackInInventory(world, AllBlocks.SHAFT.asStack());
|
||||
|
||||
// Eject overshooting items
|
||||
if (part == BeltPart.END && inventory != null) {
|
||||
List<TransportedItemStack> toEject = new ArrayList<>();
|
||||
for (TransportedItemStack transportedItemStack : inventory.getTransportedItems())
|
||||
if (transportedItemStack.beltPosition > beltLength - 1)
|
||||
toEject.add(transportedItemStack);
|
||||
toEject.forEach(inventory::eject);
|
||||
toEject.forEach(inventory.getTransportedItems()::remove);
|
||||
}
|
||||
|
||||
// Transfer items to new controller
|
||||
if (part == BeltPart.START && segmentTE != null && inventory != null) {
|
||||
controllerTE.inventory = null;
|
||||
segmentTE.inventory = null;
|
||||
segmentTE.setController(next);
|
||||
for (TransportedItemStack transportedItemStack : inventory.getTransportedItems()) {
|
||||
transportedItemStack.beltPosition -= 1;
|
||||
if (transportedItemStack.beltPosition <= 0) {
|
||||
ItemEntity entity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + 11 / 16f,
|
||||
pos.getZ() + .5f, transportedItemStack.stack);
|
||||
entity.setDeltaMovement(Vector3d.ZERO);
|
||||
entity.setDefaultPickUpDelay();
|
||||
entity.hurtMarked = true;
|
||||
world.addFreshEntity(entity);
|
||||
} else
|
||||
segmentTE.getInventory()
|
||||
.addItem(transportedItemStack);
|
||||
}
|
||||
}
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
BeltTileEntity segmentTE = BeltHelper.getSegmentTE(world, pos);
|
||||
if (segmentTE == null)
|
||||
return ActionResultType.PASS;
|
||||
|
||||
// Split in half
|
||||
int hitSegment = segmentTE.index;
|
||||
Vector3d centerOf = VecHelper.getCenterOf(hit.getBlockPos());
|
||||
Vector3d subtract = hit.getLocation()
|
||||
.subtract(centerOf);
|
||||
boolean towardPositive = subtract.dot(Vector3d.atLowerCornerOf(beltVector)) > 0;
|
||||
BlockPos next = !towardPositive ? pos.subtract(beltVector) : pos.offset(beltVector);
|
||||
|
||||
if (hitSegment == 0 || hitSegment == 1 && !towardPositive)
|
||||
return ActionResultType.FAIL;
|
||||
if (hitSegment == controllerTE.beltLength - 1 || hitSegment == controllerTE.beltLength - 2 && towardPositive)
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
// Look for shafts
|
||||
if (!creative) {
|
||||
int requiredShafts = 0;
|
||||
if (!segmentTE.hasPulley())
|
||||
requiredShafts++;
|
||||
BlockState other = world.getBlockState(next);
|
||||
if (AllBlocks.BELT.has(other) && other.getValue(BeltBlock.PART) == BeltPart.MIDDLE)
|
||||
requiredShafts++;
|
||||
|
||||
int amountRetrieved = 0;
|
||||
Search: while (true) {
|
||||
for (int i = 0; i < player.inventory.getContainerSize(); ++i) {
|
||||
if (amountRetrieved == requiredShafts)
|
||||
break Search;
|
||||
|
||||
ItemStack itemstack = player.inventory.getItem(i);
|
||||
if (itemstack.isEmpty())
|
||||
continue;
|
||||
int count = itemstack.getCount();
|
||||
if (AllBlocks.SHAFT.isIn(itemstack)) {
|
||||
int taken = Math.min(count, requiredShafts - amountRetrieved);
|
||||
if (taken == count)
|
||||
player.inventory.setItem(i, ItemStack.EMPTY);
|
||||
else
|
||||
itemstack.shrink(taken);
|
||||
amountRetrieved += taken;
|
||||
}
|
||||
}
|
||||
|
||||
player.inventory.placeItemBackInInventory(world, AllBlocks.SHAFT.asStack(amountRetrieved));
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isClientSide) {
|
||||
for (BlockPos blockPos : beltChain) {
|
||||
BeltTileEntity belt = BeltHelper.getSegmentTE(world, blockPos);
|
||||
if (belt == null)
|
||||
continue;
|
||||
belt.detachKinetics();
|
||||
belt.invalidateItemHandler();
|
||||
belt.beltLength = 0;
|
||||
}
|
||||
|
||||
BeltInventory inventory = controllerTE.inventory;
|
||||
KineticTileEntity.switchToBlockState(world, pos,
|
||||
state.setValue(BeltBlock.PART, towardPositive ? BeltPart.END : BeltPart.START));
|
||||
KineticTileEntity.switchToBlockState(world, next, world.getBlockState(next)
|
||||
.setValue(BeltBlock.PART, towardPositive ? BeltPart.START : BeltPart.END));
|
||||
world.playSound(null, pos, SoundEvents.WOOL_HIT,
|
||||
player == null ? SoundCategory.BLOCKS : SoundCategory.PLAYERS, 0.5F, 2.3F);
|
||||
|
||||
// Transfer items to new controller
|
||||
BeltTileEntity newController = towardPositive ? BeltHelper.getSegmentTE(world, next) : segmentTE;
|
||||
if (newController != null && inventory != null) {
|
||||
newController.inventory = null;
|
||||
newController.setController(newController.getBlockPos());
|
||||
for (Iterator<TransportedItemStack> iterator = inventory.getTransportedItems()
|
||||
.iterator(); iterator.hasNext();) {
|
||||
TransportedItemStack transportedItemStack = iterator.next();
|
||||
float newPosition = transportedItemStack.beltPosition - hitSegment - (towardPositive ? 1 : 0);
|
||||
if (newPosition <= 0)
|
||||
continue;
|
||||
transportedItemStack.beltPosition = newPosition;
|
||||
iterator.remove();
|
||||
newController.getInventory()
|
||||
.addItem(transportedItemStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
public static ActionResultType useConnector(BlockState state, World world, BlockPos pos, PlayerEntity player,
|
||||
Hand handIn, BlockRayTraceResult hit, Feedback feedBack) {
|
||||
BeltTileEntity controllerTE = BeltHelper.getControllerTE(world, pos);
|
||||
if (controllerTE == null)
|
||||
return ActionResultType.PASS;
|
||||
|
||||
int beltLength = controllerTE.beltLength;
|
||||
if (beltLength == BeltConnectorItem.maxLength())
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
BlockPos beltVector = new BlockPos(BeltHelper.getBeltVector(state));
|
||||
BeltPart part = state.getValue(BeltBlock.PART);
|
||||
Direction facing = state.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
List<BlockPos> beltChain = BeltBlock.getBeltChain(world, controllerTE.getBlockPos());
|
||||
boolean creative = player.isCreative();
|
||||
|
||||
if (!hoveringEnd(state, hit))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
BlockPos next = part == BeltPart.START ? pos.subtract(beltVector) : pos.offset(beltVector);
|
||||
BeltTileEntity mergedController = null;
|
||||
int mergedBeltLength = 0;
|
||||
|
||||
// Merge Belts / Extend at End
|
||||
BlockState nextState = world.getBlockState(next);
|
||||
if (!nextState.getMaterial()
|
||||
.isReplaceable()) {
|
||||
if (!AllBlocks.BELT.has(nextState))
|
||||
return ActionResultType.FAIL;
|
||||
if (!beltStatesCompatible(state, nextState))
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
mergedController = BeltHelper.getControllerTE(world, next);
|
||||
if (mergedController == null)
|
||||
return ActionResultType.FAIL;
|
||||
if (mergedController.beltLength + beltLength > BeltConnectorItem.maxLength())
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
mergedBeltLength = mergedController.beltLength;
|
||||
|
||||
if (!world.isClientSide) {
|
||||
boolean flipBelt = facing != nextState.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
Optional<DyeColor> color = controllerTE.color;
|
||||
for (BlockPos blockPos : BeltBlock.getBeltChain(world, mergedController.getBlockPos())) {
|
||||
BeltTileEntity belt = BeltHelper.getSegmentTE(world, blockPos);
|
||||
if (belt == null)
|
||||
continue;
|
||||
belt.detachKinetics();
|
||||
belt.invalidateItemHandler();
|
||||
belt.beltLength = 0;
|
||||
belt.color = color;
|
||||
if (flipBelt)
|
||||
world.setBlock(blockPos, flipBelt(world.getBlockState(blockPos)), 3 | BlockFlags.IS_MOVING);
|
||||
}
|
||||
|
||||
// Reverse items
|
||||
if (flipBelt && mergedController.inventory != null) {
|
||||
List<TransportedItemStack> transportedItems = mergedController.inventory.getTransportedItems();
|
||||
for (TransportedItemStack transportedItemStack : transportedItems) {
|
||||
transportedItemStack.beltPosition = mergedBeltLength - transportedItemStack.beltPosition;
|
||||
transportedItemStack.prevBeltPosition =
|
||||
mergedBeltLength - transportedItemStack.prevBeltPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isClientSide) {
|
||||
for (BlockPos blockPos : beltChain) {
|
||||
BeltTileEntity belt = BeltHelper.getSegmentTE(world, blockPos);
|
||||
if (belt == null)
|
||||
continue;
|
||||
belt.detachKinetics();
|
||||
belt.invalidateItemHandler();
|
||||
belt.beltLength = 0;
|
||||
}
|
||||
|
||||
BeltInventory inventory = controllerTE.inventory;
|
||||
KineticTileEntity.switchToBlockState(world, pos, state.setValue(BeltBlock.PART, BeltPart.MIDDLE));
|
||||
|
||||
if (mergedController == null) {
|
||||
// Attach at end
|
||||
world.setBlock(next, state.setValue(BeltBlock.CASING, false), 3 | BlockFlags.IS_MOVING);
|
||||
BeltTileEntity segmentTE = BeltHelper.getSegmentTE(world, next);
|
||||
if (segmentTE != null)
|
||||
segmentTE.color = controllerTE.color;
|
||||
world.playSound(null, pos, SoundEvents.WOOL_PLACE,
|
||||
player == null ? SoundCategory.BLOCKS : SoundCategory.PLAYERS, 0.5F, 1F);
|
||||
|
||||
// Transfer items to new controller
|
||||
if (part == BeltPart.START && segmentTE != null && inventory != null) {
|
||||
segmentTE.setController(next);
|
||||
for (TransportedItemStack transportedItemStack : inventory.getTransportedItems()) {
|
||||
transportedItemStack.beltPosition += 1;
|
||||
segmentTE.getInventory()
|
||||
.addItem(transportedItemStack);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Merge with other
|
||||
BeltInventory mergedInventory = mergedController.inventory;
|
||||
world.playSound(null, pos, SoundEvents.WOOL_HIT,
|
||||
player == null ? SoundCategory.BLOCKS : SoundCategory.PLAYERS, 0.5F, 1.3F);
|
||||
BeltTileEntity segmentTE = BeltHelper.getSegmentTE(world, next);
|
||||
KineticTileEntity.switchToBlockState(world, next,
|
||||
state.setValue(BeltBlock.CASING, segmentTE != null && segmentTE.casing != CasingType.NONE)
|
||||
.setValue(BeltBlock.PART, BeltPart.MIDDLE));
|
||||
|
||||
if (!creative)
|
||||
player.inventory.placeItemBackInInventory(world, AllBlocks.SHAFT.asStack(2));
|
||||
|
||||
// Transfer items to other controller
|
||||
BlockPos search = controllerTE.getBlockPos();
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
BlockState blockState = world.getBlockState(search);
|
||||
if (!AllBlocks.BELT.has(blockState))
|
||||
break;
|
||||
if (blockState.getValue(BeltBlock.PART) != BeltPart.START) {
|
||||
search = search.subtract(beltVector);
|
||||
continue;
|
||||
}
|
||||
|
||||
BeltTileEntity newController = BeltHelper.getSegmentTE(world, search);
|
||||
|
||||
if (newController != controllerTE && inventory != null) {
|
||||
newController.setController(search);
|
||||
controllerTE.inventory = null;
|
||||
for (TransportedItemStack transportedItemStack : inventory.getTransportedItems()) {
|
||||
transportedItemStack.beltPosition += mergedBeltLength;
|
||||
newController.getInventory()
|
||||
.addItem(transportedItemStack);
|
||||
}
|
||||
}
|
||||
|
||||
if (newController != mergedController && mergedInventory != null) {
|
||||
newController.setController(search);
|
||||
mergedController.inventory = null;
|
||||
for (TransportedItemStack transportedItemStack : mergedInventory.getTransportedItems()) {
|
||||
if (newController == controllerTE)
|
||||
transportedItemStack.beltPosition += beltLength;
|
||||
newController.getInventory()
|
||||
.addItem(transportedItemStack);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
static boolean beltStatesCompatible(BlockState state, BlockState nextState) {
|
||||
Direction facing1 = state.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
BeltSlope slope1 = state.getValue(BeltBlock.SLOPE);
|
||||
Direction facing2 = nextState.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
BeltSlope slope2 = nextState.getValue(BeltBlock.SLOPE);
|
||||
|
||||
switch (slope1) {
|
||||
case UPWARD:
|
||||
if (slope2 == BeltSlope.DOWNWARD)
|
||||
return facing1 == facing2.getOpposite();
|
||||
return slope2 == slope1 && facing1 == facing2;
|
||||
case DOWNWARD:
|
||||
if (slope2 == BeltSlope.UPWARD)
|
||||
return facing1 == facing2.getOpposite();
|
||||
return slope2 == slope1 && facing1 == facing2;
|
||||
default:
|
||||
return slope2 == slope1 && facing2.getAxis() == facing1.getAxis();
|
||||
}
|
||||
}
|
||||
|
||||
static BlockState flipBelt(BlockState state) {
|
||||
Direction facing = state.getValue(BeltBlock.HORIZONTAL_FACING);
|
||||
BeltSlope slope = state.getValue(BeltBlock.SLOPE);
|
||||
BeltPart part = state.getValue(BeltBlock.PART);
|
||||
|
||||
if (slope == BeltSlope.UPWARD)
|
||||
state = state.setValue(BeltBlock.SLOPE, BeltSlope.DOWNWARD);
|
||||
else if (slope == BeltSlope.DOWNWARD)
|
||||
state = state.setValue(BeltBlock.SLOPE, BeltSlope.UPWARD);
|
||||
|
||||
if (part == BeltPart.END)
|
||||
state = state.setValue(BeltBlock.PART, BeltPart.START);
|
||||
else if (part == BeltPart.START)
|
||||
state = state.setValue(BeltBlock.PART, BeltPart.END);
|
||||
|
||||
return state.setValue(BeltBlock.HORIZONTAL_FACING, facing.getOpposite());
|
||||
}
|
||||
|
||||
static boolean hoveringEnd(BlockState state, BlockRayTraceResult hit) {
|
||||
BeltPart part = state.getValue(BeltBlock.PART);
|
||||
if (part == BeltPart.MIDDLE || part == BeltPart.PULLEY)
|
||||
return false;
|
||||
|
||||
Vector3d beltVector = BeltHelper.getBeltVector(state);
|
||||
Vector3d centerOf = VecHelper.getCenterOf(hit.getBlockPos());
|
||||
Vector3d subtract = hit.getLocation()
|
||||
.subtract(centerOf);
|
||||
|
||||
return subtract.dot(beltVector) > 0 == (part == BeltPart.END);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void tickHoveringInformation() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
RayTraceResult target = mc.hitResult;
|
||||
if (target == null || !(target instanceof BlockRayTraceResult))
|
||||
return;
|
||||
|
||||
BlockRayTraceResult result = (BlockRayTraceResult) target;
|
||||
ClientWorld world = mc.level;
|
||||
BlockPos pos = result.getBlockPos();
|
||||
BlockState state = world.getBlockState(pos);
|
||||
ItemStack held = mc.player.getItemInHand(Hand.MAIN_HAND);
|
||||
ItemStack heldOffHand = mc.player.getItemInHand(Hand.OFF_HAND);
|
||||
|
||||
if (mc.player.isShiftKeyDown())
|
||||
return;
|
||||
if (!AllBlocks.BELT.has(state))
|
||||
return;
|
||||
|
||||
Feedback feedback = new Feedback();
|
||||
|
||||
// TODO: Populate feedback in the methods for clientside
|
||||
if (AllItems.WRENCH.isIn(held) || AllItems.WRENCH.isIn(heldOffHand))
|
||||
useWrench(state, world, pos, mc.player, Hand.MAIN_HAND, result, feedback);
|
||||
else if (AllItems.BELT_CONNECTOR.isIn(held) || AllItems.BELT_CONNECTOR.isIn(heldOffHand))
|
||||
useConnector(state, world, pos, mc.player, Hand.MAIN_HAND, result, feedback);
|
||||
else
|
||||
return;
|
||||
|
||||
if (feedback.langKey != null)
|
||||
mc.player.displayClientMessage(Lang.translate(feedback.langKey)
|
||||
.withStyle(feedback.formatting), true);
|
||||
else
|
||||
mc.player.displayClientMessage(new StringTextComponent(""), true);
|
||||
|
||||
if (feedback.bb != null)
|
||||
CreateClient.OUTLINER.chaseAABB("BeltSlicer", feedback.bb)
|
||||
.lineWidth(1 / 16f)
|
||||
.colored(feedback.color);
|
||||
}
|
||||
|
||||
}
|
@ -223,8 +223,15 @@ public class BeltTileEntity extends KineticTileEntity implements ILightUpdateLis
|
||||
if (!isController())
|
||||
controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
||||
trackerUpdateTag = compound;
|
||||
beltLength = compound.getInt("Length");
|
||||
index = compound.getInt("Index");
|
||||
int length = compound.getInt("Length");
|
||||
if (beltLength != length) {
|
||||
beltLength = length;
|
||||
if (level != null)
|
||||
initializeLight();
|
||||
else
|
||||
light = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (isController())
|
||||
@ -516,6 +523,10 @@ public class BeltTileEntity extends KineticTileEntity implements ILightUpdateLis
|
||||
return getController().equals(((BeltTileEntity) target).getController()) ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void invalidateItemHandler() {
|
||||
itemHandler.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderNormally() {
|
||||
@ -524,7 +535,7 @@ public class BeltTileEntity extends KineticTileEntity implements ILightUpdateLis
|
||||
BlockState state = getBlockState();
|
||||
return state != null && state.hasProperty(BeltBlock.PART) && state.getValue(BeltBlock.PART) == BeltPart.START;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onLightUpdate(IBlockDisplayReader world, LightType type, GridAlignedBB changed) {
|
||||
if (this.remove) {
|
||||
|
@ -15,6 +15,7 @@ import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftB
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
@ -31,6 +32,8 @@ import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@ -118,6 +121,8 @@ public class BeltConnectorItem extends BlockItem {
|
||||
}
|
||||
|
||||
public static void createBelts(World world, BlockPos start, BlockPos end) {
|
||||
world.playSound(null, new BlockPos(VecHelper.getCenterOf(start.offset(end))
|
||||
.scale(.5f)), SoundEvents.WOOL_PLACE, SoundCategory.BLOCKS, 0.5F, 1F);
|
||||
|
||||
BeltSlope slope = getSlopeBetween(start, end);
|
||||
Direction facing = getFacingFromTo(start, end);
|
||||
@ -152,8 +157,8 @@ public class BeltConnectorItem extends BlockItem {
|
||||
if (diff.getX() == 0 && diff.getZ() == 0)
|
||||
axisDirection = diff.getY() > 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE;
|
||||
else
|
||||
axisDirection = beltAxis.choose(diff.getX(), 0, diff.getZ()) > 0 ? AxisDirection.POSITIVE
|
||||
: AxisDirection.NEGATIVE;
|
||||
axisDirection =
|
||||
beltAxis.choose(diff.getX(), 0, diff.getZ()) > 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE;
|
||||
|
||||
return Direction.get(axisDirection, beltAxis);
|
||||
}
|
||||
@ -169,7 +174,8 @@ public class BeltConnectorItem extends BlockItem {
|
||||
return BeltSlope.HORIZONTAL;
|
||||
}
|
||||
|
||||
private static List<BlockPos> getBeltChainBetween(BlockPos start, BlockPos end, BeltSlope slope, Direction direction) {
|
||||
private static List<BlockPos> getBeltChainBetween(BlockPos start, BlockPos end, BeltSlope slope,
|
||||
Direction direction) {
|
||||
List<BlockPos> positions = new LinkedList<>();
|
||||
int limit = 1000;
|
||||
BlockPos current = start;
|
||||
@ -249,7 +255,7 @@ public class BeltConnectorItem extends BlockItem {
|
||||
|
||||
}
|
||||
|
||||
protected static Integer maxLength() {
|
||||
public static Integer maxLength() {
|
||||
return AllConfigs.SERVER.kinetics.maxBeltLength.get();
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import com.simibubi.create.content.contraptions.components.turntable.TurntableHa
|
||||
import com.simibubi.create.content.contraptions.goggles.GoggleOverlayRenderer;
|
||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.content.contraptions.itemAssembly.SequencedAssemblyRecipe;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltSlicer;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorHandler;
|
||||
import com.simibubi.create.content.curiosities.armor.CopperBacktankArmorLayer;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintOverlayRenderer;
|
||||
@ -125,6 +126,7 @@ public class ClientEvents {
|
||||
// ScreenOpener.tick();
|
||||
ServerSpeedProvider.clientTick();
|
||||
BeltConnectorHandler.tick();
|
||||
BeltSlicer.tickHoveringInformation();
|
||||
FilteringRenderer.tick();
|
||||
LinkRenderer.tick();
|
||||
ScrollValueRenderer.tick();
|
||||
|
Loading…
Reference in New Issue
Block a user