diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java index 2c13dd27..f245c201 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java @@ -86,9 +86,13 @@ public abstract class DynamicRegion implements Region { Set needsFullReset = new HashSet<>(); list.forEach(data -> { boolean previousGardenState = data.region().isGarden(); + PathSide previousToriState = data.region().getToriiSide(); data.region().calculateGardenState(); + data.region().calculateToriiState(); if (data.region().isGarden() != previousGardenState) { needsFullReset.add(data.region().getID()); + } else if (data.region().getToriiSide() != previousToriState) { + needsFullReset.add(data.region().getID()); } }); // Updating world state for all neighbouring PathRegions diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegionRepository.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegionRepository.java index 70ced2b4..753a3de8 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegionRepository.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegionRepository.java @@ -146,6 +146,7 @@ public class DynamicRegionRepository { DynamicRegionSystem.INSTANCE.getRegionsByType(RegionType.PATH) .forEach(region -> { ((PathRegion) region).calculateGardenState(); + ((PathRegion) region).calculateToriiState(); }); } diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathArea.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathArea.java index 85aa567b..ec3e6139 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathArea.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathArea.java @@ -29,7 +29,6 @@ import de.steamwar.bausystem.region.dynamic.DynamicRegion; import de.steamwar.bausystem.region.dynamic.PasteUtils; import de.steamwar.bausystem.region.dynamic.Tile; import de.steamwar.bausystem.region.dynamic.VariantSelector; -import de.steamwar.bausystem.region.dynamic.spawn.SpawnRegion; import de.steamwar.bausystem.shared.Pair; import de.steamwar.bausystem.utils.PasteBuilder; import de.steamwar.sql.SchematicNode; @@ -68,6 +67,10 @@ public class PathArea extends Region.Area { private static final VariantSelector CORNER_INNER_GARDEN = VariantSelector.Get(new File(PATH_DIR, "cinner/garden")); private static final VariantSelector CORNER_OUTER_GARDEN = VariantSelector.Get(new File(PATH_DIR, "couter/garden")); + private static final VariantSelector TORII_CENTER = VariantSelector.Schematic("Path", "Torii", "Center"); + private static final VariantSelector TORII_SIDE_VOID = VariantSelector.Schematic("Path", "Torii", "Edge_Void"); + private static final VariantSelector TORII_SIDE_WATER = VariantSelector.Schematic("Path", "Torii", "Edge_Water"); + private static final SelectorSide SELECTOR_SIDE = new SelectorSide() .Case(Path, CENTER) .Case(Void, SIDE_VOID) @@ -160,9 +163,16 @@ public class PathArea extends Region.Area { return true; } - public void reset(PathSide side) { + public void reset(PathSide side, boolean torii) { SchematicNode reset = null; VariantSelector selector = SELECTOR_SIDE.Select(tile, side); + if (torii) { + if (selector == SIDE_VOID) { + selector = TORII_SIDE_VOID; + } else if (selector == SIDE_WATER) { + selector = TORII_SIDE_WATER; + } + } if (selector != null) reset = selector.select().orElse(null); if (selector == null || reset == null) { if (!BauSystem.DEV_SERVER) return; @@ -205,19 +215,17 @@ public class PathArea extends Region.Area { public void place(PasteBuilder pasteBuilder, boolean extension) { if (region.isGarden()) { SchematicNode reset = GARDEN.select().orElse(null); - if (reset != null) { - PasteUtils.paste(reset, minPoint, 0); - } + if (reset != null) PasteUtils.paste(reset, minPoint, 0); return; } - SchematicNode reset = CENTER.select().orElse(null); + SchematicNode reset = (region.getToriiSide() != null ? TORII_CENTER : CENTER).select().orElse(null); if (reset != null) { - PasteUtils.paste(reset, minPoint.add(7, 0, 7), 0); + PasteUtils.paste(reset, minPoint.add(7, 0, 7), region.getToriiSide() != null ? region.getToriiSide().rotate : 0); } for (PathSide side : PathSide.values()) { - reset(side); + reset(side, region.getToriiSide() != null); } for (PathCorner corner : PathCorner.values()) { @@ -225,6 +233,45 @@ public class PathArea extends Region.Area { } } + protected PathSide getToriiSide() { + VariantSelector north = SELECTOR_SIDE.Select(tile, PathSide.North); + VariantSelector south = SELECTOR_SIDE.Select(tile, PathSide.South); + boolean zAxis = false; + if (isValidTorriVariantSelector(north) && isValidTorriVariantSelector(south)) { + zAxis = true; + } + + VariantSelector east = SELECTOR_SIDE.Select(tile, PathSide.East); + VariantSelector west = SELECTOR_SIDE.Select(tile, PathSide.West); + boolean xAxis = false; + if (isValidTorriVariantSelector(east) && isValidTorriVariantSelector(west)) { + xAxis = true; + } + + if (xAxis && zAxis) return null; + + VariantSelector northEast = SELECTOR_CORNER.Select(tile, PathCorner.NorthEast).getKey(); + if (!isValidTorriVariantSelector(northEast)) return null; + VariantSelector northWest = SELECTOR_CORNER.Select(tile, PathCorner.NorthWest).getKey(); + if (!isValidTorriVariantSelector(northWest)) return null; + VariantSelector southEast = SELECTOR_CORNER.Select(tile, PathCorner.SouthEast).getKey(); + if (!isValidTorriVariantSelector(southEast)) return null; + VariantSelector southWest = SELECTOR_CORNER.Select(tile, PathCorner.SouthWest).getKey(); + if (!isValidTorriVariantSelector(southWest)) return null; + + if (zAxis) { + return PathSide.North; + } else if (xAxis) { + return PathSide.West; + } else { + return null; + } + } + + private boolean isValidTorriVariantSelector(VariantSelector selector) { + return selector == SIDE_VOID || selector == SIDE_WATER; + } + protected static RegionType.ConnectionType getConnectionType(Tile source, PathSide side, PathSide optionalSide) { Optional optionalTile = source.add(side.tileOffsetX, side.tileOffsetZ); if (optionalSide != null) { diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathRegion.java index 5a6ff930..e858b9a5 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathRegion.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathRegion.java @@ -67,6 +67,7 @@ public class PathRegion extends DynamicRegion { area = new PathArea(tile, this); regionData = PathRegionData.INSTANCE; calculateGardenState(); + calculateToriiState(); } @Override @@ -75,7 +76,7 @@ public class PathRegion extends DynamicRegion { } @Override - public @org.jspecify.annotations.NonNull PathConnectResult shouldPathConnect(Tile source, PathSide side, boolean diagonal) { + public @NonNull PathConnectResult shouldPathConnect(Tile source, PathSide side, boolean diagonal) { if (diagonal) { // Needed for inner corners of Small Spawn if (!(Math.abs(source.getTileX()) == 2 && source.getTileZ() == 0) && !(source.getTileX() == 0 && Math.abs(source.getTileZ()) == 2)) { @@ -88,7 +89,7 @@ public class PathRegion extends DynamicRegion { public void update(DynamicRegion updateFrom, NeighbourDirection direction) { for (PathSide side : direction.getSideUpdates()) { - area.reset(side); + area.reset(side, toriiSide != null); } for (PathCorner corner : direction.getCornerUpdates()) { area.reset(corner); @@ -113,6 +114,17 @@ public class PathRegion extends DynamicRegion { garden = true; } + @Getter + private PathSide toriiSide = null; + + public void calculateToriiState() { + if ((Math.abs(tile.getTileX()) + Math.abs(tile.getTileZ())) % 2 == 0) { + toriiSide = null; + return; + } + toriiSide = area.getToriiSide(); + } + @Override public @NonNull RegionType getType() { return RegionType.PATH; diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java index c7e6fd02..cb4ad2d1 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnRegion.java @@ -79,7 +79,7 @@ public class SpawnRegion extends DynamicRegion { } @Override - public @org.jspecify.annotations.NonNull PathConnectResult shouldPathConnect(Tile source, PathSide side, boolean diagonal) { + public @NonNull PathConnectResult shouldPathConnect(Tile source, PathSide side, boolean diagonal) { if (diagonal) return PathConnectResult.BY_TYPE; return switch (side) { case North -> PathConnectResult.of(tile.equals(Tile.TILE_ZN), PathConnectResult.BY_TYPE);