Search in sources :

Example 1 with VecHelper

use of com.simibubi.create.foundation.utility.VecHelper in project Create by Creators-of-Create.

the class CouplingPhysics method softCollisionStep.

public static void softCollisionStep(Level world, Couple<AbstractMinecart> carts, double couplingLength) {
    Couple<Float> maxSpeed = carts.map(AbstractMinecart::getMaxCartSpeedOnRail);
    Couple<Boolean> canAddmotion = carts.map(MinecartSim2020::canAddMotion);
    // Assuming Minecarts will never move faster than 1 block/tick
    Couple<Vec3> motions = carts.map(Entity::getDeltaMovement);
    motions.replaceWithParams(VecHelper::clamp, Couple.create(1f, 1f));
    Couple<Vec3> nextPositions = carts.map(MinecartSim2020::predictNextPositionOf);
    Couple<RailShape> shapes = carts.mapWithContext((minecart, current) -> {
        Vec3 vec = nextPositions.get(current);
        int x = Mth.floor(vec.x());
        int y = Mth.floor(vec.y());
        int z = Mth.floor(vec.z());
        BlockPos pos = new BlockPos(x, y - 1, z);
        if (minecart.level.getBlockState(pos).is(BlockTags.RAILS))
            pos = pos.below();
        BlockPos railPosition = pos;
        BlockState railState = world.getBlockState(railPosition.above());
        if (!(railState.getBlock() instanceof BaseRailBlock))
            return null;
        BaseRailBlock block = (BaseRailBlock) railState.getBlock();
        return block.getRailDirection(railState, world, railPosition, minecart);
    });
    float futureStress = (float) (couplingLength - nextPositions.getFirst().distanceTo(nextPositions.getSecond()));
    if (Mth.equal(futureStress, 0D))
        return;
    for (boolean current : Iterate.trueAndFalse) {
        Vec3 correction = Vec3.ZERO;
        Vec3 pos = nextPositions.get(current);
        Vec3 link = nextPositions.get(!current).subtract(pos);
        float correctionMagnitude = -futureStress / 2f;
        if (canAddmotion.get(current) != canAddmotion.get(!current))
            correctionMagnitude = !canAddmotion.get(current) ? 0 : correctionMagnitude * 2;
        if (!canAddmotion.get(current))
            continue;
        RailShape shape = shapes.get(current);
        if (shape != null) {
            Vec3 railVec = MinecartSim2020.getRailVec(shape);
            correction = followLinkOnRail(link, pos, correctionMagnitude, railVec).subtract(pos);
        } else
            correction = link.normalize().scale(correctionMagnitude);
        correction = VecHelper.clamp(correction, maxSpeed.get(current));
        motions.set(current, motions.get(current).add(correction));
    }
    motions.replaceWithParams(VecHelper::clamp, maxSpeed);
    carts.forEachWithParams(Entity::setDeltaMovement, motions);
}
Also used : Entity(net.minecraft.world.entity.Entity) AbstractMinecart(net.minecraft.world.entity.vehicle.AbstractMinecart) BlockState(net.minecraft.world.level.block.state.BlockState) BaseRailBlock(net.minecraft.world.level.block.BaseRailBlock) RailShape(net.minecraft.world.level.block.state.properties.RailShape) Vec3(net.minecraft.world.phys.Vec3) VecHelper(com.simibubi.create.foundation.utility.VecHelper) BlockPos(net.minecraft.core.BlockPos)

Aggregations

VecHelper (com.simibubi.create.foundation.utility.VecHelper)1 BlockPos (net.minecraft.core.BlockPos)1 Entity (net.minecraft.world.entity.Entity)1 AbstractMinecart (net.minecraft.world.entity.vehicle.AbstractMinecart)1 BaseRailBlock (net.minecraft.world.level.block.BaseRailBlock)1 BlockState (net.minecraft.world.level.block.state.BlockState)1 RailShape (net.minecraft.world.level.block.state.properties.RailShape)1 Vec3 (net.minecraft.world.phys.Vec3)1