419 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			419 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.entity.vehicle;
 | |
| 
 | |
| import com.mojang.datafixers.util.Pair;
 | |
| import java.util.List;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.Direction;
 | |
| import net.minecraft.core.Vec3i;
 | |
| import net.minecraft.server.level.ServerLevel;
 | |
| import net.minecraft.server.level.ServerPlayer;
 | |
| import net.minecraft.tags.BlockTags;
 | |
| import net.minecraft.util.Mth;
 | |
| import net.minecraft.world.entity.Entity;
 | |
| import net.minecraft.world.entity.EntitySelector;
 | |
| import net.minecraft.world.entity.InterpolationHandler;
 | |
| import net.minecraft.world.entity.MoverType;
 | |
| import net.minecraft.world.entity.animal.IronGolem;
 | |
| import net.minecraft.world.entity.player.Player;
 | |
| import net.minecraft.world.level.block.BaseRailBlock;
 | |
| import net.minecraft.world.level.block.Blocks;
 | |
| import net.minecraft.world.level.block.PoweredRailBlock;
 | |
| import net.minecraft.world.level.block.state.BlockState;
 | |
| import net.minecraft.world.level.block.state.properties.RailShape;
 | |
| import net.minecraft.world.phys.AABB;
 | |
| import net.minecraft.world.phys.Vec3;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| public class OldMinecartBehavior extends MinecartBehavior {
 | |
| 	private static final double MINECART_RIDABLE_THRESHOLD = 0.01;
 | |
| 	private static final double MAX_SPEED_IN_WATER = 0.2;
 | |
| 	private static final double MAX_SPEED_ON_LAND = 0.4;
 | |
| 	private static final double ABSOLUTE_MAX_SPEED = 0.4;
 | |
| 	private final InterpolationHandler interpolation;
 | |
| 	private Vec3 targetDeltaMovement = Vec3.ZERO;
 | |
| 
 | |
| 	public OldMinecartBehavior(AbstractMinecart minecart) {
 | |
| 		super(minecart);
 | |
| 		this.interpolation = new InterpolationHandler(minecart, this::onInterpolation);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public InterpolationHandler getInterpolation() {
 | |
| 		return this.interpolation;
 | |
| 	}
 | |
| 
 | |
| 	public void onInterpolation(InterpolationHandler handler) {
 | |
| 		this.setDeltaMovement(this.targetDeltaMovement);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void lerpMotion(double x, double y, double z) {
 | |
| 		this.targetDeltaMovement = new Vec3(x, y, z);
 | |
| 		this.setDeltaMovement(this.targetDeltaMovement);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void tick() {
 | |
| 		if (this.level() instanceof ServerLevel serverLevel) {
 | |
| 			this.minecart.applyGravity();
 | |
| 			BlockPos var11 = this.minecart.getCurrentBlockPosOrRailBelow();
 | |
| 			BlockState blockState = this.level().getBlockState(var11);
 | |
| 			boolean bl = BaseRailBlock.isRail(blockState);
 | |
| 			this.minecart.setOnRails(bl);
 | |
| 			if (bl) {
 | |
| 				this.moveAlongTrack(serverLevel);
 | |
| 				if (blockState.is(Blocks.ACTIVATOR_RAIL)) {
 | |
| 					this.minecart.activateMinecart(var11.getX(), var11.getY(), var11.getZ(), (Boolean)blockState.getValue(PoweredRailBlock.POWERED));
 | |
| 				}
 | |
| 			} else {
 | |
| 				this.minecart.comeOffTrack(serverLevel);
 | |
| 			}
 | |
| 
 | |
| 			this.minecart.applyEffectsFromBlocks();
 | |
| 			this.setXRot(0.0F);
 | |
| 			double d = this.minecart.xo - this.getX();
 | |
| 			double e = this.minecart.zo - this.getZ();
 | |
| 			if (d * d + e * e > 0.001) {
 | |
| 				this.setYRot((float)(Mth.atan2(e, d) * 180.0 / Math.PI));
 | |
| 				if (this.minecart.isFlipped()) {
 | |
| 					this.setYRot(this.getYRot() + 180.0F);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			double f = Mth.wrapDegrees(this.getYRot() - this.minecart.yRotO);
 | |
| 			if (f < -170.0 || f >= 170.0) {
 | |
| 				this.setYRot(this.getYRot() + 180.0F);
 | |
| 				this.minecart.setFlipped(!this.minecart.isFlipped());
 | |
| 			}
 | |
| 
 | |
| 			this.setXRot(this.getXRot() % 360.0F);
 | |
| 			this.setYRot(this.getYRot() % 360.0F);
 | |
| 			this.pushAndPickupEntities();
 | |
| 		} else {
 | |
| 			if (this.interpolation.hasActiveInterpolation()) {
 | |
| 				this.interpolation.interpolate();
 | |
| 			} else {
 | |
| 				this.minecart.reapplyPosition();
 | |
| 				this.setXRot(this.getXRot() % 360.0F);
 | |
| 				this.setYRot(this.getYRot() % 360.0F);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void moveAlongTrack(ServerLevel level) {
 | |
| 		BlockPos blockPos = this.minecart.getCurrentBlockPosOrRailBelow();
 | |
| 		BlockState blockState = this.level().getBlockState(blockPos);
 | |
| 		this.minecart.resetFallDistance();
 | |
| 		double d = this.minecart.getX();
 | |
| 		double e = this.minecart.getY();
 | |
| 		double f = this.minecart.getZ();
 | |
| 		Vec3 vec3 = this.getPos(d, e, f);
 | |
| 		e = blockPos.getY();
 | |
| 		boolean bl = false;
 | |
| 		boolean bl2 = false;
 | |
| 		if (blockState.is(Blocks.POWERED_RAIL)) {
 | |
| 			bl = (Boolean)blockState.getValue(PoweredRailBlock.POWERED);
 | |
| 			bl2 = !bl;
 | |
| 		}
 | |
| 
 | |
| 		double g = 0.0078125;
 | |
| 		if (this.minecart.isInWater()) {
 | |
| 			g *= 0.2;
 | |
| 		}
 | |
| 
 | |
| 		Vec3 vec32 = this.getDeltaMovement();
 | |
| 		RailShape railShape = blockState.getValue(((BaseRailBlock)blockState.getBlock()).getShapeProperty());
 | |
| 		switch (railShape) {
 | |
| 			case ASCENDING_EAST:
 | |
| 				this.setDeltaMovement(vec32.add(-g, 0.0, 0.0));
 | |
| 				e++;
 | |
| 				break;
 | |
| 			case ASCENDING_WEST:
 | |
| 				this.setDeltaMovement(vec32.add(g, 0.0, 0.0));
 | |
| 				e++;
 | |
| 				break;
 | |
| 			case ASCENDING_NORTH:
 | |
| 				this.setDeltaMovement(vec32.add(0.0, 0.0, g));
 | |
| 				e++;
 | |
| 				break;
 | |
| 			case ASCENDING_SOUTH:
 | |
| 				this.setDeltaMovement(vec32.add(0.0, 0.0, -g));
 | |
| 				e++;
 | |
| 		}
 | |
| 
 | |
| 		vec32 = this.getDeltaMovement();
 | |
| 		Pair<Vec3i, Vec3i> pair = AbstractMinecart.exits(railShape);
 | |
| 		Vec3i vec3i = pair.getFirst();
 | |
| 		Vec3i vec3i2 = pair.getSecond();
 | |
| 		double h = vec3i2.getX() - vec3i.getX();
 | |
| 		double i = vec3i2.getZ() - vec3i.getZ();
 | |
| 		double j = Math.sqrt(h * h + i * i);
 | |
| 		double k = vec32.x * h + vec32.z * i;
 | |
| 		if (k < 0.0) {
 | |
| 			h = -h;
 | |
| 			i = -i;
 | |
| 		}
 | |
| 
 | |
| 		double l = Math.min(2.0, vec32.horizontalDistance());
 | |
| 		vec32 = new Vec3(l * h / j, vec32.y, l * i / j);
 | |
| 		this.setDeltaMovement(vec32);
 | |
| 		Entity entity = this.minecart.getFirstPassenger();
 | |
| 		Vec3 vec33;
 | |
| 		if (this.minecart.getFirstPassenger() instanceof ServerPlayer serverPlayer) {
 | |
| 			vec33 = serverPlayer.getLastClientMoveIntent();
 | |
| 		} else {
 | |
| 			vec33 = Vec3.ZERO;
 | |
| 		}
 | |
| 
 | |
| 		if (entity instanceof Player && vec33.lengthSqr() > 0.0) {
 | |
| 			Vec3 vec34 = vec33.normalize();
 | |
| 			double m = this.getDeltaMovement().horizontalDistanceSqr();
 | |
| 			if (vec34.lengthSqr() > 0.0 && m < 0.01) {
 | |
| 				this.setDeltaMovement(this.getDeltaMovement().add(vec33.x * 0.001, 0.0, vec33.z * 0.001));
 | |
| 				bl2 = false;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if (bl2) {
 | |
| 			double n = this.getDeltaMovement().horizontalDistance();
 | |
| 			if (n < 0.03) {
 | |
| 				this.setDeltaMovement(Vec3.ZERO);
 | |
| 			} else {
 | |
| 				this.setDeltaMovement(this.getDeltaMovement().multiply(0.5, 0.0, 0.5));
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		double n = blockPos.getX() + 0.5 + vec3i.getX() * 0.5;
 | |
| 		double o = blockPos.getZ() + 0.5 + vec3i.getZ() * 0.5;
 | |
| 		double p = blockPos.getX() + 0.5 + vec3i2.getX() * 0.5;
 | |
| 		double q = blockPos.getZ() + 0.5 + vec3i2.getZ() * 0.5;
 | |
| 		h = p - n;
 | |
| 		i = q - o;
 | |
| 		double r;
 | |
| 		if (h == 0.0) {
 | |
| 			r = f - blockPos.getZ();
 | |
| 		} else if (i == 0.0) {
 | |
| 			r = d - blockPos.getX();
 | |
| 		} else {
 | |
| 			double s = d - n;
 | |
| 			double t = f - o;
 | |
| 			r = (s * h + t * i) * 2.0;
 | |
| 		}
 | |
| 
 | |
| 		d = n + h * r;
 | |
| 		f = o + i * r;
 | |
| 		this.setPos(d, e, f);
 | |
| 		double s = this.minecart.isVehicle() ? 0.75 : 1.0;
 | |
| 		double t = this.minecart.getMaxSpeed(level);
 | |
| 		vec32 = this.getDeltaMovement();
 | |
| 		this.minecart.move(MoverType.SELF, new Vec3(Mth.clamp(s * vec32.x, -t, t), 0.0, Mth.clamp(s * vec32.z, -t, t)));
 | |
| 		if (vec3i.getY() != 0
 | |
| 			&& Mth.floor(this.minecart.getX()) - blockPos.getX() == vec3i.getX()
 | |
| 			&& Mth.floor(this.minecart.getZ()) - blockPos.getZ() == vec3i.getZ()) {
 | |
| 			this.setPos(this.minecart.getX(), this.minecart.getY() + vec3i.getY(), this.minecart.getZ());
 | |
| 		} else if (vec3i2.getY() != 0
 | |
| 			&& Mth.floor(this.minecart.getX()) - blockPos.getX() == vec3i2.getX()
 | |
| 			&& Mth.floor(this.minecart.getZ()) - blockPos.getZ() == vec3i2.getZ()) {
 | |
| 			this.setPos(this.minecart.getX(), this.minecart.getY() + vec3i2.getY(), this.minecart.getZ());
 | |
| 		}
 | |
| 
 | |
| 		this.setDeltaMovement(this.minecart.applyNaturalSlowdown(this.getDeltaMovement()));
 | |
| 		Vec3 vec35 = this.getPos(this.minecart.getX(), this.minecart.getY(), this.minecart.getZ());
 | |
| 		if (vec35 != null && vec3 != null) {
 | |
| 			double u = (vec3.y - vec35.y) * 0.05;
 | |
| 			Vec3 vec36 = this.getDeltaMovement();
 | |
| 			double v = vec36.horizontalDistance();
 | |
| 			if (v > 0.0) {
 | |
| 				this.setDeltaMovement(vec36.multiply((v + u) / v, 1.0, (v + u) / v));
 | |
| 			}
 | |
| 
 | |
| 			this.setPos(this.minecart.getX(), vec35.y, this.minecart.getZ());
 | |
| 		}
 | |
| 
 | |
| 		int w = Mth.floor(this.minecart.getX());
 | |
| 		int x = Mth.floor(this.minecart.getZ());
 | |
| 		if (w != blockPos.getX() || x != blockPos.getZ()) {
 | |
| 			Vec3 vec36 = this.getDeltaMovement();
 | |
| 			double v = vec36.horizontalDistance();
 | |
| 			this.setDeltaMovement(v * (w - blockPos.getX()), vec36.y, v * (x - blockPos.getZ()));
 | |
| 		}
 | |
| 
 | |
| 		if (bl) {
 | |
| 			Vec3 vec36 = this.getDeltaMovement();
 | |
| 			double v = vec36.horizontalDistance();
 | |
| 			if (v > 0.01) {
 | |
| 				double y = 0.06;
 | |
| 				this.setDeltaMovement(vec36.add(vec36.x / v * 0.06, 0.0, vec36.z / v * 0.06));
 | |
| 			} else {
 | |
| 				Vec3 vec37 = this.getDeltaMovement();
 | |
| 				double z = vec37.x;
 | |
| 				double aa = vec37.z;
 | |
| 				if (railShape == RailShape.EAST_WEST) {
 | |
| 					if (this.minecart.isRedstoneConductor(blockPos.west())) {
 | |
| 						z = 0.02;
 | |
| 					} else if (this.minecart.isRedstoneConductor(blockPos.east())) {
 | |
| 						z = -0.02;
 | |
| 					}
 | |
| 				} else {
 | |
| 					if (railShape != RailShape.NORTH_SOUTH) {
 | |
| 						return;
 | |
| 					}
 | |
| 
 | |
| 					if (this.minecart.isRedstoneConductor(blockPos.north())) {
 | |
| 						aa = 0.02;
 | |
| 					} else if (this.minecart.isRedstoneConductor(blockPos.south())) {
 | |
| 						aa = -0.02;
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				this.setDeltaMovement(z, vec37.y, aa);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	public Vec3 getPosOffs(double x, double y, double z, double scale) {
 | |
| 		int i = Mth.floor(x);
 | |
| 		int j = Mth.floor(y);
 | |
| 		int k = Mth.floor(z);
 | |
| 		if (this.level().getBlockState(new BlockPos(i, j - 1, k)).is(BlockTags.RAILS)) {
 | |
| 			j--;
 | |
| 		}
 | |
| 
 | |
| 		BlockState blockState = this.level().getBlockState(new BlockPos(i, j, k));
 | |
| 		if (BaseRailBlock.isRail(blockState)) {
 | |
| 			RailShape railShape = blockState.getValue(((BaseRailBlock)blockState.getBlock()).getShapeProperty());
 | |
| 			y = j;
 | |
| 			if (railShape.isSlope()) {
 | |
| 				y = j + 1;
 | |
| 			}
 | |
| 
 | |
| 			Pair<Vec3i, Vec3i> pair = AbstractMinecart.exits(railShape);
 | |
| 			Vec3i vec3i = pair.getFirst();
 | |
| 			Vec3i vec3i2 = pair.getSecond();
 | |
| 			double d = vec3i2.getX() - vec3i.getX();
 | |
| 			double e = vec3i2.getZ() - vec3i.getZ();
 | |
| 			double f = Math.sqrt(d * d + e * e);
 | |
| 			d /= f;
 | |
| 			e /= f;
 | |
| 			x += d * scale;
 | |
| 			z += e * scale;
 | |
| 			if (vec3i.getY() != 0 && Mth.floor(x) - i == vec3i.getX() && Mth.floor(z) - k == vec3i.getZ()) {
 | |
| 				y += vec3i.getY();
 | |
| 			} else if (vec3i2.getY() != 0 && Mth.floor(x) - i == vec3i2.getX() && Mth.floor(z) - k == vec3i2.getZ()) {
 | |
| 				y += vec3i2.getY();
 | |
| 			}
 | |
| 
 | |
| 			return this.getPos(x, y, z);
 | |
| 		} else {
 | |
| 			return null;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	public Vec3 getPos(double x, double y, double z) {
 | |
| 		int i = Mth.floor(x);
 | |
| 		int j = Mth.floor(y);
 | |
| 		int k = Mth.floor(z);
 | |
| 		if (this.level().getBlockState(new BlockPos(i, j - 1, k)).is(BlockTags.RAILS)) {
 | |
| 			j--;
 | |
| 		}
 | |
| 
 | |
| 		BlockState blockState = this.level().getBlockState(new BlockPos(i, j, k));
 | |
| 		if (BaseRailBlock.isRail(blockState)) {
 | |
| 			RailShape railShape = blockState.getValue(((BaseRailBlock)blockState.getBlock()).getShapeProperty());
 | |
| 			Pair<Vec3i, Vec3i> pair = AbstractMinecart.exits(railShape);
 | |
| 			Vec3i vec3i = pair.getFirst();
 | |
| 			Vec3i vec3i2 = pair.getSecond();
 | |
| 			double d = i + 0.5 + vec3i.getX() * 0.5;
 | |
| 			double e = j + 0.0625 + vec3i.getY() * 0.5;
 | |
| 			double f = k + 0.5 + vec3i.getZ() * 0.5;
 | |
| 			double g = i + 0.5 + vec3i2.getX() * 0.5;
 | |
| 			double h = j + 0.0625 + vec3i2.getY() * 0.5;
 | |
| 			double l = k + 0.5 + vec3i2.getZ() * 0.5;
 | |
| 			double m = g - d;
 | |
| 			double n = (h - e) * 2.0;
 | |
| 			double o = l - f;
 | |
| 			double p;
 | |
| 			if (m == 0.0) {
 | |
| 				p = z - k;
 | |
| 			} else if (o == 0.0) {
 | |
| 				p = x - i;
 | |
| 			} else {
 | |
| 				double q = x - d;
 | |
| 				double r = z - f;
 | |
| 				p = (q * m + r * o) * 2.0;
 | |
| 			}
 | |
| 
 | |
| 			x = d + m * p;
 | |
| 			y = e + n * p;
 | |
| 			z = f + o * p;
 | |
| 			if (n < 0.0) {
 | |
| 				y++;
 | |
| 			} else if (n > 0.0) {
 | |
| 				y += 0.5;
 | |
| 			}
 | |
| 
 | |
| 			return new Vec3(x, y, z);
 | |
| 		} else {
 | |
| 			return null;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public double stepAlongTrack(BlockPos pos, RailShape railShape, double speed) {
 | |
| 		return 0.0;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean pushAndPickupEntities() {
 | |
| 		AABB aABB = this.minecart.getBoundingBox().inflate(0.2F, 0.0, 0.2F);
 | |
| 		if (this.minecart.isRideable() && this.getDeltaMovement().horizontalDistanceSqr() >= 0.01) {
 | |
| 			List<Entity> list = this.level().getEntities(this.minecart, aABB, EntitySelector.pushableBy(this.minecart));
 | |
| 			if (!list.isEmpty()) {
 | |
| 				for (Entity entity : list) {
 | |
| 					if (!(entity instanceof Player)
 | |
| 						&& !(entity instanceof IronGolem)
 | |
| 						&& !(entity instanceof AbstractMinecart)
 | |
| 						&& !this.minecart.isVehicle()
 | |
| 						&& !entity.isPassenger()) {
 | |
| 						entity.startRiding(this.minecart);
 | |
| 					} else {
 | |
| 						entity.push(this.minecart);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			for (Entity entity2 : this.level().getEntities(this.minecart, aABB)) {
 | |
| 				if (!this.minecart.hasPassenger(entity2) && entity2.isPushable() && entity2 instanceof AbstractMinecart) {
 | |
| 					entity2.push(this.minecart);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public Direction getMotionDirection() {
 | |
| 		return this.minecart.isFlipped() ? this.minecart.getDirection().getOpposite().getClockWise() : this.minecart.getDirection().getClockWise();
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public Vec3 getKnownMovement(Vec3 movement) {
 | |
| 		return !Double.isNaN(movement.x) && !Double.isNaN(movement.y) && !Double.isNaN(movement.z)
 | |
| 			? new Vec3(Mth.clamp(movement.x, -0.4, 0.4), movement.y, Mth.clamp(movement.z, -0.4, 0.4))
 | |
| 			: Vec3.ZERO;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public double getMaxSpeed(ServerLevel level) {
 | |
| 		return this.minecart.isInWater() ? 0.2 : 0.4;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public double getSlowdownFactor() {
 | |
| 		return this.minecart.isVehicle() ? 0.997 : 0.96;
 | |
| 	}
 | |
| }
 |