Improve multi-level support and stairs

This commit is contained in:
2026-09-27 07:52:48 -07:00
parent 30c31c185b
commit 917dac9c8e
7 changed files with 276 additions and 46 deletions

View File

@@ -25,29 +25,64 @@ public final class AvenueStairwayLayout {
public static List<Step> centeredEastAvenue(
Cuboid plot, int roadWidth, int stairWidth, int lowerY, int rise) {
int plotLength = plot.maxZ - plot.minZ + 1;
if (roadWidth < 1
|| stairWidth < 1
|| stairWidth >= roadWidth
|| rise < 1
|| rise + 2 > plotLength) {
return stairBlocks(plot, roadWidth, stairWidth, lowerY, rise, Side.EAST);
}
public static List<Flight> forUpperRoadSegments(
Cuboid plot,
int plotSizeZ,
int gridSizeZ,
int firstBlockIndex,
int everyNBlocks,
int avenueWidth,
int stairWidth,
int lowerY,
int rise,
int openingLength) {
if (plotSizeZ < 1 || gridSizeZ < plotSizeZ || everyNBlocks < 1) {
return List.of();
}
int firstX = plot.maxX + 1 + (roadWidth - stairWidth) / 2;
int firstZ = plot.minZ + (plotLength - rise) / 2 + 1;
List<Step> steps = new ArrayList<>(stairWidth * rise);
for (int riseIndex = 0; riseIndex < rise; riseIndex++) {
for (int widthIndex = 0; widthIndex < stairWidth; widthIndex++) {
steps.add(new Step(firstX + widthIndex, lowerY + riseIndex + 1, firstZ + riseIndex));
List<Flight> flights = new ArrayList<>();
int segmentIndex = 0;
for (int segmentStart = plot.minZ;
segmentStart <= plot.maxZ;
segmentStart += gridSizeZ, segmentIndex++) {
int avenueBlockIndex = firstBlockIndex + segmentIndex;
if (Math.floorMod(avenueBlockIndex + 1, everyNBlocks) != 0) {
continue;
}
Cuboid segment =
new Cuboid(
plot.minX,
plot.minY,
segmentStart,
plot.maxX,
plot.maxY,
Math.min(segmentStart + plotSizeZ - 1, plot.maxZ));
for (Side side : Side.values()) {
List<Step> stairs = stairBlocks(segment, avenueWidth, stairWidth, lowerY, rise, side);
if (stairs.isEmpty()) {
continue;
}
List<Step> backings = invertedBackings(stairs, lowerY);
List<Step> openings =
upperRoadOpening(stairs, avenueWidth, stairWidth, lowerY, rise, openingLength);
flights.add(new Flight(stairs, backings, openings));
}
}
return List.copyOf(steps);
return List.copyOf(flights);
}
public static List<Step> upperRoadOpening(
Cuboid plot, int roadWidth, int stairWidth, int lowerY, int rise, int openingLength) {
List<Step> stairs = centeredEastAvenue(plot, roadWidth, stairWidth, lowerY, rise);
return upperRoadOpening(stairs, roadWidth, stairWidth, lowerY, rise, openingLength);
}
private static List<Step> upperRoadOpening(
List<Step> stairs, int roadWidth, int stairWidth, int lowerY, int rise, int openingLength) {
if (stairs.isEmpty() || openingLength < 1) {
return List.of();
}
@@ -71,17 +106,50 @@ public final class AvenueStairwayLayout {
return new Flight(List.of(), List.of(), List.of());
}
return new Flight(
stairs,
invertedBackings(stairs, lowerY),
upperRoadOpening(stairs, roadWidth, stairWidth, lowerY, rise, openingLength));
}
private static List<Step> invertedBackings(List<Step> stairs, int lowerY) {
List<Step> invertedBackings = new ArrayList<>();
for (Step stair : stairs) {
if (stair.y() > lowerY + 1) {
invertedBackings.add(new Step(stair.x(), stair.y() - 1, stair.z()));
}
}
return List.copyOf(invertedBackings);
}
return new Flight(
stairs,
invertedBackings,
upperRoadOpening(plot, roadWidth, stairWidth, lowerY, rise, openingLength));
private static List<Step> stairBlocks(
Cuboid plot, int roadWidth, int stairWidth, int lowerY, int rise, Side side) {
int plotLength = plot.maxZ - plot.minZ + 1;
if (roadWidth < 1
|| stairWidth < 1
|| stairWidth >= roadWidth
|| rise < 1
|| rise + 2 > plotLength) {
return List.of();
}
int firstX =
side == Side.EAST
? plot.maxX + 1 + (roadWidth - stairWidth) / 2
: plot.minX - roadWidth + (roadWidth - stairWidth) / 2;
int firstZ = plot.minZ + (plotLength - rise) / 2 + 1;
List<Step> steps = new ArrayList<>(stairWidth * rise);
for (int riseIndex = 0; riseIndex < rise; riseIndex++) {
for (int widthIndex = 0; widthIndex < stairWidth; widthIndex++) {
steps.add(new Step(firstX + widthIndex, lowerY + riseIndex + 1, firstZ + riseIndex));
}
}
return List.copyOf(steps);
}
public enum Side {
EAST,
WEST
}
public record Step(int x, int y, int z) {}