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:
parent
7e167f3b29
commit
bb5a6c45f6
7 changed files with 140 additions and 55 deletions
|
@ -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))
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue