Couple things, Part II

- Fixed a few major issues with dual cart assembly
- Attempted to fight the heavy loss of momentum in coupling physics
This commit is contained in:
simibubi 2020-08-06 16:29:40 +02:00
parent 7e167f3b29
commit bb5a6c45f6
7 changed files with 140 additions and 55 deletions

View File

@ -13,6 +13,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.bea
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingTileEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState;
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock;
@ -116,6 +117,8 @@ public class BlockMovementTraits {
return true;
if (block instanceof HorizontalFaceBlock)
return true;
if (block instanceof CartAssemblerBlock)
return false;
if (block instanceof AbstractRailBlock)
return true;
if (block instanceof RedstoneDiodeBlock)
@ -197,6 +200,8 @@ public class BlockMovementTraits {
public static boolean notSupportive(BlockState state, Direction facing) {
if (AllBlocks.MECHANICAL_DRILL.has(state))
return state.get(BlockStateProperties.FACING) == facing;
if (AllBlocks.CART_ASSEMBLER.has(state))
return Direction.DOWN == facing;
if (AllBlocks.MECHANICAL_SAW.has(state))
return state.get(BlockStateProperties.FACING) == facing;
if (AllBlocks.PORTABLE_STORAGE_INTERFACE.has(state))

View File

@ -6,8 +6,11 @@ import static com.simibubi.create.foundation.utility.AngleHelper.getShortestAngl
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.UUID;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.MutablePair;
import com.simibubi.create.AllEntityTypes;
@ -72,7 +75,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
protected Vec3d motionBeforeStall;
protected boolean stationary;
protected boolean initialized;
protected boolean onCoupling;
final List<Entity> collidingEntities = new ArrayList<>();
private boolean isSerializingFurnaceCart;
@ -80,6 +82,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
private static final DataParameter<Boolean> STALLED =
EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.BOOLEAN);
private static final DataParameter<Optional<UUID>> COUPLING =
EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.OPTIONAL_UNIQUE_ID);
private static final DataParameter<Optional<UUID>> COUPLED_CART =
EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.OPTIONAL_UNIQUE_ID);
public float prevYaw;
public float prevPitch;
public float prevRoll;
@ -109,11 +116,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
}
public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle,
Direction facing, boolean onCoupling) {
Direction facing) {
ContraptionEntity entity = createMounted(world, contraption, initialAngle);
entity.forcedAngle = facing.getHorizontalAngle();
entity.forceYaw(entity.forcedAngle);
entity.onCoupling = onCoupling;
return entity;
}
@ -312,27 +318,36 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
public void tickAsPassenger(Entity e) {
boolean rotationLock = false;
boolean pauseWhileRotating = false;
boolean rotating = false;
Entity riding = e;
while (riding.getRidingEntity() != null)
riding = riding.getRidingEntity();
boolean isOnCoupling = false;
if (contraption instanceof MountedContraption) {
MountedContraption mountedContraption = (MountedContraption) contraption;
if (onCoupling && riding instanceof AbstractMinecartEntity) {
MinecartCoupling coupling = MinecartCouplingHandler.getCoupling(world, riding.getUniqueID());
UUID couplingId = getCouplingId();
isOnCoupling = couplingId != null && riding instanceof AbstractMinecartEntity;
if (isOnCoupling) {
MinecartCoupling coupling = MinecartCouplingHandler.getCoupling(world, couplingId);
if (coupling != null && coupling.areBothEndsPresent()) {
boolean notOnMainCart = !coupling.getId()
.equals(riding.getUniqueID());
Vec3d positionVec = coupling.asCouple()
.getSecond()
.get(notOnMainCart)
.getPositionVec();
prevYaw = yaw;
prevPitch = pitch;
double diffZ = positionVec.z - getZ();
double diffX = positionVec.x - getX();
yaw = 90 + (float) (MathHelper.atan2(diffZ, diffX) * 180 / Math.PI);
double diffZ = positionVec.z - riding.getZ();
double diffX = positionVec.x - riding.getX();
yaw = (float) (MathHelper.atan2(diffZ, diffX) * 180 / Math.PI);
pitch = (float) (Math.atan2(positionVec.y - getY(), Math.sqrt(diffX * diffX + diffZ * diffZ)) * 180
/ Math.PI);
return;
if (notOnMainCart) {
yaw += 180;
}
}
}
@ -341,26 +356,27 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
}
Vec3d movementVector = riding.getMotion();
if (riding instanceof BoatEntity)
movementVector = getPositionVec().subtract(prevPosX, prevPosY, prevPosZ);
Vec3d motion = movementVector.normalize();
boolean rotating = false;
if (!isOnCoupling) {
if (riding instanceof BoatEntity)
movementVector = getPositionVec().subtract(prevPosX, prevPosY, prevPosZ);
Vec3d motion = movementVector.normalize();
if (!rotationLock) {
if (motion.length() > 0) {
targetYaw = yawFromVector(motion);
if (targetYaw < 0)
targetYaw += 360;
if (yaw < 0)
yaw += 360;
if (!rotationLock) {
if (motion.length() > 0) {
targetYaw = yawFromVector(motion);
if (targetYaw < 0)
targetYaw += 360;
if (yaw < 0)
yaw += 360;
}
prevYaw = yaw;
yaw = angleLerp(0.4f, yaw, targetYaw);
if (Math.abs(AngleHelper.getShortestAngleDiff(yaw, targetYaw)) < 1f)
yaw = targetYaw;
else
rotating = true;
}
prevYaw = yaw;
yaw = angleLerp(0.4f, yaw, targetYaw);
if (Math.abs(AngleHelper.getShortestAngleDiff(yaw, targetYaw)) < 1f)
yaw = targetYaw;
else
rotating = true;
}
boolean wasStalled = isStalled();
@ -579,12 +595,13 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
@Override
protected void registerData() {
this.dataManager.register(STALLED, false);
this.dataManager.register(COUPLING, null);
this.dataManager.register(COUPLED_CART, null);
}
@Override
protected void readAdditional(CompoundNBT compound) {
initialized = compound.getBoolean("Initialized");
onCoupling = compound.getBoolean("OnCoupling");
contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"));
initialAngle = compound.getFloat("InitialAngle");
forceYaw(compound.contains("ForcedYaw") ? compound.getFloat("ForcedYaw") : initialAngle);
@ -598,6 +615,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
}
if (compound.contains("Controller"))
controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller"));
if (compound.contains("OnCoupling")) {
setCouplingId(NBTUtil.readUniqueId(compound.getCompound("OnCoupling")));
setCoupledCart(NBTUtil.readUniqueId(compound.getCompound("CoupledCart")));
} else {
setCouplingId(null);
setCoupledCart(null);
}
}
public void forceYaw(float forcedYaw) {
@ -636,7 +661,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
compound.putFloat("InitialAngle", initialAngle);
compound.putBoolean("Stalled", isStalled());
compound.putBoolean("Initialized", initialized);
compound.putBoolean("OnCoupling", onCoupling);
if (getCouplingId() != null) {
compound.put("OnCoupling", NBTUtil.writeUniqueId(getCouplingId()));
compound.put("CoupledCart", NBTUtil.writeUniqueId(getCoupledCart()));
}
}
@Override
@ -849,4 +878,24 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
return e.getPushReaction() == PushReaction.NORMAL;
}
@Nullable
public UUID getCouplingId() {
Optional<UUID> uuid = dataManager.get(COUPLING);
return uuid == null ? null : uuid.isPresent() ? uuid.get() : null;
}
public void setCouplingId(UUID id) {
dataManager.set(COUPLING, Optional.ofNullable(id));
}
@Nullable
public UUID getCoupledCart() {
Optional<UUID> uuid = dataManager.get(COUPLED_CART);
return uuid.isPresent() ? uuid.get() : null;
}
public void setCoupledCart(UUID id) {
dataManager.set(COUPLED_CART, Optional.ofNullable(id));
}
}

View File

@ -46,6 +46,7 @@ import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
@ -212,12 +213,24 @@ public class CartAssemblerBlock extends AbstractRailBlock
float initialAngle = facing.getHorizontalAngle();
withTileEntityDo(world, pos, te -> contraption.rotationMode = CartMovementMode.values()[te.movementMode.value]);
boolean couplingFound = contraption.connectedCart != null;
if (couplingFound)
if (couplingFound) {
MinecartCouplingHandler.connectCarts(null, world, cart.getEntityId(),
contraption.connectedCart.getEntityId());
ContraptionEntity entity =
ContraptionEntity.createMounted(world, contraption, initialAngle, facing, couplingFound);
Vec3d diff = contraption.connectedCart.getPositionVec()
.subtract(cart.getPositionVec());
initialAngle = Direction.fromAngle(MathHelper.atan2(diff.z, diff.x) * 180 / Math.PI)
.getHorizontalAngle();
}
ContraptionEntity entity = ContraptionEntity.createMounted(world, contraption, initialAngle, facing);
if (couplingFound) {
entity.setCouplingId(cart.getUniqueID());
entity.setCoupledCart(contraption.connectedCart.getUniqueID());
}
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
world.addEntity(entity);
entity.startRiding(cart);

View File

@ -159,8 +159,7 @@ public class MinecartContraptionItem extends Item {
ContraptionEntity contraption;
if (newFacing != null)
contraption =
ContraptionEntity.createMounted(world, mountedContraption, initialAngle, newFacing, false);
contraption = ContraptionEntity.createMounted(world, mountedContraption, initialAngle, newFacing);
else
contraption = ContraptionEntity.createMounted(world, mountedContraption, initialAngle);

View File

@ -123,7 +123,7 @@ public class MountedContraption extends Contraption {
@Override
protected boolean customBlockRemoval(IWorld world, BlockPos pos, BlockState state) {
return pos.equals(anchor);
return AllBlocks.MINECART_ANCHOR.has(state);
}
}

View File

@ -12,9 +12,11 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.train.MinecartCouplingSerializer.CouplingData;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.WorldAttached;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -217,13 +219,13 @@ public class MinecartCouplingHandler {
@OnlyIn(Dist.CLIENT)
public static void render(MatrixStack ms, IRenderTypeBuffer buffer) {
ClientWorld world = Minecraft.getInstance().world;
if (world == null)
if (world == null)
return;
loadedCouplings.get(world)
.values()
.forEach(c -> MinecartCouplingRenderer.renderCoupling(ms, buffer, c));
}
public static void tick(World world) {
initQueuedCarts(world);
removeUnloadedCouplings(world);
@ -367,7 +369,7 @@ public class MinecartCouplingHandler {
train.flip(world);
map.put(train.getId(), train);
}
public static MinecartCoupling getCoupling(World world, UUID id) {
Map<UUID, MinecartCoupling> map = loadedCouplings.get(world);
return map.get(id);
@ -376,6 +378,25 @@ public class MinecartCouplingHandler {
public static void flipCoupling(World world, MinecartCoupling coupling) {
Map<UUID, MinecartCoupling> map = loadedCouplings.get(world);
map.remove(coupling.getId());
if (coupling.areBothEndsPresent()) {
Couple<AbstractMinecartEntity> carts = coupling.asCouple();
Couple<UUID> ids = carts.map(Entity::getUniqueID);
carts.map(c -> c.isBeingRidden() ? c.getPassengers()
.get(0) : null)
.map(c -> c instanceof ContraptionEntity ? (ContraptionEntity) c : null)
.forEachWithContext((contraption, current) -> {
if (contraption == null || contraption.getCouplingId() == null)
return;
boolean switchTo = contraption.getCouplingId()
.equals(ids.get(current)) ? !current : current;
if (!carts.get(switchTo).getUniqueID().equals(contraption.getCoupledCart()))
return;
contraption.setCouplingId(ids.get(switchTo));
contraption.setCoupledCart(ids.get(!switchTo));
});
}
coupling.flip();
map.put(coupling.getId(), coupling);
}

View File

@ -13,9 +13,7 @@ import net.minecraft.block.AbstractRailBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.entity.item.minecart.ContainerMinecartEntity;
import net.minecraft.entity.item.minecart.FurnaceMinecartEntity;
import net.minecraft.inventory.container.Container;
import net.minecraft.state.properties.RailShape;
import net.minecraft.util.Direction;
import net.minecraft.util.Util;
@ -49,24 +47,24 @@ public class MinecartSim2020 {
});
public static Vec3d predictMotionOf(AbstractMinecartEntity cart) {
if (cart instanceof FurnaceMinecartEntity) {
return cart.getPositionVec()
.subtract(cart.lastTickPosX, cart.lastTickPosY, cart.lastTickPosZ);
}
if (cart instanceof ContainerMinecartEntity) {
ContainerMinecartEntity containerCart = (ContainerMinecartEntity) cart;
float f = 0.98F;
if (containerCart.isEmpty())
return cart.getMotion()
.mul(f, 0.0D, f);
int i = 15 - Container.calcRedstoneFromInventory(containerCart);
f += (float) i * 0.001F;
return cart.getMotion()
.mul(f, 0.0D, f);
}
return cart.getMotion()
.scale(cart.isBeingRidden() ? 0.997D : 0.96D);
return cart.getMotion().scale(1.03f);
// if (cart instanceof ContainerMinecartEntity) {
// ContainerMinecartEntity containerCart = (ContainerMinecartEntity) cart;
// float f = 0.98F;
// if (containerCart.isEmpty())
// return cart.getMotion()
// .mul(f, 0.0D, f);
// int i = 15 - Container.calcRedstoneFromInventory(containerCart);
// f += (float) i * 0.001F;
// return cart.getMotion()
// .mul(f, 0.0D, f);
// }
// return cart.getMotion()
// .scale(cart.isBeingRidden() ? 0.997D : 0.96D);
}
public static boolean canAddMotion(AbstractMinecartEntity c) {