mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-19 14:59:25 +00:00
209 lines
11 KiB
Diff
209 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: SoSeDiK <mrsosedik@gmail.com>
|
|
Date: Fri, 2 Dec 2022 21:44:23 +0200
|
|
Subject: [PATCH] Dynamic minecart speed
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
|
|
index 9a80cf593bbdd7681bc9395daf4545a98e07636f..012d4ad1651d7a9118b24e0589d8bdf28ed0b708 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
|
|
@@ -573,7 +573,108 @@ public abstract class AbstractMinecart extends Entity {
|
|
d5 = -d5;
|
|
}
|
|
|
|
- double d8 = Math.min(2.0D, vec3d1.horizontalDistance());
|
|
+ // Kiterino start - dynamic minecart speed
|
|
+ double vanillaMaxHorizontalMovementPerTick = 0.4D;
|
|
+ double horizontalMomentumPerTick = vec3d1.horizontalDistance();
|
|
+
|
|
+ java.util.function.DoubleSupplier calculateMaxHorizontalMovementPerTick = () -> {
|
|
+ final double fallbackSpeedFactor = 1.15D;
|
|
+ double fallback = this.getMaxSpeed();
|
|
+
|
|
+ if (this.getPassengers().isEmpty())
|
|
+ return fallback;
|
|
+
|
|
+ if (horizontalMomentumPerTick < vanillaMaxHorizontalMovementPerTick)
|
|
+ return fallback;
|
|
+
|
|
+ fallback *= fallbackSpeedFactor;
|
|
+
|
|
+ boolean hasEligibleShape = blockpropertytrackposition == RailShape.NORTH_SOUTH || blockpropertytrackposition == RailShape.EAST_WEST;
|
|
+ if (!hasEligibleShape)
|
|
+ return fallback;
|
|
+
|
|
+ boolean hasEligibleType = state.is(Blocks.RAIL) || (state.is(Blocks.POWERED_RAIL) && state.getValue(PoweredRailBlock.POWERED));
|
|
+ if (!hasEligibleType)
|
|
+ return fallback;
|
|
+
|
|
+ var eligibleNeighbors = new java.util.concurrent.atomic.AtomicInteger();
|
|
+
|
|
+ java.util.HashSet<BlockPos> checkedPositions = new java.util.HashSet<>();
|
|
+ checkedPositions.add(pos);
|
|
+
|
|
+ java.util.function.BiFunction<BlockPos, RailShape, java.util.ArrayList<Pair<BlockPos, RailShape>>> checkNeighbors = (cPos, cRailShape) -> {
|
|
+ Pair<Vec3i, Vec3i> cAdjPosDiff = AbstractMinecart.exits(cRailShape);
|
|
+ java.util.ArrayList<Pair<BlockPos, RailShape>> newNeighbors = new java.util.ArrayList<>();
|
|
+
|
|
+ BlockPos n1Pos = cPos.offset(cAdjPosDiff.getFirst());
|
|
+
|
|
+ if (!checkedPositions.contains(n1Pos)) {
|
|
+ BlockState n1State = this.level.getBlockState(n1Pos);
|
|
+ boolean n1HasEligibleType = n1State.is(Blocks.RAIL) || (n1State.is(Blocks.POWERED_RAIL) && n1State.getValue(PoweredRailBlock.POWERED));
|
|
+ if (!n1HasEligibleType)
|
|
+ return new java.util.ArrayList<>();
|
|
+
|
|
+ RailShape n1RailShape = n1State.getValue(((BaseRailBlock) n1State.getBlock()).getShapeProperty());
|
|
+ if (n1RailShape != blockpropertytrackposition)
|
|
+ return new java.util.ArrayList<>();
|
|
+
|
|
+ checkedPositions.add(n1Pos);
|
|
+ eligibleNeighbors.incrementAndGet();
|
|
+ newNeighbors.add(Pair.of(n1Pos, n1RailShape));
|
|
+ }
|
|
+
|
|
+ BlockPos n2Pos = cPos.offset(cAdjPosDiff.getSecond());
|
|
+ if (!checkedPositions.contains(n2Pos)) {
|
|
+ BlockState n2State = this.level.getBlockState(n2Pos);
|
|
+ boolean n2HasEligibleType = n2State.is(Blocks.RAIL) || (n2State.is(Blocks.POWERED_RAIL) && n2State.getValue(PoweredRailBlock.POWERED));
|
|
+ if (!n2HasEligibleType)
|
|
+ return new java.util.ArrayList<>();
|
|
+
|
|
+ RailShape n2RailShape = n2State.getValue(((BaseRailBlock) n2State.getBlock()).getShapeProperty());
|
|
+
|
|
+ if (n2RailShape != blockpropertytrackposition)
|
|
+ return new java.util.ArrayList<>();
|
|
+
|
|
+ checkedPositions.add(n2Pos);
|
|
+ eligibleNeighbors.incrementAndGet();
|
|
+ newNeighbors.add(Pair.of(n2Pos, n2RailShape));
|
|
+ }
|
|
+
|
|
+ return newNeighbors;
|
|
+ };
|
|
+
|
|
+
|
|
+ java.util.ArrayList<Pair<BlockPos, RailShape>> newNeighbors = checkNeighbors.apply(pos, blockpropertytrackposition);
|
|
+
|
|
+ while (!newNeighbors.isEmpty() && eligibleNeighbors.get() < 16) {
|
|
+ java.util.ArrayList<Pair<BlockPos, RailShape>> tempNewNeighbors = new java.util.ArrayList<>(newNeighbors);
|
|
+ newNeighbors.clear();
|
|
+
|
|
+ for (Pair<BlockPos, RailShape> newNeighbor : tempNewNeighbors) {
|
|
+ java.util.ArrayList<Pair<BlockPos, RailShape>> result = checkNeighbors.apply(newNeighbor.getFirst(), newNeighbor.getSecond());
|
|
+
|
|
+ if (result.isEmpty()) {
|
|
+ newNeighbors.clear();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ newNeighbors.addAll(result);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ int eligibleForwardRailTrackCount = eligibleNeighbors.get() / 2;
|
|
+
|
|
+ if (eligibleForwardRailTrackCount <= 1)
|
|
+ return fallback;
|
|
+
|
|
+ return (2.01D + eligibleForwardRailTrackCount * 4D) / 20D;
|
|
+ };
|
|
+
|
|
+ double maxHorizontalMovementPerTick = calculateMaxHorizontalMovementPerTick.getAsDouble();
|
|
+ double maxHorizontalMomentumPerTick = Math.max(maxHorizontalMovementPerTick * 5D, 4.2D);
|
|
+ // Kiterino end
|
|
+
|
|
+ double d8 = Math.min(maxHorizontalMomentumPerTick, vec3d1.horizontalDistance()); // Kiterino - dynamic minecart speed, unhardcode 2.0D
|
|
|
|
vec3d1 = new Vec3(d8 * d4 / d6, vec3d1.y, d8 * d5 / d6);
|
|
this.setDeltaMovement(vec3d1);
|
|
@@ -596,8 +697,15 @@ public abstract class AbstractMinecart extends Entity {
|
|
d11 = this.getDeltaMovement().horizontalDistance();
|
|
if (d11 < 0.03D) {
|
|
this.setDeltaMovement(Vec3.ZERO);
|
|
- } else {
|
|
- this.setDeltaMovement(this.getDeltaMovement().multiply(0.5D, 0.0D, 0.5D));
|
|
+ }
|
|
+ else {
|
|
+ // Kiterino start - dynamic minecart speed
|
|
+ double brakeFactor = 0.5D;
|
|
+ if (horizontalMomentumPerTick > 4D * vanillaMaxHorizontalMovementPerTick) {
|
|
+ brakeFactor = Math.pow(brakeFactor, 1D + ((horizontalMomentumPerTick - 3.99D * vanillaMaxHorizontalMovementPerTick) / 1.2D));
|
|
+ }
|
|
+ // Kiterino end
|
|
+ this.setDeltaMovement(this.getDeltaMovement().multiply(brakeFactor, 0.0D, brakeFactor)); // Kiterino - dynamic minecart speed, unhardcode 0.5D
|
|
}
|
|
}
|
|
|
|
@@ -626,9 +734,10 @@ public abstract class AbstractMinecart extends Entity {
|
|
d2 = d12 + d5 * d15;
|
|
this.setPos(d0, d1, d2);
|
|
d16 = this.isVehicle() ? 0.75D : 1.0D;
|
|
- d17 = this.getMaxSpeed();
|
|
+ d17 = maxHorizontalMomentumPerTick;
|
|
vec3d1 = this.getDeltaMovement();
|
|
- this.move(MoverType.SELF, new Vec3(Mth.clamp(d16 * vec3d1.x, -d17, d17), 0.0D, Mth.clamp(d16 * vec3d1.z, -d17, d17)));
|
|
+ var movement = new Vec3(Mth.clamp(d16 * vec3d1.x, -d17, d17), 0D, Mth.clamp(d16 * vec3d1.z, -d17, d17));
|
|
+ this.move(MoverType.SELF, movement); // Kiterino - dynamic minecart speed, expose into the variable
|
|
if (baseblockposition.getY() != 0 && Mth.floor(this.getX()) - pos.getX() == baseblockposition.getX() && Mth.floor(this.getZ()) - pos.getZ() == baseblockposition.getZ()) {
|
|
this.setPos(this.getX(), this.getY() + (double) baseblockposition.getY(), this.getZ());
|
|
} else if (baseblockposition1.getY() != 0 && Mth.floor(this.getX()) - pos.getX() == baseblockposition1.getX() && Mth.floor(this.getZ()) - pos.getZ() == baseblockposition1.getZ()) {
|
|
@@ -658,26 +767,52 @@ public abstract class AbstractMinecart extends Entity {
|
|
if (i != pos.getX() || j != pos.getZ()) {
|
|
vec3d4 = this.getDeltaMovement();
|
|
d18 = vec3d4.horizontalDistance();
|
|
- this.setDeltaMovement(d18 * (double) (i - pos.getX()), vec3d4.y, d18 * (double) (j - pos.getZ()));
|
|
+ this.setDeltaMovement(d18 * Mth.clamp((double) i - pos.getX(), -1D, 1D), vec3d4.y, d18 * Mth.clamp((double) j - pos.getZ(), -1D, 1D)); // Kiterino - dynamic minecart speed, clamp values
|
|
}
|
|
|
|
if (flag) {
|
|
vec3d4 = this.getDeltaMovement();
|
|
d18 = vec3d4.horizontalDistance();
|
|
+ final double basisAccelerationPerTick = 0.021D; // Kiterino - dynamic minecart speed
|
|
if (d18 > 0.01D) {
|
|
+ // Kiterino start - dynamic minecart speed
|
|
+ if (!getPassengers().isEmpty()) {
|
|
+ // Based on 10 ticks per second basis spent per powered block we calculate a fair acceleration per tick
|
|
+ // due to spending less ticks per powered block on higher speeds (and even skipping blocks)
|
|
+ final double basisTicksPerSecond = 10D;
|
|
+ // Tps = Ticks per second
|
|
+ final double tickMovementForBasisTps = 1D / basisTicksPerSecond;
|
|
+ final double maxSkippedBlocksToConsider = 3D;
|
|
+
|
|
+ double acceleration = basisAccelerationPerTick;
|
|
+ final double distanceMovedHorizontally = movement.horizontalDistance();
|
|
+
|
|
+ if (distanceMovedHorizontally > tickMovementForBasisTps) {
|
|
+ acceleration *= Math.min((1D + maxSkippedBlocksToConsider) * basisTicksPerSecond, distanceMovedHorizontally / tickMovementForBasisTps);
|
|
+
|
|
+ // Add progressively slower (or faster) acceleration for higher speeds;
|
|
+ double highspeedFactor = 1D + Mth.clamp(-0.45D * (distanceMovedHorizontally / tickMovementForBasisTps / basisTicksPerSecond), -0.7D, 2D);
|
|
+ acceleration *= highspeedFactor;
|
|
+ }
|
|
+ this.setDeltaMovement(vec3d4.add(acceleration * (vec3d4.x / d18), 0D, acceleration * (vec3d4.z / d18)));
|
|
+ } else {
|
|
+ this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0D, vec3d4.z / d18 * 0.06D));
|
|
+ }
|
|
+ // Kiterino end
|
|
double d20 = 0.06D;
|
|
|
|
- this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0.0D, vec3d4.z / d18 * 0.06D));
|
|
+ // this.setDeltaMovement(vec3d4.add(vec3d4.x / d18 * 0.06D, 0.0D, vec3d4.z / d18 * 0.06D)); // Kiterino - dynamic minecart speed
|
|
} else {
|
|
Vec3 vec3d5 = this.getDeltaMovement();
|
|
double d21 = vec3d5.x;
|
|
double d22 = vec3d5.z;
|
|
+ final double railStopperAcceleration = basisAccelerationPerTick * 16D; // Kiterino
|
|
|
|
if (blockpropertytrackposition == RailShape.EAST_WEST) {
|
|
if (this.isRedstoneConductor(pos.west())) {
|
|
- d21 = 0.02D;
|
|
+ d21 = railStopperAcceleration; // Kiterino - dynamic minecart speed, unhardcode 0.02D
|
|
} else if (this.isRedstoneConductor(pos.east())) {
|
|
- d21 = -0.02D;
|
|
+ d21 = -railStopperAcceleration; // Kiterino - dynamic minecart speed, unhardcode -0.02D
|
|
}
|
|
} else {
|
|
if (blockpropertytrackposition != RailShape.NORTH_SOUTH) {
|