9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-25 18:09:17 +00:00

Update changes from ver/1.21.4 branch

This commit is contained in:
Dreeam
2025-06-13 22:46:52 +08:00
125 changed files with 483 additions and 238 deletions

View File

@@ -13,7 +13,7 @@ public class AsyncExecutor implements Runnable {
private final Logger LOGGER = LogManager.getLogger("Leaf");
private final PriorityQueue<Runnable> jobs = PriorityQueues.synchronize(new ObjectArrayFIFOQueue<>());
private final Thread thread;
public final Thread thread;
private volatile boolean killswitch = false;
public AsyncExecutor(String threadName) {

View File

@@ -32,7 +32,8 @@ public class AsyncPlayerDataSaving {
new ThreadPoolExecutor.DiscardPolicy()
);
} else {
throw new IllegalStateException();
// Temp no-op
//throw new IllegalStateException();
}
}

View File

@@ -14,7 +14,7 @@ public class ShutdownExecutors {
public static final Logger LOGGER = LogManager.getLogger("Leaf");
public static void shutdown(MinecraftServer server) {
if (server.mobSpawnExecutor != null) {
if (server.mobSpawnExecutor != null && server.mobSpawnExecutor.thread.isAlive()) {
LOGGER.info("Waiting for mob spawning thread to shutdown...");
try {
server.mobSpawnExecutor.join(3000L);

View File

@@ -43,7 +43,8 @@ public class AsyncPathProcessor {
getRejectedPolicy()
);
} else {
throw new IllegalStateException();
// Temp no-op
//throw new IllegalStateException();
}
}

View File

@@ -46,7 +46,8 @@ public class MultithreadedTracker {
getRejectedPolicy()
);
} else {
throw new IllegalStateException();
// Temp no-op
//throw new IllegalStateException();
}
}
@@ -129,13 +130,13 @@ public class MultithreadedTracker {
// Original ChunkMap#newTrackerTick of Paper
// Just for diff usage for future update
private static void tickOriginal(ServerLevel level) {
final ServerEntityLookup entityLookup = (ServerEntityLookup) ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) level).moonrise$getEntityLookup();
final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup) ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) level).moonrise$getEntityLookup();
final ReferenceList<Entity> trackerEntities = entityLookup.trackerEntities;
final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.world.entity.Entity> trackerEntities = entityLookup.trackerEntities;
final Entity[] trackerEntitiesRaw = trackerEntities.getRawDataUnchecked();
for (int i = 0, len = trackerEntities.size(); i < len; ++i) {
final Entity entity = trackerEntitiesRaw[i];
final ChunkMap.TrackedEntity tracker = ((EntityTrackerEntity) entity).moonrise$getTrackedEntity();
final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity) entity).moonrise$getTrackedEntity();
if (tracker == null) {
continue;
}

View File

@@ -71,7 +71,7 @@ public class LeafConfig {
Command.broadcastCommandMessage(sender, Component.text(success, NamedTextColor.GREEN));
} catch (Exception e) {
Command.broadcastCommandMessage(sender, Component.text("Failed to reload config. See error in console!", NamedTextColor.RED));
LOGGER.error(e);
LOGGER.error("Failed to reload config!", e);
}
}, Util.ioPool());
}
@@ -87,7 +87,7 @@ public class LeafConfig {
LOGGER.info("Successfully loaded config in {}ms.", (System.nanoTime() - begin) / 1_000_000);
} catch (Exception e) {
LeafConfig.LOGGER.error("Failed to load config modules!", e);
LOGGER.error("Failed to load config modules!", e);
}
}
@@ -95,7 +95,7 @@ public class LeafConfig {
private static void loadConfig(boolean init) throws Exception {
// Create config folder
createDirectory(LeafConfig.I_CONFIG_FOLDER);
createDirectory(I_CONFIG_FOLDER);
leafGlobalConfig = new LeafGlobalConfig(init);

View File

@@ -1,17 +0,0 @@
package org.dreeam.leaf.config.modules.opt;
import org.dreeam.leaf.config.ConfigModules;
import org.dreeam.leaf.config.EnumConfigCategory;
public class PreloadNaturalMobSpawning extends ConfigModules {
public String getBasePath() {
return EnumConfigCategory.PERF.getBaseKeyName() + ".preload-mob-spawning-position";
}
public static boolean enabled = false;
@Override
public void onLoaded() {
enabled = config.getBoolean(getBasePath() + ".enabled", enabled);
}
}

View File

@@ -1,5 +1,6 @@
package org.dreeam.leaf.world.block;
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
@@ -8,8 +9,6 @@ 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;
@@ -23,6 +22,8 @@ public class OptimizedPoweredRails {
private static int RAIL_POWER_LIMIT = 8;
private static final Object2BooleanOpenHashMap<BlockPos> CHECKED_POS_POOL = new Object2BooleanOpenHashMap<>();
private static void giveShapeUpdate(Level level, BlockState state, BlockPos pos, BlockPos fromPos, Direction direction) {
BlockState oldState = level.getBlockState(pos);
Block.updateOrDestroy(
@@ -45,8 +46,8 @@ public class OptimizedPoweredRails {
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);
findPoweredRailSignalFaster(self, level, pos, state, true, 0, CHECKED_POS_POOL) ||
findPoweredRailSignalFaster(self, level, pos, state, false, 0, CHECKED_POS_POOL);
if (shouldBePowered != state.getValue(POWERED)) {
RailShape railShape = state.getValue(SHAPE);
if (railShape.isSlope()) {
@@ -61,14 +62,14 @@ public class OptimizedPoweredRails {
}
}
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);
private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level level, BlockPos pos,
boolean searchForward, int distance, RailShape shape,
Object2BooleanOpenHashMap<BlockPos> checkedPos) {
BlockState blockState = level.getBlockState(pos);
boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.getBoolean(pos);
if (speedCheck) {
return world.hasNeighborSignal(pos) ||
findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos);
return level.hasNeighborSignal(pos) ||
findPoweredRailSignalFaster(self, level, pos, blockState, searchForward, distance + 1, checkedPos);
} else {
if (blockState.is(self)) {
RailShape railShape = blockState.getValue(SHAPE);
@@ -83,8 +84,8 @@ public class OptimizedPoweredRails {
)) {
return false;
} else if (blockState.getValue(POWERED)) {
return world.hasNeighborSignal(pos) ||
findPoweredRailSignalFaster(self, world, pos, blockState, bl, distance + 1, checkedPos);
return level.hasNeighborSignal(pos) ||
findPoweredRailSignalFaster(self, level, pos, blockState, searchForward, distance + 1, checkedPos);
} else {
return false;
}
@@ -94,191 +95,200 @@ public class OptimizedPoweredRails {
}
private static boolean findPoweredRailSignalFaster(PoweredRailBlock self, Level level,
BlockPos pos, BlockState state, boolean bl, int distance,
HashMap<BlockPos, Boolean> checkedPos) {
BlockPos pos, BlockState state, boolean searchForward, int distance,
Object2BooleanOpenHashMap<BlockPos> checkedPos) {
if (distance >= RAIL_POWER_LIMIT - 1) return false;
int i = pos.getX();
int j = pos.getY();
int k = pos.getZ();
boolean bl2 = true;
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
boolean flag = true;
RailShape railShape = state.getValue(SHAPE);
switch (railShape.ordinal()) {
case 0 -> {
if (bl) ++k;
else --k;
if (searchForward) ++z;
else --z;
}
case 1 -> {
if (bl) --i;
else ++i;
if (searchForward) --x;
else ++x;
}
case 2 -> {
if (bl) {
--i;
if (searchForward) {
--x;
} else {
++i;
++j;
bl2 = false;
++x;
++y;
flag = false;
}
railShape = RailShape.EAST_WEST;
}
case 3 -> {
if (bl) {
--i;
++j;
bl2 = false;
if (searchForward) {
--x;
++y;
flag = false;
} else {
++i;
++x;
}
railShape = RailShape.EAST_WEST;
}
case 4 -> {
if (bl) {
++k;
if (searchForward) {
++z;
} else {
--k;
++j;
bl2 = false;
--z;
++y;
flag = false;
}
railShape = RailShape.NORTH_SOUTH;
}
case 5 -> {
if (bl) {
++k;
++j;
bl2 = false;
if (searchForward) {
++z;
++y;
flag = false;
} else {
--k;
--z;
}
railShape = RailShape.NORTH_SOUTH;
}
}
return findPoweredRailSignalFaster(
self, level, new BlockPos(i, j, k),
bl, distance, railShape, checkedPos
self, level, new BlockPos(x, y, z),
searchForward, distance, railShape, checkedPos
) ||
(bl2 && findPoweredRailSignalFaster(
self, level, new BlockPos(i, j - 1, k),
bl, distance, railShape, checkedPos
(flag && findPoweredRailSignalFaster(
self, level, new BlockPos(x, y - 1, z),
searchForward, distance, railShape, checkedPos
));
}
private static void powerLane(PoweredRailBlock self, Level world, BlockPos pos,
private static void powerLane(PoweredRailBlock self, Level level, BlockPos pos,
BlockState mainState, RailShape railShape) {
world.setBlock(pos, mainState.setValue(POWERED, true), UPDATE_FORCE_PLACE);
HashMap<BlockPos, Boolean> checkedPos = new HashMap<>();
level.setBlock(pos, mainState.setValue(POWERED, true), UPDATE_FORCE_PLACE);
Object2BooleanOpenHashMap<BlockPos> checkedPos = CHECKED_POS_POOL;
checkedPos.clear();
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]);
setRailPositionsPower(self, level, pos, checkedPos, count, i, NORTH_SOUTH_DIR[i]);
}
updateRails(self, false, world, pos, mainState, count);
updateRails(self, false, level, 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]);
setRailPositionsPower(self, level, pos, checkedPos, count, i, EAST_WEST_DIR[i]);
}
updateRails(self, true, world, pos, mainState, count);
updateRails(self, true, level, pos, mainState, count);
}
checkedPos.clear();
}
private static void dePowerLane(PoweredRailBlock self, Level world, BlockPos pos,
private static void dePowerLane(PoweredRailBlock self, Level level, BlockPos pos,
BlockState mainState, RailShape railShape) {
world.setBlock(pos, mainState.setValue(POWERED, false), UPDATE_FORCE_PLACE);
level.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]);
setRailPositionsDePower(self, level, pos, count, i, NORTH_SOUTH_DIR[i]);
}
updateRails(self, false, world, pos, mainState, count);
updateRails(self, false, level, 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]);
setRailPositionsDePower(self, level, pos, count, i, EAST_WEST_DIR[i]);
}
updateRails(self, true, world, pos, mainState, count);
updateRails(self, true, level, pos, mainState, count);
}
}
private static void setRailPositionsPower(PoweredRailBlock self, Level world, BlockPos pos,
HashMap<BlockPos, Boolean> checkedPos, int[] count, int i, Direction dir) {
private static void setRailPositionsPower(PoweredRailBlock self, Level level, BlockPos pos,
Object2BooleanOpenHashMap<BlockPos> 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);
BlockState state = level.getBlockState(newPos);
if (checkedPos.containsKey(newPos)) {
if (!checkedPos.get(newPos)) break;
if (!checkedPos.getBoolean(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)
)) {
} else if (!state.is(self) || state.getValue(POWERED) || !(level.hasNeighborSignal(newPos) ||
findPoweredRailSignalFaster(self, level, newPos, state, true, 0, checkedPos) ||
findPoweredRailSignalFaster(self, level, 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);
if (!state.getValue(POWERED)) {
level.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) {
private static void setRailPositionsDePower(PoweredRailBlock self, Level level, BlockPos pos,
int[] count, int i, Direction dir) {
Object2BooleanOpenHashMap<BlockPos> checkedPos = CHECKED_POS_POOL;
checkedPos.clear();
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);
BlockState state = level.getBlockState(newPos);
if (!state.is(self) || !state.getValue(POWERED) || level.hasNeighborSignal(newPos) ||
findPoweredRailSignalFaster(self, level, newPos, state, true, 0, checkedPos) ||
findPoweredRailSignalFaster(self, level, newPos, state, false, 0, checkedPos))
break;
if (state.getValue(POWERED)) {
level.setBlock(newPos, state.setValue(POWERED, false), UPDATE_FORCE_PLACE);
}
count[i]++;
}
checkedPos.clear();
}
private static void shapeUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, BlockState mainState,
private static void shapeUpdateEnd(PoweredRailBlock self, Level level, 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);
giveShapeUpdate(level, mainState, newPos, pos, direction);
BlockState state = level.getBlockState(blockPos);
if (state.is(self) && state.getValue(SHAPE).isSlope()) giveShapeUpdate(level, mainState, newPos.above(), pos, direction);
}
}
private static void neighborUpdateEnd(PoweredRailBlock self, Level world, BlockPos pos, int endPos,
private static void neighborUpdateEnd(PoweredRailBlock self, Level level, 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);
level.neighborChanged(newPos, block, null);
BlockState state = level.getBlockState(blockPos);
if (state.is(self) && state.getValue(SHAPE).isSlope()) level.neighborChanged(newPos.above(), block, null);
}
}
private static void updateRailsSectionEastWestShape(PoweredRailBlock self, Level world, BlockPos pos,
private static void updateRailsSectionEastWestShape(PoweredRailBlock self, Level level, 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);
if (c == 0 && count[1] == 0) giveShapeUpdate(level, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite());
shapeUpdateEnd(self, level, pos, mainState, countAmt, dir, c, pos1);
giveShapeUpdate(level, mainState, pos1.below(), pos, Direction.DOWN);
giveShapeUpdate(level, mainState, pos1.above(), pos, Direction.UP);
giveShapeUpdate(level, mainState, pos1.north(), pos, Direction.NORTH);
giveShapeUpdate(level, mainState, pos1.south(), pos, Direction.SOUTH);
}
private static void updateRailsSectionNorthSouthShape(PoweredRailBlock self, Level world, BlockPos pos,
private static void updateRailsSectionNorthSouthShape(PoweredRailBlock self, Level level, 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());
giveShapeUpdate(level, mainState, pos1.west(), pos, Direction.WEST);
giveShapeUpdate(level, mainState, pos1.east(), pos, Direction.EAST);
giveShapeUpdate(level, mainState, pos1.below(), pos, Direction.DOWN);
giveShapeUpdate(level, mainState, pos1.above(), pos, Direction.UP);
shapeUpdateEnd(self, level, pos, mainState, countAmt, dir, c, pos1);
if (c == 0 && count[1] == 0) giveShapeUpdate(level, mainState, pos1.relative(dir.getOpposite()), pos, dir.getOpposite());
}
private static void updateRails(PoweredRailBlock self, boolean eastWest, Level world,
private static void updateRails(PoweredRailBlock self, boolean eastWest, Level level,
BlockPos pos, BlockState mainState, int[] count) {
if (eastWest) {
for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
@@ -288,21 +298,21 @@ public class OptimizedPoweredRails {
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);
if (c == 0 && count[1] == 0) level.neighborChanged(p.relative(dir.getOpposite()), block, null);
neighborUpdateEnd(self, level, pos, countAmt, dir, block, c, p);
level.neighborChanged(p.below(), block, null);
level.neighborChanged(p.above(), block, null);
level.neighborChanged(p.north(), block, null);
level.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);
level.neighborChanged(pos2.below(), block, null);
level.neighborChanged(pos2.north(), block, null);
level.neighborChanged(pos2.south(), block, null);
if (c == countAmt) level.neighborChanged(pos.relative(dir, c + 1).below(), block, null);
if (c == 0 && count[1] == 0) level.neighborChanged(p.relative(dir.getOpposite()).below(), block, null);
}
for (int c = countAmt; c >= i; c--)
updateRailsSectionEastWestShape(self, world, pos, c, mainState, dir, count, countAmt);
updateRailsSectionEastWestShape(self, level, pos, c, mainState, dir, count, countAmt);
}
} else {
for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
@@ -312,21 +322,21 @@ public class OptimizedPoweredRails {
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);
level.neighborChanged(p.west(), block, null);
level.neighborChanged(p.east(), block, null);
level.neighborChanged(p.below(), block, null);
level.neighborChanged(p.above(), block, null);
neighborUpdateEnd(self, level, pos, countAmt, dir, block, c, p);
if (c == 0 && count[1] == 0) level.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);
level.neighborChanged(pos2.west(), block, null);
level.neighborChanged(pos2.east(), block, null);
level.neighborChanged(pos2.below(), block, null);
if (c == countAmt) level.neighborChanged(pos.relative(dir, c + 1).below(), block, null);
if (c == 0 && count[1] == 0) level.neighborChanged(p.relative(dir.getOpposite()).below(), block, null);
}
for (int c = countAmt; c >= i; c--)
updateRailsSectionNorthSouthShape(self, world, pos, c, mainState, dir, count, countAmt);
updateRailsSectionNorthSouthShape(self, level, pos, c, mainState, dir, count, countAmt);
}
}
}