Bundle o' bugfixes
- Fix Extendo Grip not applying extended reach when equipped on rejoin - Fix mechanical crafters duping + dropping their items when added to minecart contraption - Fix Wand of Symmetry duping rails under placed cart assemblers - Lecterns now keep NBT when moved by contraption - Super glue entities hanging on positions above build limit now get removed - Fix harvester replanting sweet berry bushes in wrong state - Cuckoo clock and clockwork bearing now go crazy in unnatural dimensions
This commit is contained in:
parent
c97da3868f
commit
12bfc78443
9 changed files with 296 additions and 187 deletions
|
@ -4,6 +4,8 @@ import static net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
@ -150,11 +152,15 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
|
|||
}
|
||||
|
||||
private BlockState cutCrop(World world, BlockPos pos, BlockState state) {
|
||||
if (state.getBlock() instanceof CropsBlock) {
|
||||
CropsBlock crop = (CropsBlock) state.getBlock();
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof CropsBlock) {
|
||||
CropsBlock crop = (CropsBlock) block;
|
||||
return crop.withAge(0);
|
||||
}
|
||||
if (state.getBlock() == Blocks.SUGAR_CANE || state.getBlock() == Blocks.KELP) {
|
||||
if (block == Blocks.SWEET_BERRY_BUSH) {
|
||||
return state.with(BlockStateProperties.AGE_0_3, Integer.valueOf(1));
|
||||
}
|
||||
if (block == Blocks.SUGAR_CANE || block == Blocks.KELP) {
|
||||
if (state.getFluidState()
|
||||
.isEmpty())
|
||||
return Blocks.AIR.getDefaultState();
|
||||
|
@ -162,7 +168,7 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
|
|||
.getBlockState();
|
||||
}
|
||||
if (state.getCollisionShape(world, pos)
|
||||
.isEmpty() || state.getBlock() instanceof CocoaBlock) {
|
||||
.isEmpty() || block instanceof CocoaBlock) {
|
||||
for (Property<?> property : state.getProperties()) {
|
||||
if (!(property instanceof IntegerProperty))
|
||||
continue;
|
||||
|
|
|
@ -41,7 +41,7 @@ public class CuckooClockTileEntity extends KineticTileEntity {
|
|||
super(type);
|
||||
animationType = Animation.NONE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
|
||||
super.fromTag(state, compound, clientPacket);
|
||||
|
@ -51,7 +51,7 @@ public class CuckooClockTileEntity extends KineticTileEntity {
|
|||
animationProgress.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||
if (clientPacket && sendAnimationUpdate)
|
||||
|
@ -66,10 +66,24 @@ public class CuckooClockTileEntity extends KineticTileEntity {
|
|||
if (getSpeed() == 0)
|
||||
return;
|
||||
|
||||
int dayTime = (int) (world.getDayTime() % 24000);
|
||||
|
||||
boolean isNatural = world.getDimension().isNatural();
|
||||
int dayTime = (int) ((world.getDayTime() * (isNatural ? 1 : 24)) % 24000);
|
||||
int hours = (dayTime / 1000 + 6) % 24;
|
||||
int minutes = (dayTime % 1000) * 60 / 1000;
|
||||
|
||||
if (!isNatural) {
|
||||
if (world.isRemote) {
|
||||
moveHands(hours, minutes);
|
||||
|
||||
if (AnimationTickHolder.getTicks() % 6 == 0)
|
||||
playSound(SoundEvents.BLOCK_NOTE_BLOCK_HAT, 1 / 16f, 2f);
|
||||
else if (AnimationTickHolder.getTicks() % 3 == 0)
|
||||
playSound(SoundEvents.BLOCK_NOTE_BLOCK_HAT, 1 / 16f, 1.5f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!world.isRemote) {
|
||||
if (animationType == Animation.NONE) {
|
||||
if (hours == 12 && minutes < 5)
|
||||
|
@ -150,10 +164,10 @@ public class CuckooClockTileEntity extends KineticTileEntity {
|
|||
animationProgress.lastValue = 0;
|
||||
animationProgress.value = 0;
|
||||
sendAnimationUpdate = true;
|
||||
|
||||
|
||||
if (animation == Animation.CREEPER)
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.CUCKOO, world, pos, 10);
|
||||
|
||||
|
||||
sendData();
|
||||
}
|
||||
|
||||
|
|
|
@ -119,11 +119,11 @@ public class ClockworkBearingTileEntity extends KineticTileEntity
|
|||
protected void applyRotations() {
|
||||
BlockState blockState = getBlockState();
|
||||
Axis axis = Axis.X;
|
||||
|
||||
|
||||
if (blockState.contains(BlockStateProperties.FACING))
|
||||
axis = blockState.get(BlockStateProperties.FACING)
|
||||
.getAxis();
|
||||
|
||||
|
||||
if (hourHand != null) {
|
||||
hourHand.setAngle(hourAngle);
|
||||
hourHand.setRotationAxis(axis);
|
||||
|
@ -177,7 +177,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity
|
|||
}
|
||||
|
||||
protected float getHourTarget(boolean cycle24) {
|
||||
int dayTime = (int) (world.getDayTime() % 24000);
|
||||
boolean isNatural = world.getDimension().isNatural();
|
||||
int dayTime = (int) ((world.getDayTime() * (isNatural ? 1 : 24)) % 24000);
|
||||
int hours = (dayTime / 1000 + 6) % 24;
|
||||
int offset = getBlockState().get(ClockworkBearingBlock.FACING)
|
||||
.getAxisDirection()
|
||||
|
@ -187,7 +188,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity
|
|||
}
|
||||
|
||||
protected float getMinuteTarget() {
|
||||
int dayTime = (int) (world.getDayTime() % 24000);
|
||||
boolean isNatural = world.getDimension().isNatural();
|
||||
int dayTime = (int) ((world.getDayTime() * (isNatural ? 1 : 24)) % 24000);
|
||||
int minutes = (dayTime % 1000) * 60 / 1000;
|
||||
int offset = getBlockState().get(ClockworkBearingBlock.FACING)
|
||||
.getAxisDirection()
|
||||
|
|
|
@ -181,6 +181,8 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
|||
public boolean onValidSurface() {
|
||||
BlockPos pos = hangingPosition;
|
||||
BlockPos pos2 = hangingPosition.offset(getFacingDirection().getOpposite());
|
||||
if (pos2.getY() >= 256)
|
||||
return false;
|
||||
if (!world.isAreaLoaded(pos, 0) || !world.isAreaLoaded(pos2, 0))
|
||||
return true;
|
||||
if (!isValidFace(world, pos2, getFacingDirection())
|
||||
|
|
|
@ -138,42 +138,7 @@ public class CartAssemblerBlock extends AbstractRailBlock
|
|||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
withTileEntityDo(world, pos, te -> {
|
||||
if (!te.isMinecartUpdateValid())
|
||||
return;
|
||||
|
||||
CartAssemblerAction action = getActionForCart(state, cart);
|
||||
if (action.shouldAssemble())
|
||||
assemble(world, pos, cart);
|
||||
if (action.shouldDisassemble())
|
||||
disassemble(world, pos, cart);
|
||||
if (action == CartAssemblerAction.ASSEMBLE_ACCELERATE) {
|
||||
Direction facing = cart.getAdjustedHorizontalFacing();
|
||||
|
||||
RailShape railShape = state.get(RAIL_SHAPE);
|
||||
for (Direction d : Iterate.directionsInAxis(railShape == RailShape.EAST_WEST ? Axis.X : Axis.Z))
|
||||
if (world.getBlockState(pos.offset(d))
|
||||
.isNormalCube(world, pos.offset(d)))
|
||||
facing = d.getOpposite();
|
||||
|
||||
float speed = getRailMaxSpeed(state, world, pos, cart);
|
||||
cart.setMotion(facing.getXOffset() * speed, facing.getYOffset() * speed, facing.getZOffset() * speed);
|
||||
}
|
||||
if (action == CartAssemblerAction.ASSEMBLE_ACCELERATE_DIRECTIONAL) {
|
||||
Vector3i accelerationVector = ControllerRailBlock.getAccelerationVector(
|
||||
AllBlocks.CONTROLLER_RAIL.getDefaultState()
|
||||
.with(ControllerRailBlock.SHAPE, state.get(RAIL_SHAPE))
|
||||
.with(ControllerRailBlock.BACKWARDS, state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS));
|
||||
float speed = getRailMaxSpeed(state, world, pos, cart);
|
||||
cart.setMotion(Vector3d.of(accelerationVector).scale(speed));
|
||||
}
|
||||
if (action == CartAssemblerAction.DISASSEMBLE_BRAKE) {
|
||||
Vector3d diff = VecHelper.getCenterOf(pos)
|
||||
.subtract(cart.getPositionVec());
|
||||
cart.setMotion(diff.x / 16f, 0, diff.z / 16f);
|
||||
}
|
||||
|
||||
});
|
||||
withTileEntityDo(world, pos, te -> te.assembleNextTick(cart));
|
||||
}
|
||||
|
||||
public enum CartAssemblerAction {
|
||||
|
@ -245,124 +210,6 @@ public class CartAssemblerBlock extends AbstractRailBlock
|
|||
return ActionResultType.PASS;
|
||||
}
|
||||
|
||||
protected void assemble(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||
if (!cart.getPassengers()
|
||||
.isEmpty())
|
||||
return;
|
||||
|
||||
LazyOptional<MinecartController> optional =
|
||||
cart.getCapability(CapabilityMinecartController.MINECART_CONTROLLER_CAPABILITY);
|
||||
if (optional.isPresent() && optional.orElse(null)
|
||||
.isCoupledThroughContraption())
|
||||
return;
|
||||
|
||||
Optional<CartAssemblerTileEntity> assembler = getTileEntityOptional(world, pos);
|
||||
CartMovementMode mode = assembler.map(te -> CartMovementMode.values()[te.movementMode.value])
|
||||
.orElse(CartMovementMode.ROTATE);
|
||||
|
||||
MountedContraption contraption = new MountedContraption(mode);
|
||||
try {
|
||||
if (!contraption.assemble(world, pos))
|
||||
return;
|
||||
|
||||
assembler.ifPresent(te -> {
|
||||
te.lastException = null;
|
||||
te.sendData();
|
||||
});
|
||||
} catch (AssemblyException e) {
|
||||
assembler.ifPresent(te -> {
|
||||
te.lastException = e;
|
||||
te.sendData();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
boolean couplingFound = contraption.connectedCart != null;
|
||||
Optional<Direction> initialOrientation = cart.getMotion()
|
||||
.length() < 1 / 512f ? Optional.empty() : Optional.of(cart.getAdjustedHorizontalFacing());
|
||||
|
||||
if (couplingFound) {
|
||||
cart.setPosition(pos.getX() + .5f, pos.getY(), pos.getZ() + .5f);
|
||||
if (!CouplingHandler.tryToCoupleCarts(null, world, cart.getEntityId(),
|
||||
contraption.connectedCart.getEntityId()))
|
||||
return;
|
||||
}
|
||||
|
||||
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
||||
contraption.startMoving(world);
|
||||
contraption.expandBoundsAroundAxis(Axis.Y);
|
||||
|
||||
if (couplingFound) {
|
||||
Vector3d diff = contraption.connectedCart.getPositionVec()
|
||||
.subtract(cart.getPositionVec());
|
||||
initialOrientation = Optional.of(Direction.fromAngle(MathHelper.atan2(diff.z, diff.x) * 180 / Math.PI));
|
||||
}
|
||||
|
||||
OrientedContraptionEntity entity = OrientedContraptionEntity.create(world, contraption, initialOrientation);
|
||||
if (couplingFound)
|
||||
entity.setCouplingId(cart.getUniqueID());
|
||||
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||
world.addEntity(entity);
|
||||
entity.startRiding(cart);
|
||||
|
||||
if (cart instanceof FurnaceMinecartEntity) {
|
||||
CompoundNBT nbt = cart.serializeNBT();
|
||||
nbt.putDouble("PushZ", 0);
|
||||
nbt.putDouble("PushX", 0);
|
||||
cart.deserializeNBT(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
protected void disassemble(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||
if (cart.getPassengers()
|
||||
.isEmpty())
|
||||
return;
|
||||
Entity entity = cart.getPassengers()
|
||||
.get(0);
|
||||
if (!(entity instanceof OrientedContraptionEntity))
|
||||
return;
|
||||
OrientedContraptionEntity contraption = (OrientedContraptionEntity) entity;
|
||||
UUID couplingId = contraption.getCouplingId();
|
||||
|
||||
if (couplingId == null) {
|
||||
disassembleCart(cart);
|
||||
return;
|
||||
}
|
||||
|
||||
Couple<MinecartController> coupledCarts = contraption.getCoupledCartsIfPresent();
|
||||
if (coupledCarts == null)
|
||||
return;
|
||||
|
||||
// Make sure connected cart is present and being disassembled
|
||||
for (boolean current : Iterate.trueAndFalse) {
|
||||
MinecartController minecartController = coupledCarts.get(current);
|
||||
if (minecartController.cart() == cart)
|
||||
continue;
|
||||
BlockPos otherPos = minecartController.cart()
|
||||
.getBlockPos();
|
||||
BlockState blockState = world.getBlockState(otherPos);
|
||||
if (!AllBlocks.CART_ASSEMBLER.has(blockState))
|
||||
return;
|
||||
if (!getActionForCart(blockState, minecartController.cart()).shouldDisassemble())
|
||||
return;
|
||||
}
|
||||
|
||||
for (boolean current : Iterate.trueAndFalse)
|
||||
coupledCarts.get(current)
|
||||
.removeConnection(current);
|
||||
disassembleCart(cart);
|
||||
}
|
||||
|
||||
protected void disassembleCart(AbstractMinecartEntity cart) {
|
||||
cart.removePassengers();
|
||||
if (cart instanceof FurnaceMinecartEntity) {
|
||||
CompoundNBT nbt = cart.serializeNBT();
|
||||
nbt.putDouble("PushZ", cart.getMotion().x);
|
||||
nbt.putDouble("PushX", cart.getMotion().z);
|
||||
cart.deserializeNBT(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(@Nonnull BlockState state, @Nonnull World worldIn, @Nonnull BlockPos pos,
|
||||
@Nonnull Block blockIn, @Nonnull BlockPos fromPos, boolean isMoving) {
|
||||
|
|
|
@ -1,9 +1,20 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.mounted;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IDisplayAssemblyExceptions;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingHandler;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartController;
|
||||
import com.simibubi.create.content.contraptions.components.tracks.ControllerRailBlock;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
@ -11,15 +22,26 @@ import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxT
|
|||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.INamedIconOptions;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||
import net.minecraft.entity.item.minecart.FurnaceMinecartEntity;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.RailShape;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.math.vector.Vector3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplayAssemblyExceptions {
|
||||
private static final int assemblyCooldown = 8;
|
||||
|
@ -28,6 +50,8 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay
|
|||
private int ticksSinceMinecartUpdate;
|
||||
protected AssemblyException lastException;
|
||||
|
||||
protected AbstractMinecartEntity cartToAssemble;
|
||||
|
||||
public CartAssemblerTileEntity(TileEntityType<? extends CartAssemblerTileEntity> type) {
|
||||
super(type);
|
||||
ticksSinceMinecartUpdate = assemblyCooldown;
|
||||
|
@ -39,6 +63,166 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay
|
|||
if (ticksSinceMinecartUpdate < assemblyCooldown) {
|
||||
ticksSinceMinecartUpdate++;
|
||||
}
|
||||
|
||||
tryAssemble(cartToAssemble);
|
||||
cartToAssemble = null;
|
||||
}
|
||||
|
||||
public void tryAssemble(AbstractMinecartEntity cart) {
|
||||
if (cart == null)
|
||||
return;
|
||||
|
||||
if (!isMinecartUpdateValid())
|
||||
return;
|
||||
resetTicksSinceMinecartUpdate();
|
||||
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!AllBlocks.CART_ASSEMBLER.has(state))
|
||||
return;
|
||||
CartAssemblerBlock block = (CartAssemblerBlock) state.getBlock();
|
||||
|
||||
CartAssemblerBlock.CartAssemblerAction action = CartAssemblerBlock.getActionForCart(state, cart);
|
||||
if (action.shouldAssemble())
|
||||
assemble(world, pos, cart);
|
||||
if (action.shouldDisassemble())
|
||||
disassemble(world, pos, cart);
|
||||
if (action == CartAssemblerBlock.CartAssemblerAction.ASSEMBLE_ACCELERATE) {
|
||||
Direction facing = cart.getAdjustedHorizontalFacing();
|
||||
|
||||
RailShape railShape = state.get(CartAssemblerBlock.RAIL_SHAPE);
|
||||
for (Direction d : Iterate.directionsInAxis(railShape == RailShape.EAST_WEST ? Axis.X : Axis.Z))
|
||||
if (world.getBlockState(pos.offset(d))
|
||||
.isNormalCube(world, pos.offset(d)))
|
||||
facing = d.getOpposite();
|
||||
|
||||
float speed = block.getRailMaxSpeed(state, world, pos, cart);
|
||||
cart.setMotion(facing.getXOffset() * speed, facing.getYOffset() * speed, facing.getZOffset() * speed);
|
||||
}
|
||||
if (action == CartAssemblerBlock.CartAssemblerAction.ASSEMBLE_ACCELERATE_DIRECTIONAL) {
|
||||
Vector3i accelerationVector = ControllerRailBlock.getAccelerationVector(
|
||||
AllBlocks.CONTROLLER_RAIL.getDefaultState()
|
||||
.with(ControllerRailBlock.SHAPE, state.get(CartAssemblerBlock.RAIL_SHAPE))
|
||||
.with(ControllerRailBlock.BACKWARDS, state.get(CartAssemblerBlock.RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS));
|
||||
float speed = block.getRailMaxSpeed(state, world, pos, cart);
|
||||
cart.setMotion(Vector3d.of(accelerationVector).scale(speed));
|
||||
}
|
||||
if (action == CartAssemblerBlock.CartAssemblerAction.DISASSEMBLE_BRAKE) {
|
||||
Vector3d diff = VecHelper.getCenterOf(pos)
|
||||
.subtract(cart.getPositionVec());
|
||||
cart.setMotion(diff.x / 16f, 0, diff.z / 16f);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assemble(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||
if (!cart.getPassengers()
|
||||
.isEmpty())
|
||||
return;
|
||||
|
||||
LazyOptional<MinecartController> optional =
|
||||
cart.getCapability(CapabilityMinecartController.MINECART_CONTROLLER_CAPABILITY);
|
||||
if (optional.isPresent() && optional.orElse(null)
|
||||
.isCoupledThroughContraption())
|
||||
return;
|
||||
|
||||
CartMovementMode mode = CartMovementMode.values()[movementMode.value];
|
||||
|
||||
MountedContraption contraption = new MountedContraption(mode);
|
||||
try {
|
||||
if (!contraption.assemble(world, pos))
|
||||
return;
|
||||
|
||||
lastException = null;
|
||||
sendData();
|
||||
} catch (AssemblyException e) {
|
||||
lastException = e;
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean couplingFound = contraption.connectedCart != null;
|
||||
Optional<Direction> initialOrientation = cart.getMotion()
|
||||
.length() < 1 / 512f ? Optional.empty() : Optional.of(cart.getAdjustedHorizontalFacing());
|
||||
|
||||
if (couplingFound) {
|
||||
cart.setPosition(pos.getX() + .5f, pos.getY(), pos.getZ() + .5f);
|
||||
if (!CouplingHandler.tryToCoupleCarts(null, world, cart.getEntityId(),
|
||||
contraption.connectedCart.getEntityId()))
|
||||
return;
|
||||
}
|
||||
|
||||
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
|
||||
contraption.startMoving(world);
|
||||
contraption.expandBoundsAroundAxis(Axis.Y);
|
||||
|
||||
if (couplingFound) {
|
||||
Vector3d diff = contraption.connectedCart.getPositionVec()
|
||||
.subtract(cart.getPositionVec());
|
||||
initialOrientation = Optional.of(Direction.fromAngle(MathHelper.atan2(diff.z, diff.x) * 180 / Math.PI));
|
||||
}
|
||||
|
||||
OrientedContraptionEntity entity = OrientedContraptionEntity.create(world, contraption, initialOrientation);
|
||||
if (couplingFound)
|
||||
entity.setCouplingId(cart.getUniqueID());
|
||||
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||
world.addEntity(entity);
|
||||
entity.startRiding(cart);
|
||||
|
||||
if (cart instanceof FurnaceMinecartEntity) {
|
||||
CompoundNBT nbt = cart.serializeNBT();
|
||||
nbt.putDouble("PushZ", 0);
|
||||
nbt.putDouble("PushX", 0);
|
||||
cart.deserializeNBT(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
protected void disassemble(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||
if (cart.getPassengers()
|
||||
.isEmpty())
|
||||
return;
|
||||
Entity entity = cart.getPassengers()
|
||||
.get(0);
|
||||
if (!(entity instanceof OrientedContraptionEntity))
|
||||
return;
|
||||
OrientedContraptionEntity contraption = (OrientedContraptionEntity) entity;
|
||||
UUID couplingId = contraption.getCouplingId();
|
||||
|
||||
if (couplingId == null) {
|
||||
disassembleCart(cart);
|
||||
return;
|
||||
}
|
||||
|
||||
Couple<MinecartController> coupledCarts = contraption.getCoupledCartsIfPresent();
|
||||
if (coupledCarts == null)
|
||||
return;
|
||||
|
||||
// Make sure connected cart is present and being disassembled
|
||||
for (boolean current : Iterate.trueAndFalse) {
|
||||
MinecartController minecartController = coupledCarts.get(current);
|
||||
if (minecartController.cart() == cart)
|
||||
continue;
|
||||
BlockPos otherPos = minecartController.cart()
|
||||
.getBlockPos();
|
||||
BlockState blockState = world.getBlockState(otherPos);
|
||||
if (!AllBlocks.CART_ASSEMBLER.has(blockState))
|
||||
return;
|
||||
if (!CartAssemblerBlock.getActionForCart(blockState, minecartController.cart()).shouldDisassemble())
|
||||
return;
|
||||
}
|
||||
|
||||
for (boolean current : Iterate.trueAndFalse)
|
||||
coupledCarts.get(current)
|
||||
.removeConnection(current);
|
||||
disassembleCart(cart);
|
||||
}
|
||||
|
||||
protected void disassembleCart(AbstractMinecartEntity cart) {
|
||||
cart.removePassengers();
|
||||
if (cart instanceof FurnaceMinecartEntity) {
|
||||
CompoundNBT nbt = cart.serializeNBT();
|
||||
nbt.putDouble("PushZ", cart.getMotion().x);
|
||||
nbt.putDouble("PushX", cart.getMotion().z);
|
||||
cart.deserializeNBT(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,7 +255,7 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay
|
|||
}
|
||||
|
||||
private class CartAssemblerValueBoxTransform extends CenteredSideValueBoxTransform {
|
||||
|
||||
|
||||
public CartAssemblerValueBoxTransform() {
|
||||
super((state, d) -> {
|
||||
if (d.getAxis()
|
||||
|
@ -83,15 +267,15 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay
|
|||
return (d.getAxis() == Axis.X) == (railShape == RailShape.NORTH_SOUTH);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Vector3d getSouthLocation() {
|
||||
return VecHelper.voxelSpace(8, 8, 18);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static enum CartMovementMode implements INamedIconOptions {
|
||||
|
||||
public enum CartMovementMode implements INamedIconOptions {
|
||||
|
||||
ROTATE(AllIcons.I_CART_ROTATE),
|
||||
ROTATE_PAUSED(AllIcons.I_CART_ROTATE_PAUSED),
|
||||
|
@ -102,7 +286,7 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay
|
|||
private String translationKey;
|
||||
private AllIcons icon;
|
||||
|
||||
private CartMovementMode(AllIcons icon) {
|
||||
CartMovementMode(AllIcons icon) {
|
||||
this.icon = icon;
|
||||
translationKey = "contraptions.cart_movement_mode." + Lang.asId(name());
|
||||
}
|
||||
|
@ -122,6 +306,11 @@ public class CartAssemblerTileEntity extends SmartTileEntity implements IDisplay
|
|||
ticksSinceMinecartUpdate = 0;
|
||||
}
|
||||
|
||||
public void assembleNextTick(AbstractMinecartEntity cart) {
|
||||
if (cartToAssemble == null)
|
||||
cartToAssemble = cart;
|
||||
}
|
||||
|
||||
public boolean isMinecartUpdateValid() {
|
||||
return ticksSinceMinecartUpdate >= assemblyCooldown;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Map;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock;
|
||||
import com.simibubi.create.content.curiosities.symmetry.mirror.CrossPlaneMirror;
|
||||
import com.simibubi.create.content.curiosities.symmetry.mirror.EmptyMirror;
|
||||
import com.simibubi.create.content.curiosities.symmetry.mirror.PlaneMirror;
|
||||
|
@ -229,8 +231,17 @@ public class SymmetryWandItem extends Item {
|
|||
continue;
|
||||
if (toReplace.getBlockHardness(world, position) == -1)
|
||||
continue;
|
||||
if (BlockHelper.findAndRemoveInInventory(blockState, player, 1) == 0)
|
||||
continue;
|
||||
|
||||
if (AllBlocks.CART_ASSEMBLER.has(blockState)) {
|
||||
BlockState railBlock = CartAssemblerBlock.getRailBlock(blockState);
|
||||
if (BlockHelper.findAndRemoveInInventory(railBlock, player, 1) == 0)
|
||||
continue;
|
||||
if (BlockHelper.findAndRemoveInInventory(blockState, player, 1) == 0)
|
||||
blockState = railBlock;
|
||||
} else {
|
||||
if (BlockHelper.findAndRemoveInInventory(blockState, player, 1) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockSnapshot blocksnapshot = BlockSnapshot.create(world.getRegistryKey(), world, position);
|
||||
FluidState ifluidstate = world.getFluidState(position);
|
||||
|
|
|
@ -37,6 +37,7 @@ import net.minecraftforge.event.entity.living.LivingAttackEvent;
|
|||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingKnockBackEvent;
|
||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
@ -65,14 +66,15 @@ public class ExtendoGripItem extends Item {
|
|||
.rarity(Rarity.UNCOMMON));
|
||||
}
|
||||
|
||||
public static final String EXTENDO_MARKER = "createExtendo";
|
||||
public static final String DUAL_EXTENDO_MARKER = "createDualExtendo";
|
||||
|
||||
@SubscribeEvent
|
||||
public static void holdingExtendoGripIncreasesRange(LivingUpdateEvent event) {
|
||||
if (!(event.getEntity() instanceof PlayerEntity))
|
||||
return;
|
||||
|
||||
PlayerEntity player = (PlayerEntity) event.getEntityLiving();
|
||||
String marker = "createExtendo";
|
||||
String dualMarker = "createDualExtendo";
|
||||
|
||||
CompoundNBT persistentData = player.getPersistentData();
|
||||
boolean inOff = AllItems.EXTENDO_GRIP.isIn(player.getHeldItemOffhand());
|
||||
|
@ -80,19 +82,19 @@ public class ExtendoGripItem extends Item {
|
|||
boolean holdingDualExtendo = inOff && inMain;
|
||||
boolean holdingExtendo = inOff ^ inMain;
|
||||
holdingExtendo &= !holdingDualExtendo;
|
||||
boolean wasHoldingExtendo = persistentData.contains(marker);
|
||||
boolean wasHoldingDualExtendo = persistentData.contains(dualMarker);
|
||||
boolean wasHoldingExtendo = persistentData.contains(EXTENDO_MARKER);
|
||||
boolean wasHoldingDualExtendo = persistentData.contains(DUAL_EXTENDO_MARKER);
|
||||
|
||||
if (holdingExtendo != wasHoldingExtendo) {
|
||||
if (!holdingExtendo) {
|
||||
player.getAttributes().removeModifiers(rangeModifier.getValue());
|
||||
persistentData.remove(marker);
|
||||
persistentData.remove(EXTENDO_MARKER);
|
||||
} else {
|
||||
if (player instanceof ServerPlayerEntity)
|
||||
AllTriggers.EXTENDO.trigger((ServerPlayerEntity) player);
|
||||
player.getAttributes()
|
||||
.addTemporaryModifiers(rangeModifier.getValue());
|
||||
persistentData.putBoolean(marker, true);
|
||||
persistentData.putBoolean(EXTENDO_MARKER, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,18 +102,29 @@ public class ExtendoGripItem extends Item {
|
|||
if (!holdingDualExtendo) {
|
||||
player.getAttributes()
|
||||
.removeModifiers(doubleRangeModifier.getValue());
|
||||
persistentData.remove(dualMarker);
|
||||
persistentData.remove(DUAL_EXTENDO_MARKER);
|
||||
} else {
|
||||
if (player instanceof ServerPlayerEntity)
|
||||
AllTriggers.GIGA_EXTENDO.trigger((ServerPlayerEntity) player);
|
||||
player.getAttributes()
|
||||
.addTemporaryModifiers(doubleRangeModifier.getValue());
|
||||
persistentData.putBoolean(dualMarker, true);
|
||||
persistentData.putBoolean(DUAL_EXTENDO_MARKER, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void addReachToJoiningPlayersHoldingExtendo(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
PlayerEntity player = event.getPlayer();
|
||||
CompoundNBT persistentData = player.getPersistentData();
|
||||
|
||||
if (persistentData.contains(DUAL_EXTENDO_MARKER))
|
||||
player.getAttributes().addTemporaryModifiers(doubleRangeModifier.getValue());
|
||||
else if (persistentData.contains(EXTENDO_MARKER))
|
||||
player.getAttributes().addTemporaryModifiers(rangeModifier.getValue());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void dontMissEntitiesWhenYouHaveHighReachDistance(ClickInputEvent event) {
|
||||
|
|
|
@ -11,10 +11,14 @@ import com.simibubi.create.content.logistics.item.filter.FilterItem;
|
|||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.INBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.StringNBT;
|
||||
import net.minecraft.tileentity.MobSpawnerTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
public final class NBTProcessors {
|
||||
|
||||
|
@ -32,10 +36,26 @@ public final class NBTProcessors {
|
|||
static {
|
||||
addProcessor(TileEntityType.SIGN, data -> {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
String s = data.getString("Text" + (i + 1));
|
||||
ITextComponent textcomponent = ITextComponent.Serializer.fromJson(s.isEmpty() ? "\"\"" : s);
|
||||
if (textcomponent != null && textcomponent.getStyle() != null && textcomponent.getStyle()
|
||||
.getClickEvent() != null)
|
||||
if (textComponentHasClickEvent(data.getString("Text" + (i + 1))))
|
||||
return null;
|
||||
}
|
||||
return data;
|
||||
});
|
||||
addProcessor(TileEntityType.LECTERN, data -> {
|
||||
if (!data.contains("Book", Constants.NBT.TAG_COMPOUND))
|
||||
return data;
|
||||
CompoundNBT book = data.getCompound("Book");
|
||||
|
||||
if (!book.contains("tag", Constants.NBT.TAG_COMPOUND))
|
||||
return data;
|
||||
CompoundNBT tag = book.getCompound("tag");
|
||||
|
||||
if (!tag.contains("pages", Constants.NBT.TAG_LIST))
|
||||
return data;
|
||||
ListNBT pages = tag.getList("pages", Constants.NBT.TAG_STRING);
|
||||
|
||||
for (INBT inbt : pages) {
|
||||
if (textComponentHasClickEvent(inbt.getString()))
|
||||
return null;
|
||||
}
|
||||
return data;
|
||||
|
@ -50,6 +70,11 @@ public final class NBTProcessors {
|
|||
});
|
||||
}
|
||||
|
||||
public static boolean textComponentHasClickEvent(String json) {
|
||||
ITextComponent component = ITextComponent.Serializer.fromJson(json.isEmpty() ? "\"\"" : json);
|
||||
return component != null && component.getStyle() != null && component.getStyle().getClickEvent() != null;
|
||||
}
|
||||
|
||||
private NBTProcessors() {}
|
||||
|
||||
@Nullable
|
||||
|
|
Loading…
Reference in a new issue