mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
Add back Rail Optimization: optimized PoweredRailBlock logic
This commit is contained in:
@@ -14,6 +14,7 @@ public net.minecraft.world.entity.decoration.ArmorStand noTickEquipmentDirty
|
|||||||
public net.minecraft.world.entity.monster.Shulker MAX_SCALE
|
public net.minecraft.world.entity.monster.Shulker MAX_SCALE
|
||||||
public net.minecraft.world.entity.player.Player canGlide()Z
|
public net.minecraft.world.entity.player.Player canGlide()Z
|
||||||
public net.minecraft.world.item.CrossbowItem getShotPitch(Lnet/minecraft/util/RandomSource;I)F
|
public net.minecraft.world.item.CrossbowItem getShotPitch(Lnet/minecraft/util/RandomSource;I)F
|
||||||
|
public net.minecraft.world.level.block.PoweredRailBlock findPoweredRailSignal(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;ZI)Z
|
||||||
public net.minecraft.world.level.block.entity.FuelValues values
|
public net.minecraft.world.level.block.entity.FuelValues values
|
||||||
public net.minecraft.world.level.chunk.storage.RegionFile getOversizedData(II)Lnet/minecraft/nbt/CompoundTag;
|
public net.minecraft.world.level.chunk.storage.RegionFile getOversizedData(II)Lnet/minecraft/nbt/CompoundTag;
|
||||||
public net.minecraft.world.level.chunk.storage.RegionFile isOversized(II)Z
|
public net.minecraft.world.level.chunk.storage.RegionFile isOversized(II)Z
|
||||||
|
|||||||
@@ -1,405 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
|
|
||||||
Date: Sat, 17 Feb 2024 17:57:08 -0500
|
|
||||||
Subject: [PATCH] Rail Optimization: optimized PoweredRailBlock logic
|
|
||||||
|
|
||||||
Original project: https://github.com/FxMorin/RailOptimization
|
|
||||||
|
|
||||||
Full Rewrite of the powered rail iteration logic
|
|
||||||
that makes powered/activator rails turning on/off up to 4x faster.
|
|
||||||
This rewrite brings a massive performance boost while keeping the vanilla order. This is achieved by running all the
|
|
||||||
powered rail logic from a single rail instead of each block iterating separately. Which was not only very
|
|
||||||
expensive but also completely unnecessary and with a lot of massive overhead
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
|
|
||||||
index bd14c08defe8afc5ceca59d16a5b1dbad178f594..b37ab12d4c51aca1576a14147a959188031d0fd7 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
|
|
||||||
@@ -29,7 +29,7 @@ public class PoweredRailBlock extends BaseRailBlock {
|
|
||||||
this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(PoweredRailBlock.SHAPE, RailShape.NORTH_SOUTH)).setValue(PoweredRailBlock.POWERED, false)).setValue(PoweredRailBlock.WATERLOGGED, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
- protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) {
|
|
||||||
+ public boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) { // Leaf - Rail Optimization - protected -> public
|
|
||||||
if (distance >= world.purpurConfig.railActivationRange) { // Purpur
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
@@ -117,6 +117,12 @@ public class PoweredRailBlock extends BaseRailBlock {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateState(BlockState state, Level world, BlockPos pos, Block neighbor) {
|
|
||||||
+ // Leaf start - Rail Optimization
|
|
||||||
+ if (org.dreeam.leaf.config.modules.opt.OptimizedPoweredRails.enabled) {
|
|
||||||
+ org.dreeam.leaf.optimize.OptimizedPoweredRails.customUpdateState(this, state, world, pos);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ // Leaf end - Rail Optimization
|
|
||||||
boolean flag = (Boolean) state.getValue(PoweredRailBlock.POWERED);
|
|
||||||
boolean flag1 = world.hasNeighborSignal(pos) || this.findPoweredRailSignal(world, pos, state, true, 0) || this.findPoweredRailSignal(world, pos, state, false, 0);
|
|
||||||
|
|
||||||
diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java b/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..ded3c385fcfc6c35086f76bed1b2223a6a29a43e
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java
|
|
||||||
@@ -0,0 +1,18 @@
|
|
||||||
+package org.dreeam.leaf.config.modules.opt;
|
|
||||||
+
|
|
||||||
+import org.dreeam.leaf.config.ConfigModules;
|
|
||||||
+import org.dreeam.leaf.config.EnumConfigCategory;
|
|
||||||
+
|
|
||||||
+public class OptimizedPoweredRails extends ConfigModules {
|
|
||||||
+
|
|
||||||
+ public String getBasePath() {
|
|
||||||
+ return EnumConfigCategory.PERF.getBaseKeyName() + ".optimized-powered-rails";
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public static boolean enabled = true;
|
|
||||||
+
|
|
||||||
+ @Override
|
|
||||||
+ public void onLoaded() {
|
|
||||||
+ enabled = config().getBoolean(getBasePath(), enabled);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
diff --git a/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java b/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..9e8bc27585e204aa2df77a90418bbe9e00bcd040
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java
|
|
||||||
@@ -0,0 +1,335 @@
|
|
||||||
+package org.dreeam.leaf.optimize;
|
|
||||||
+
|
|
||||||
+import net.minecraft.core.BlockPos;
|
|
||||||
+import net.minecraft.core.Direction;
|
|
||||||
+import net.minecraft.world.level.Level;
|
|
||||||
+import net.minecraft.world.level.block.Block;
|
|
||||||
+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 java.util.HashMap;
|
|
||||||
+
|
|
||||||
+import static net.minecraft.world.level.block.Block.*;
|
|
||||||
+import static net.minecraft.world.level.block.PoweredRailBlock.POWERED;
|
|
||||||
+import static net.minecraft.world.level.block.PoweredRailBlock.SHAPE;
|
|
||||||
+
|
|
||||||
+public class OptimizedPoweredRails {
|
|
||||||
+
|
|
||||||
+ private static final Direction[] EAST_WEST_DIR = new Direction[]{Direction.WEST, Direction.EAST};
|
|
||||||
+ private static final Direction[] NORTH_SOUTH_DIR = new Direction[]{Direction.SOUTH, Direction.NORTH};
|
|
||||||
+
|
|
||||||
+ private static final int UPDATE_FORCE_PLACE = UPDATE_MOVE_BY_PISTON | UPDATE_KNOWN_SHAPE | UPDATE_CLIENTS;
|
|
||||||
+
|
|
||||||
+ public static int RAIL_POWER_LIMIT = 8;
|
|
||||||
+
|
|
||||||
+ public static void giveShapeUpdate(Level level, BlockState state, BlockPos pos, BlockPos fromPos, Direction direction) {
|
|
||||||
+ BlockState oldState = level.getBlockState(pos);
|
|
||||||
+ Block.updateOrDestroy(
|
|
||||||
+ oldState,
|
|
||||||
+ oldState.updateShape(direction.getOpposite(), state, level, pos, fromPos),
|
|
||||||
+ level,
|
|
||||||
+ pos,
|
|
||||||
+ UPDATE_CLIENTS & -34,
|
|
||||||
+ 0
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public static void setRailPowerLimit(int powerLimit) {
|
|
||||||
+ RAIL_POWER_LIMIT = powerLimit;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public static void customUpdateState(PoweredRailBlock self, BlockState state, Level level, BlockPos pos) {
|
|
||||||
+ boolean shouldBePowered = level.hasNeighborSignal(pos) ||
|
|
||||||
+ self.findPoweredRailSignal(level, pos, state, true, 0) ||
|
|
||||||
+ self.findPoweredRailSignal(level, pos, state, false, 0);
|
|
||||||
+ if (shouldBePowered != state.getValue(POWERED)) {
|
|
||||||
+ RailShape railShape = state.getValue(SHAPE);
|
|
||||||
+ if (railShape.isAscending()) {
|
|
||||||
+ level.setBlock(pos, state.setValue(POWERED, shouldBePowered), 3);
|
|
||||||
+ level.updateNeighborsAtExceptFromFacing(pos.below(), self, Direction.UP);
|
|
||||||
+ level.updateNeighborsAtExceptFromFacing(pos.above(), self, Direction.DOWN); //isAscending
|
|
||||||
+ } else if (shouldBePowered) {
|
|
||||||
+ powerLane(self, level, pos, state, railShape);
|
|
||||||
+ } else {
|
|
||||||
+ dePowerLane(self, level, pos, state, railShape);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level world, BlockPos pos,
|
|
||||||
+ boolean bl, int distance, RailShape shape,
|
|
||||||
+ HashMap<BlockPos, Boolean> checkedPos) {
|
|
||||||
+ BlockState blockState = world.getBlockState(pos);
|
|
||||||
+ boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.get(pos);
|
|
||||||
+ if (speedCheck) {
|
|
||||||
+ return world.hasNeighborSignal(pos) ||
|
|
||||||
+ findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos);
|
|
||||||
+ } else {
|
|
||||||
+ if (blockState.is(self)) {
|
|
||||||
+ RailShape railShape = blockState.getValue(SHAPE);
|
|
||||||
+ if (shape == RailShape.EAST_WEST && (
|
|
||||||
+ railShape == RailShape.NORTH_SOUTH ||
|
|
||||||
+ railShape == RailShape.ASCENDING_NORTH ||
|
|
||||||
+ railShape == RailShape.ASCENDING_SOUTH
|
|
||||||
+ ) || shape == RailShape.NORTH_SOUTH && (
|
|
||||||
+ railShape == RailShape.EAST_WEST ||
|
|
||||||
+ railShape == RailShape.ASCENDING_EAST ||
|
|
||||||
+ railShape == RailShape.ASCENDING_WEST
|
|
||||||
+ )) {
|
|
||||||
+ return false;
|
|
||||||
+ } else if (blockState.getValue(POWERED)) {
|
|
||||||
+ return world.hasNeighborSignal(pos) ||
|
|
||||||
+ findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos);
|
|
||||||
+ } else {
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level level,
|
|
||||||
+ BlockPos pos, BlockState state, boolean bl, int distance,
|
|
||||||
+ HashMap<BlockPos, Boolean> checkedPos) {
|
|
||||||
+ if (distance >= RAIL_POWER_LIMIT - 1) return false;
|
|
||||||
+ int i = pos.getX();
|
|
||||||
+ int j = pos.getY();
|
|
||||||
+ int k = pos.getZ();
|
|
||||||
+ boolean bl2 = true;
|
|
||||||
+ RailShape railShape = state.getValue(SHAPE);
|
|
||||||
+ switch (railShape.ordinal()) {
|
|
||||||
+ case 0 -> {
|
|
||||||
+ if (bl) ++k;
|
|
||||||
+ else --k;
|
|
||||||
+ }
|
|
||||||
+ case 1 -> {
|
|
||||||
+ if (bl) --i;
|
|
||||||
+ else ++i;
|
|
||||||
+ }
|
|
||||||
+ case 2 -> {
|
|
||||||
+ if (bl) {
|
|
||||||
+ --i;
|
|
||||||
+ } else {
|
|
||||||
+ ++i;
|
|
||||||
+ ++j;
|
|
||||||
+ bl2 = false;
|
|
||||||
+ }
|
|
||||||
+ railShape = RailShape.EAST_WEST;
|
|
||||||
+ }
|
|
||||||
+ case 3 -> {
|
|
||||||
+ if (bl) {
|
|
||||||
+ --i;
|
|
||||||
+ ++j;
|
|
||||||
+ bl2 = false;
|
|
||||||
+ } else {
|
|
||||||
+ ++i;
|
|
||||||
+ }
|
|
||||||
+ railShape = RailShape.EAST_WEST;
|
|
||||||
+ }
|
|
||||||
+ case 4 -> {
|
|
||||||
+ if (bl) {
|
|
||||||
+ ++k;
|
|
||||||
+ } else {
|
|
||||||
+ --k;
|
|
||||||
+ ++j;
|
|
||||||
+ bl2 = false;
|
|
||||||
+ }
|
|
||||||
+ railShape = RailShape.NORTH_SOUTH;
|
|
||||||
+ }
|
|
||||||
+ case 5 -> {
|
|
||||||
+ if (bl) {
|
|
||||||
+ ++k;
|
|
||||||
+ ++j;
|
|
||||||
+ bl2 = false;
|
|
||||||
+ } else {
|
|
||||||
+ --k;
|
|
||||||
+ }
|
|
||||||
+ railShape = RailShape.NORTH_SOUTH;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return findPoweredRailSignalFaster(
|
|
||||||
+ self, level, new BlockPos(i, j, k),
|
|
||||||
+ bl, distance, railShape, checkedPos
|
|
||||||
+ ) ||
|
|
||||||
+ (bl2 && findPoweredRailSignalFaster(
|
|
||||||
+ self, level, new BlockPos(i, j - 1, k),
|
|
||||||
+ bl, distance, railShape, checkedPos
|
|
||||||
+ ));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public static void powerLane(PoweredRailBlock self, Level world, BlockPos pos,
|
|
||||||
+ BlockState mainState, RailShape railShape) {
|
|
||||||
+ world.setBlock(pos, mainState.setValue(POWERED, true), UPDATE_FORCE_PLACE);
|
|
||||||
+ HashMap<BlockPos, Boolean> checkedPos = new HashMap<>();
|
|
||||||
+ checkedPos.put(pos, true);
|
|
||||||
+ int[] count = new int[2];
|
|
||||||
+ if (railShape == RailShape.NORTH_SOUTH) { //Order: +z, -z
|
|
||||||
+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
|
|
||||||
+ setRailPositionsPower(self, world, pos, checkedPos, count, i, NORTH_SOUTH_DIR[i]);
|
|
||||||
+ }
|
|
||||||
+ updateRails(self, false, world, pos, mainState, count);
|
|
||||||
+ } else if (railShape == RailShape.EAST_WEST) { //Order: -x, +x
|
|
||||||
+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
|
|
||||||
+ setRailPositionsPower(self, world, pos, checkedPos, count, i, EAST_WEST_DIR[i]);
|
|
||||||
+ }
|
|
||||||
+ updateRails(self, true, world, pos, mainState, count);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public static void dePowerLane(PoweredRailBlock self, Level world, BlockPos pos,
|
|
||||||
+ BlockState mainState, RailShape railShape) {
|
|
||||||
+ world.setBlock(pos, mainState.setValue(POWERED, false), UPDATE_FORCE_PLACE);
|
|
||||||
+ int[] count = new int[2];
|
|
||||||
+ if (railShape == RailShape.NORTH_SOUTH) { //Order: +z, -z
|
|
||||||
+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
|
|
||||||
+ setRailPositionsDePower(self, world, pos, count, i, NORTH_SOUTH_DIR[i]);
|
|
||||||
+ }
|
|
||||||
+ updateRails(self, false, world, pos, mainState, count);
|
|
||||||
+ } else if (railShape == RailShape.EAST_WEST) { //Order: -x, +x
|
|
||||||
+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
|
|
||||||
+ setRailPositionsDePower(self, world, pos, count, i, EAST_WEST_DIR[i]);
|
|
||||||
+ }
|
|
||||||
+ updateRails(self, true, world, pos, mainState, count);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void setRailPositionsPower(PoweredRailBlock self, Level world, BlockPos pos,
|
|
||||||
+ HashMap<BlockPos, Boolean> checkedPos, int[] count, int i, Direction dir) {
|
|
||||||
+ for (int z = 1; z < RAIL_POWER_LIMIT; z++) {
|
|
||||||
+ BlockPos newPos = pos.relative(dir, z);
|
|
||||||
+ BlockState state = world.getBlockState(newPos);
|
|
||||||
+ if (checkedPos.containsKey(newPos)) {
|
|
||||||
+ if (!checkedPos.get(newPos)) break;
|
|
||||||
+ count[i]++;
|
|
||||||
+ } else if (!state.is(self) || state.getValue(POWERED) || !(
|
|
||||||
+ world.hasNeighborSignal(newPos) ||
|
|
||||||
+ findPoweredRailSignalFaster(self, world, newPos, state, true, 0, checkedPos) ||
|
|
||||||
+ findPoweredRailSignalFaster(self, world, newPos, state, false, 0, checkedPos)
|
|
||||||
+ )) {
|
|
||||||
+ checkedPos.put(newPos, false);
|
|
||||||
+ break;
|
|
||||||
+ } else {
|
|
||||||
+ checkedPos.put(newPos, true);
|
|
||||||
+ world.setBlock(newPos, state.setValue(POWERED, true), UPDATE_FORCE_PLACE);
|
|
||||||
+ count[i]++;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void setRailPositionsDePower(PoweredRailBlock self, Level world, BlockPos pos,
|
|
||||||
+ int[] count, int i, Direction dir) {
|
|
||||||
+ for (int z = 1; z < RAIL_POWER_LIMIT; z++) {
|
|
||||||
+ BlockPos newPos = pos.relative(dir, z);
|
|
||||||
+ BlockState state = world.getBlockState(newPos);
|
|
||||||
+ if (!state.is(self) || !state.getValue(POWERED) || world.hasNeighborSignal(newPos) ||
|
|
||||||
+ self.findPoweredRailSignal(world, newPos, state, true, 0) ||
|
|
||||||
+ self.findPoweredRailSignal(world, newPos, state, false, 0)) break;
|
|
||||||
+ world.setBlock(newPos, state.setValue(POWERED, false), UPDATE_FORCE_PLACE);
|
|
||||||
+ count[i]++;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void shapeUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, BlockState mainState,
|
|
||||||
+ int endPos, Direction direction, int currentPos, BlockPos blockPos) {
|
|
||||||
+ if (currentPos == endPos) {
|
|
||||||
+ BlockPos newPos = pos.relative(direction, currentPos + 1);
|
|
||||||
+ OptimizedPoweredRails.giveShapeUpdate(world, mainState, newPos, pos, direction);
|
|
||||||
+ BlockState state = world.getBlockState(blockPos);
|
|
||||||
+ if (state.is(self) && state.getValue(SHAPE).isAscending())
|
|
||||||
+ OptimizedPoweredRails.giveShapeUpdate(world, mainState, newPos.above(), pos, direction);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void neighborUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, int endPos,
|
|
||||||
+ Direction direction, Block block, int currentPos, BlockPos blockPos) {
|
|
||||||
+ if (currentPos == endPos) {
|
|
||||||
+ BlockPos newPos = pos.relative(direction, currentPos + 1);
|
|
||||||
+ world.neighborChanged(newPos, block, pos);
|
|
||||||
+ BlockState state = world.getBlockState(blockPos);
|
|
||||||
+ if (state.is(self) && state.getValue(SHAPE).isAscending())
|
|
||||||
+ world.neighborChanged(newPos.above(), block, blockPos);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void updateRailsSectionEastWestShape(PoweredRailBlock self, Level world, BlockPos pos,
|
|
||||||
+ int c, BlockState mainState, Direction dir,
|
|
||||||
+ int[] count, int countAmt) {
|
|
||||||
+ BlockPos pos1 = pos.relative(dir, c);
|
|
||||||
+ if (c == 0 && count[1] == 0)
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite());
|
|
||||||
+ shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.north(), pos, Direction.NORTH);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.south(), pos, Direction.SOUTH);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void updateRailsSectionNorthSouthShape(PoweredRailBlock self, Level world, BlockPos pos,
|
|
||||||
+ int c, BlockState mainState, Direction dir,
|
|
||||||
+ int[] count, int countAmt) {
|
|
||||||
+ BlockPos pos1 = pos.relative(dir, c);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.west(), pos, Direction.WEST);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.east(), pos, Direction.EAST);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN);
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP);
|
|
||||||
+ shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1);
|
|
||||||
+ if (c == 0 && count[1] == 0)
|
|
||||||
+ giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite());
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static void updateRails(PoweredRailBlock self, boolean eastWest, Level world,
|
|
||||||
+ BlockPos pos, BlockState mainState, int[] count) {
|
|
||||||
+ if (eastWest) {
|
|
||||||
+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
|
|
||||||
+ int countAmt = count[i];
|
|
||||||
+ if (i == 1 && countAmt == 0) continue;
|
|
||||||
+ Direction dir = EAST_WEST_DIR[i];
|
|
||||||
+ Block block = mainState.getBlock();
|
|
||||||
+ for (int c = countAmt; c >= i; c--) {
|
|
||||||
+ BlockPos p = pos.relative(dir, c);
|
|
||||||
+ if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, pos);
|
|
||||||
+ neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p);
|
|
||||||
+ world.neighborChanged(p.below(), block, pos);
|
|
||||||
+ world.neighborChanged(p.above(), block, pos);
|
|
||||||
+ world.neighborChanged(p.north(), block, pos);
|
|
||||||
+ world.neighborChanged(p.south(), block, pos);
|
|
||||||
+ BlockPos pos2 = pos.relative(dir, c).below();
|
|
||||||
+ world.neighborChanged(pos2.below(), block, pos);
|
|
||||||
+ world.neighborChanged(pos2.north(), block, pos);
|
|
||||||
+ world.neighborChanged(pos2.south(), block, pos);
|
|
||||||
+ if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, pos);
|
|
||||||
+ if (c == 0 && count[1] == 0)
|
|
||||||
+ world.neighborChanged(p.relative(dir.getOpposite()).below(), block, pos);
|
|
||||||
+ }
|
|
||||||
+ for (int c = countAmt; c >= i; c--)
|
|
||||||
+ updateRailsSectionEastWestShape(self, world, pos, c, mainState, dir, count, countAmt);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
|
|
||||||
+ int countAmt = count[i];
|
|
||||||
+ if (i == 1 && countAmt == 0) continue;
|
|
||||||
+ Direction dir = NORTH_SOUTH_DIR[i];
|
|
||||||
+ Block block = mainState.getBlock();
|
|
||||||
+ for (int c = countAmt; c >= i; c--) {
|
|
||||||
+ BlockPos p = pos.relative(dir, c);
|
|
||||||
+ world.neighborChanged(p.west(), block, pos);
|
|
||||||
+ world.neighborChanged(p.east(), block, pos);
|
|
||||||
+ world.neighborChanged(p.below(), block, pos);
|
|
||||||
+ world.neighborChanged(p.above(), block, pos);
|
|
||||||
+ neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p);
|
|
||||||
+ if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, pos);
|
|
||||||
+ BlockPos pos2 = pos.relative(dir, c).below();
|
|
||||||
+ world.neighborChanged(pos2.west(), block, pos);
|
|
||||||
+ world.neighborChanged(pos2.east(), block, pos);
|
|
||||||
+ world.neighborChanged(pos2.below(), block, pos);
|
|
||||||
+ if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, pos);
|
|
||||||
+ if (c == 0 && count[1] == 0)
|
|
||||||
+ world.neighborChanged(p.relative(dir.getOpposite()).below(), block, pos);
|
|
||||||
+ }
|
|
||||||
+ for (int c = countAmt; c >= i; c--)
|
|
||||||
+ updateRailsSectionNorthSouthShape(self, world, pos, c, mainState, dir, count, countAmt);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
\ No newline at end of file
|
|
||||||
@@ -15798,13 +15798,13 @@ index 9c0ded7ae7e3a520704033a866f80743ae85d772..4f3646961beb877520e257e11224c304
|
|||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
diff --git a/net/minecraft/world/level/block/PoweredRailBlock.java b/net/minecraft/world/level/block/PoweredRailBlock.java
|
diff --git a/net/minecraft/world/level/block/PoweredRailBlock.java b/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||||
index f33b53257a231dccf16740f1e78a3cdfa6e70726..4b3d00b085ea5d345b418815c9869f5f8c9fe558 100644
|
index be3b5531cab74df8770ffa04ec4a4bae28cc57e6..e6674c37e09fe0ad2e971bd957666929492ba57e 100644
|
||||||
--- a/net/minecraft/world/level/block/PoweredRailBlock.java
|
--- a/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||||
+++ b/net/minecraft/world/level/block/PoweredRailBlock.java
|
+++ b/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||||
@@ -34,7 +34,7 @@ public class PoweredRailBlock extends BaseRailBlock {
|
@@ -34,7 +34,7 @@ public class PoweredRailBlock extends BaseRailBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean findPoweredRailSignal(Level level, BlockPos pos, BlockState state, boolean searchForward, int recursionCount) {
|
public boolean findPoweredRailSignal(Level level, BlockPos pos, BlockState state, boolean searchForward, int recursionCount) {
|
||||||
- if (recursionCount >= 8) {
|
- if (recursionCount >= 8) {
|
||||||
+ if (recursionCount >= level.purpurConfig.railActivationRange) { // Purpur - Config for powered rail activation distance
|
+ if (recursionCount >= level.purpurConfig.railActivationRange) { // Purpur - Config for powered rail activation distance
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
|
||||||
|
Date: Sat, 17 Feb 2024 17:57:08 -0500
|
||||||
|
Subject: [PATCH] Rail Optimization: optimized PoweredRailBlock logic
|
||||||
|
|
||||||
|
Original project: https://github.com/FxMorin/RailOptimization
|
||||||
|
|
||||||
|
Full Rewrite of the powered rail iteration logic
|
||||||
|
that makes powered/activator rails turning on/off up to 4x faster.
|
||||||
|
This rewrite brings a massive performance boost while keeping the vanilla order. This is achieved by running all the
|
||||||
|
powered rail logic from a single rail instead of each block iterating separately. Which was not only very
|
||||||
|
expensive but also completely unnecessary and with a lot of massive overhead
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/world/level/block/PoweredRailBlock.java b/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||||
|
index e6674c37e09fe0ad2e971bd957666929492ba57e..c93a7d166ac97bac981d906c6894606237107fe8 100644
|
||||||
|
--- a/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||||
|
+++ b/net/minecraft/world/level/block/PoweredRailBlock.java
|
||||||
|
@@ -128,6 +128,12 @@ public class PoweredRailBlock extends BaseRailBlock {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateState(BlockState state, Level level, BlockPos pos, Block block) {
|
||||||
|
+ // Leaf start - Rail Optimization
|
||||||
|
+ if (org.dreeam.leaf.config.modules.opt.OptimizedPoweredRails.enabled) {
|
||||||
|
+ org.dreeam.leaf.optimize.OptimizedPoweredRails.updateState(this, state, level, pos);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ // Leaf end - Rail Optimization
|
||||||
|
boolean poweredValue = state.getValue(POWERED);
|
||||||
|
boolean flag = level.hasNeighborSignal(pos)
|
||||||
|
|| this.findPoweredRailSignal(level, pos, state, true, 0)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.dreeam.leaf.config.modules.opt;
|
||||||
|
|
||||||
|
import org.dreeam.leaf.config.ConfigModules;
|
||||||
|
import org.dreeam.leaf.config.EnumConfigCategory;
|
||||||
|
|
||||||
|
public class OptimizedPoweredRails extends ConfigModules {
|
||||||
|
|
||||||
|
public String getBasePath() {
|
||||||
|
return EnumConfigCategory.PERF.getBaseKeyName() + ".optimized-powered-rails";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean enabled = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaded() {
|
||||||
|
enabled = config().getBoolean(getBasePath(), enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,333 @@
|
|||||||
|
package org.dreeam.leaf.optimize;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
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 java.util.HashMap;
|
||||||
|
|
||||||
|
import static net.minecraft.world.level.block.Block.*;
|
||||||
|
import static net.minecraft.world.level.block.PoweredRailBlock.POWERED;
|
||||||
|
import static net.minecraft.world.level.block.PoweredRailBlock.SHAPE;
|
||||||
|
|
||||||
|
public class OptimizedPoweredRails {
|
||||||
|
|
||||||
|
private static final Direction[] EAST_WEST_DIR = new Direction[]{Direction.WEST, Direction.EAST};
|
||||||
|
private static final Direction[] NORTH_SOUTH_DIR = new Direction[]{Direction.SOUTH, Direction.NORTH};
|
||||||
|
|
||||||
|
private static final int UPDATE_FORCE_PLACE = UPDATE_MOVE_BY_PISTON | UPDATE_KNOWN_SHAPE | UPDATE_CLIENTS;
|
||||||
|
|
||||||
|
private static int RAIL_POWER_LIMIT = 8;
|
||||||
|
|
||||||
|
private static void giveShapeUpdate(Level level, BlockState state, BlockPos pos, BlockPos fromPos, Direction direction) {
|
||||||
|
BlockState oldState = level.getBlockState(pos);
|
||||||
|
Block.updateOrDestroy(
|
||||||
|
oldState,
|
||||||
|
oldState.updateShape(level, level, pos, direction.getOpposite(), fromPos, state, level.random),
|
||||||
|
level,
|
||||||
|
pos,
|
||||||
|
UPDATE_CLIENTS & -34,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getRailPowerLimit() {
|
||||||
|
return RAIL_POWER_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setRailPowerLimit(int powerLimit) {
|
||||||
|
RAIL_POWER_LIMIT = powerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateState(PoweredRailBlock self, BlockState state, Level level, BlockPos pos) {
|
||||||
|
boolean shouldBePowered = level.hasNeighborSignal(pos) ||
|
||||||
|
self.findPoweredRailSignal(level, pos, state, true, 0) ||
|
||||||
|
self.findPoweredRailSignal(level, pos, state, false, 0);
|
||||||
|
if (shouldBePowered != state.getValue(POWERED)) {
|
||||||
|
RailShape railShape = state.getValue(SHAPE);
|
||||||
|
if (railShape.isSlope()) {
|
||||||
|
level.setBlock(pos, state.setValue(POWERED, shouldBePowered), 3);
|
||||||
|
level.updateNeighborsAtExceptFromFacing(pos.below(), self, Direction.UP, null);
|
||||||
|
level.updateNeighborsAtExceptFromFacing(pos.above(), self, Direction.DOWN, null); // isSlope
|
||||||
|
} else if (shouldBePowered) {
|
||||||
|
powerLane(self, level, pos, state, railShape);
|
||||||
|
} else {
|
||||||
|
dePowerLane(self, level, pos, state, railShape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level world, BlockPos pos,
|
||||||
|
boolean bl, int distance, RailShape shape,
|
||||||
|
HashMap<BlockPos, Boolean> checkedPos) {
|
||||||
|
BlockState blockState = world.getBlockState(pos);
|
||||||
|
boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.get(pos);
|
||||||
|
if (speedCheck) {
|
||||||
|
return world.hasNeighborSignal(pos) ||
|
||||||
|
findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos);
|
||||||
|
} else {
|
||||||
|
if (blockState.is(self)) {
|
||||||
|
RailShape railShape = blockState.getValue(SHAPE);
|
||||||
|
if (shape == RailShape.EAST_WEST && (
|
||||||
|
railShape == RailShape.NORTH_SOUTH ||
|
||||||
|
railShape == RailShape.ASCENDING_NORTH ||
|
||||||
|
railShape == RailShape.ASCENDING_SOUTH
|
||||||
|
) || shape == RailShape.NORTH_SOUTH && (
|
||||||
|
railShape == RailShape.EAST_WEST ||
|
||||||
|
railShape == RailShape.ASCENDING_EAST ||
|
||||||
|
railShape == RailShape.ASCENDING_WEST
|
||||||
|
)) {
|
||||||
|
return false;
|
||||||
|
} else if (blockState.getValue(POWERED)) {
|
||||||
|
return world.hasNeighborSignal(pos) ||
|
||||||
|
findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level level,
|
||||||
|
BlockPos pos, BlockState state, boolean bl, int distance,
|
||||||
|
HashMap<BlockPos, Boolean> checkedPos) {
|
||||||
|
if (distance >= RAIL_POWER_LIMIT - 1) return false;
|
||||||
|
int i = pos.getX();
|
||||||
|
int j = pos.getY();
|
||||||
|
int k = pos.getZ();
|
||||||
|
boolean bl2 = true;
|
||||||
|
RailShape railShape = state.getValue(SHAPE);
|
||||||
|
switch (railShape.ordinal()) {
|
||||||
|
case 0 -> {
|
||||||
|
if (bl) ++k;
|
||||||
|
else --k;
|
||||||
|
}
|
||||||
|
case 1 -> {
|
||||||
|
if (bl) --i;
|
||||||
|
else ++i;
|
||||||
|
}
|
||||||
|
case 2 -> {
|
||||||
|
if (bl) {
|
||||||
|
--i;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
bl2 = false;
|
||||||
|
}
|
||||||
|
railShape = RailShape.EAST_WEST;
|
||||||
|
}
|
||||||
|
case 3 -> {
|
||||||
|
if (bl) {
|
||||||
|
--i;
|
||||||
|
++j;
|
||||||
|
bl2 = false;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
railShape = RailShape.EAST_WEST;
|
||||||
|
}
|
||||||
|
case 4 -> {
|
||||||
|
if (bl) {
|
||||||
|
++k;
|
||||||
|
} else {
|
||||||
|
--k;
|
||||||
|
++j;
|
||||||
|
bl2 = false;
|
||||||
|
}
|
||||||
|
railShape = RailShape.NORTH_SOUTH;
|
||||||
|
}
|
||||||
|
case 5 -> {
|
||||||
|
if (bl) {
|
||||||
|
++k;
|
||||||
|
++j;
|
||||||
|
bl2 = false;
|
||||||
|
} else {
|
||||||
|
--k;
|
||||||
|
}
|
||||||
|
railShape = RailShape.NORTH_SOUTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return findPoweredRailSignalFaster(
|
||||||
|
self, level, new BlockPos(i, j, k),
|
||||||
|
bl, distance, railShape, checkedPos
|
||||||
|
) ||
|
||||||
|
(bl2 && findPoweredRailSignalFaster(
|
||||||
|
self, level, new BlockPos(i, j - 1, k),
|
||||||
|
bl, distance, railShape, checkedPos
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void powerLane(PoweredRailBlock self, Level world, BlockPos pos,
|
||||||
|
BlockState mainState, RailShape railShape) {
|
||||||
|
world.setBlock(pos, mainState.setValue(POWERED, true), UPDATE_FORCE_PLACE);
|
||||||
|
HashMap<BlockPos, Boolean> checkedPos = new HashMap<>();
|
||||||
|
checkedPos.put(pos, true);
|
||||||
|
int[] count = new int[2];
|
||||||
|
if (railShape == RailShape.NORTH_SOUTH) { // Order: +z, -z
|
||||||
|
for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
|
||||||
|
setRailPositionsPower(self, world, pos, checkedPos, count, i, NORTH_SOUTH_DIR[i]);
|
||||||
|
}
|
||||||
|
updateRails(self, false, world, pos, mainState, count);
|
||||||
|
} else if (railShape == RailShape.EAST_WEST) { // Order: -x, +x
|
||||||
|
for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
|
||||||
|
setRailPositionsPower(self, world, pos, checkedPos, count, i, EAST_WEST_DIR[i]);
|
||||||
|
}
|
||||||
|
updateRails(self, true, world, pos, mainState, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void dePowerLane(PoweredRailBlock self, Level world, BlockPos pos,
|
||||||
|
BlockState mainState, RailShape railShape) {
|
||||||
|
world.setBlock(pos, mainState.setValue(POWERED, false), UPDATE_FORCE_PLACE);
|
||||||
|
int[] count = new int[2];
|
||||||
|
if (railShape == RailShape.NORTH_SOUTH) { // Order: +z, -z
|
||||||
|
for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
|
||||||
|
setRailPositionsDePower(self, world, pos, count, i, NORTH_SOUTH_DIR[i]);
|
||||||
|
}
|
||||||
|
updateRails(self, false, world, pos, mainState, count);
|
||||||
|
} else if (railShape == RailShape.EAST_WEST) { // Order: -x, +x
|
||||||
|
for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
|
||||||
|
setRailPositionsDePower(self, world, pos, count, i, EAST_WEST_DIR[i]);
|
||||||
|
}
|
||||||
|
updateRails(self, true, world, pos, mainState, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setRailPositionsPower(PoweredRailBlock self, Level world, BlockPos pos,
|
||||||
|
HashMap<BlockPos, Boolean> checkedPos, int[] count, int i, Direction dir) {
|
||||||
|
for (int z = 1; z < RAIL_POWER_LIMIT; z++) {
|
||||||
|
BlockPos newPos = pos.relative(dir, z);
|
||||||
|
BlockState state = world.getBlockState(newPos);
|
||||||
|
if (checkedPos.containsKey(newPos)) {
|
||||||
|
if (!checkedPos.get(newPos)) break;
|
||||||
|
count[i]++;
|
||||||
|
} else if (!state.is(self) || state.getValue(POWERED) || !(
|
||||||
|
world.hasNeighborSignal(newPos) ||
|
||||||
|
findPoweredRailSignalFaster(self, world, newPos, state, true, 0, checkedPos) ||
|
||||||
|
findPoweredRailSignalFaster(self, world, newPos, state, false, 0, checkedPos)
|
||||||
|
)) {
|
||||||
|
checkedPos.put(newPos, false);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
checkedPos.put(newPos, true);
|
||||||
|
world.setBlock(newPos, state.setValue(POWERED, true), UPDATE_FORCE_PLACE);
|
||||||
|
count[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setRailPositionsDePower(PoweredRailBlock self, Level world, BlockPos pos,
|
||||||
|
int[] count, int i, Direction dir) {
|
||||||
|
for (int z = 1; z < RAIL_POWER_LIMIT; z++) {
|
||||||
|
BlockPos newPos = pos.relative(dir, z);
|
||||||
|
BlockState state = world.getBlockState(newPos);
|
||||||
|
if (!state.is(self) || !state.getValue(POWERED) || world.hasNeighborSignal(newPos) ||
|
||||||
|
self.findPoweredRailSignal(world, newPos, state, true, 0) ||
|
||||||
|
self.findPoweredRailSignal(world, newPos, state, false, 0)) break;
|
||||||
|
world.setBlock(newPos, state.setValue(POWERED, false), UPDATE_FORCE_PLACE);
|
||||||
|
count[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void shapeUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, BlockState mainState,
|
||||||
|
int endPos, Direction direction, int currentPos, BlockPos blockPos) {
|
||||||
|
if (currentPos == endPos) {
|
||||||
|
BlockPos newPos = pos.relative(direction, currentPos + 1);
|
||||||
|
giveShapeUpdate(world, mainState, newPos, pos, direction);
|
||||||
|
BlockState state = world.getBlockState(blockPos);
|
||||||
|
if (state.is(self) && state.getValue(SHAPE).isSlope()) giveShapeUpdate(world, mainState, newPos.above(), pos, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void neighborUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, int endPos,
|
||||||
|
Direction direction, Block block, int currentPos, BlockPos blockPos) {
|
||||||
|
if (currentPos == endPos) {
|
||||||
|
BlockPos newPos = pos.relative(direction, currentPos + 1);
|
||||||
|
world.neighborChanged(newPos, block, null);
|
||||||
|
BlockState state = world.getBlockState(blockPos);
|
||||||
|
if (state.is(self) && state.getValue(SHAPE).isSlope()) world.neighborChanged(newPos.above(), block, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateRailsSectionEastWestShape(PoweredRailBlock self, Level world, BlockPos pos,
|
||||||
|
int c, BlockState mainState, Direction dir,
|
||||||
|
int[] count, int countAmt) {
|
||||||
|
BlockPos pos1 = pos.relative(dir, c);
|
||||||
|
if (c == 0 && count[1] == 0) giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite());
|
||||||
|
shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.north(), pos, Direction.NORTH);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.south(), pos, Direction.SOUTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateRailsSectionNorthSouthShape(PoweredRailBlock self, Level world, BlockPos pos,
|
||||||
|
int c, BlockState mainState, Direction dir,
|
||||||
|
int[] count, int countAmt) {
|
||||||
|
BlockPos pos1 = pos.relative(dir, c);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.west(), pos, Direction.WEST);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.east(), pos, Direction.EAST);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.below(), pos, Direction.DOWN);
|
||||||
|
giveShapeUpdate(world, mainState, pos1.above(), pos, Direction.UP);
|
||||||
|
shapeUpdateEnd(self, world, pos, mainState, countAmt, dir, c, pos1);
|
||||||
|
if (c == 0 && count[1] == 0) giveShapeUpdate(world, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateRails(PoweredRailBlock self, boolean eastWest, Level world,
|
||||||
|
BlockPos pos, BlockState mainState, int[] count) {
|
||||||
|
if (eastWest) {
|
||||||
|
for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
|
||||||
|
int countAmt = count[i];
|
||||||
|
if (i == 1 && countAmt == 0) continue;
|
||||||
|
Direction dir = EAST_WEST_DIR[i];
|
||||||
|
Block block = mainState.getBlock();
|
||||||
|
for (int c = countAmt; c >= i; c--) {
|
||||||
|
BlockPos p = pos.relative(dir, c);
|
||||||
|
if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, null);
|
||||||
|
neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p);
|
||||||
|
world.neighborChanged(p.below(), block, null);
|
||||||
|
world.neighborChanged(p.above(), block, null);
|
||||||
|
world.neighborChanged(p.north(), block, null);
|
||||||
|
world.neighborChanged(p.south(), block, null);
|
||||||
|
BlockPos pos2 = pos.relative(dir, c).below();
|
||||||
|
world.neighborChanged(pos2.below(), block, null);
|
||||||
|
world.neighborChanged(pos2.north(), block, null);
|
||||||
|
world.neighborChanged(pos2.south(), block, null);
|
||||||
|
if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, null);
|
||||||
|
if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()).below(), block, null);
|
||||||
|
}
|
||||||
|
for (int c = countAmt; c >= i; c--)
|
||||||
|
updateRailsSectionEastWestShape(self, world, pos, c, mainState, dir, count, countAmt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
|
||||||
|
int countAmt = count[i];
|
||||||
|
if (i == 1 && countAmt == 0) continue;
|
||||||
|
Direction dir = NORTH_SOUTH_DIR[i];
|
||||||
|
Block block = mainState.getBlock();
|
||||||
|
for (int c = countAmt; c >= i; c--) {
|
||||||
|
BlockPos p = pos.relative(dir, c);
|
||||||
|
world.neighborChanged(p.west(), block, null);
|
||||||
|
world.neighborChanged(p.east(), block, null);
|
||||||
|
world.neighborChanged(p.below(), block, null);
|
||||||
|
world.neighborChanged(p.above(), block, null);
|
||||||
|
neighborUpdateEnd(self, world, pos, countAmt, dir, block, c, p);
|
||||||
|
if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, null);
|
||||||
|
BlockPos pos2 = pos.relative(dir, c).below();
|
||||||
|
world.neighborChanged(pos2.west(), block, null);
|
||||||
|
world.neighborChanged(pos2.east(), block, null);
|
||||||
|
world.neighborChanged(pos2.below(), block, null);
|
||||||
|
if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, null);
|
||||||
|
if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()).below(), block, null);
|
||||||
|
}
|
||||||
|
for (int c = countAmt; c >= i; c--)
|
||||||
|
updateRailsSectionNorthSouthShape(self, world, pos, c, mainState, dir, count, countAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user