diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java index cc64cd5c..7610e461 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java @@ -178,7 +178,6 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener { Vector direction = player.getLocation().getDirection(); RayAabIntersection intersection = new RayAabIntersection((float) startPos.getX(), (float) startPos.getY(), (float) startPos.getZ(), (float) direction.getX(), (float) direction.getY(), (float) direction.getZ()); - boolean hide = true; for (RInteraction interaction : entityServer.getEntitiesByType(RInteraction.class)) { float x = (float) (interaction.getX() - 0.5); float z = (float) (interaction.getZ() - 0.5); @@ -186,12 +185,14 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener { int tileX = (int) x; int tileZ = (int) z; if (type.visualize(area, tileX, tileZ)) { - hide = false; + area.hide(false); + return; + } else { break; } } } - area.hide(hide); + area.hide(true); } @EventHandler @@ -243,7 +244,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener { return false; } Region region = DynamicRegionSystem.INSTANCE.get(tile); - if (region.getType().isGlobal()) { + if (region.getType().isGlobal() || region.getType().isSpawn()) { valid = false; return false; } @@ -267,7 +268,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener { Tile tile = Tile.fromTile(tileX, tileZ).orElse(null); if (tile == null) return; Region region = DynamicRegionSystem.INSTANCE.get(tile); - if (region.getType().isGlobal()) return; + if (region.getType().isGlobal() || region.getType().isSpawn()) return; if (region.getType().isPath()) { region.delete(); diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java index 2c3a6808..70c4eed9 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java @@ -24,8 +24,6 @@ import de.steamwar.bausystem.features.region.WireframeCommand; import de.steamwar.bausystem.region.dynamic.*; import de.steamwar.bausystem.region.dynamic.global.GlobalRegion; import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import lombok.ToString; import org.bukkit.Bukkit; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; @@ -158,33 +156,27 @@ public class DynamicRegionSystem implements RegionSystem { return regionTypeMap.getOrDefault(type, Collections.emptySet()).stream(); } - @RequiredArgsConstructor - @ToString - public static class Neighbour { - public final T region; - public final Tile tile; - public final NeighbourDirection direction; + public record Neighbour(T region, Tile tile, NeighbourDirection direction) { + public Neighbour as(Class clazz) { + if (!clazz.isInstance(region)) { + return null; + } else { + return (Neighbour) this; + } + } - public Neighbour as(Class clazz) { - if (!clazz.isInstance(region)) { - return null; - } else { - return (Neighbour) this; + @Override + public boolean equals(Object o) { + if (!(o instanceof Neighbour neighbour)) return false; + return Objects.equals(tile, neighbour.tile) && direction == neighbour.direction; + } + + @Override + public int hashCode() { + return Objects.hash(tile, direction); } } - @Override - public boolean equals(Object o) { - if (!(o instanceof Neighbour neighbour)) return false; - return Objects.equals(tile, neighbour.tile) && direction == neighbour.direction; - } - - @Override - public int hashCode() { - return Objects.hash(tile, direction); - } - } - private Stream> getNeighbours(Region region, boolean noCorners, boolean fastCache, Collection regions) { Tile minTile = Tile.fromPoint(region.getArea().getMinPoint(false)).orElse(null); Tile maxTile = Tile.fromPoint(region.getArea().getMaxPoint(false)).orElse(null); 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 7edafe34..bd959a8f 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 @@ -84,18 +84,18 @@ public abstract class DynamicRegion implements Region { // Calculate Garden State for all neighbouring PathRegions Set needsFullReset = new HashSet<>(); list.forEach(data -> { - boolean previousGardenState = data.region.isGarden(); - data.region.calculateGardenState(); - if (data.region.isGarden() != previousGardenState) { - needsFullReset.add(data.region.getID()); + boolean previousGardenState = data.region().isGarden(); + data.region().calculateGardenState(); + if (data.region().isGarden() != previousGardenState) { + needsFullReset.add(data.region().getID()); } }); // Updating world state for all neighbouring PathRegions list.forEach(data -> { - if (needsFullReset.contains(data.region.getID())) { - data.region.getArea().reset(new PasteBuilder(), false); + if (needsFullReset.contains(data.region().getID())) { + data.region().getArea().reset(new PasteBuilder(), false); } else { - data.region.update(this, data.direction.opposite()); + data.region().update(this, data.direction().opposite()); } }); // All full reset regions need to update their neighbours! @@ -106,8 +106,8 @@ public abstract class DynamicRegion implements Region { .map(neighbour -> neighbour.as(PathRegion.class)) .filter(Objects::nonNull) .forEach(data -> { - if (data.region.isGarden()) return; - data.region.update(dynamicRegion, data.direction.opposite()); + if (data.region().isGarden()) return; + data.region().update(dynamicRegion, data.direction().opposite()); }); }); } diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java index 6055543f..50144e59 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java @@ -33,6 +33,18 @@ import java.util.stream.Stream; @EqualsAndHashCode public class Tile { + public static final Tile ZERO = new Tile(0, 0); + + public static final Tile TILE_PZ = new Tile(1, 0); + public static final Tile TILE_NZ = new Tile(-1, 0); + public static final Tile TILE_ZP = new Tile(0, 1); + public static final Tile TILE_ZN = new Tile(0, -1); + + public static final Tile TILE_PP = new Tile(1, 1); + public static final Tile TILE_PN = new Tile(1, -1); + public static final Tile TILE_NP = new Tile(-1, 1); + public static final Tile TILE_NN = new Tile(-1, -1); + public static final int tileSize = 21; public static final int tileOffset = tileSize / 2; public static final int maxTile = 127; 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 cee9034a..250d73d8 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 @@ -28,6 +28,7 @@ import de.steamwar.bausystem.region.RegionType; 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 lombok.NonNull; @@ -220,19 +221,30 @@ public class PathArea extends Region.Area { } } - protected static RegionType.ConnectionType getConnectionType(Tile tile, PathSide side, PathSide optionalSide) { + protected static RegionType.ConnectionType getConnectionType(Tile tile, PathSide side, PathSide optionalSide, RegionType.ConnectionType spawnPathConnection) { Optional optionalTile = tile.add(side.tileOffsetX, side.tileOffsetZ); if (optionalSide != null) { optionalTile = optionalTile.flatMap(t -> t.add(optionalSide.tileOffsetX, optionalSide.tileOffsetZ)); } if (optionalTile.isEmpty()) { - return RegionType.ConnectionType.Global; + return Global; } tile = optionalTile.get(); - Region region = DynamicRegionSystem.INSTANCE.get(tile.getCenterLocation()); + Region region = DynamicRegionSystem.INSTANCE.get(tile); if (region instanceof PathRegion pathRegion) { return pathRegion.isGarden() ? Garden : Path; } + if (region instanceof SpawnRegion spawnRegion) { + if (optionalSide == null && side.opposite().equals(spawnRegion.getPathSide())) { + return spawnPathConnection; + } else { + return Closed; + } + } return region.getType().getConnectionType(); } + + protected static RegionType.ConnectionType getConnectionType(Tile tile, PathSide side, PathSide optionalSide) { + return getConnectionType(tile, side, optionalSide, Path); + } } 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 741f7706..83fc1d69 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 @@ -86,12 +86,15 @@ public class PathRegion extends DynamicRegion { public void calculateGardenState() { garden = false; - Set neighbours = tile.neighboursRing().collect(Collectors.toSet()); - if (neighbours.size() != 8) return; - garden = neighbours.stream() - .map(DynamicRegionSystem.INSTANCE::get) - .map(Region::getType) - .allMatch(RegionType::isPath); + for (PathSide pathSide : PathSide.values()) { + RegionType.ConnectionType connectionType = PathArea.getConnectionType(tile, pathSide, null, null); + if (connectionType != RegionType.ConnectionType.Path && connectionType != RegionType.ConnectionType.Garden) return; + } + for (PathCorner pathCorner : PathCorner.values()) { + RegionType.ConnectionType connectionType = PathArea.getConnectionType(tile, pathCorner.side1, pathCorner.side2, null); + if (connectionType != RegionType.ConnectionType.Path && connectionType != RegionType.ConnectionType.Garden) return; + } + garden = true; } @Override diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathSide.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathSide.java index 7f73fb1b..3ce57ca6 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathSide.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/PathSide.java @@ -34,4 +34,13 @@ public enum PathSide { public final int pasteOffsetX; public final int pasteOffsetZ; public final int rotate; + + public PathSide opposite() { + return switch (this) { + case North -> South; + case South -> North; + case East -> West; + case West -> East; + }; + } } diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/SelectorCorner.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/SelectorCorner.java index b374a99a..6dbb2dfb 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/SelectorCorner.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/path/SelectorCorner.java @@ -59,8 +59,8 @@ class SelectorCorner { } public Pair Select(Tile tile, PathCorner corner) { - RegionType.ConnectionType left = PathArea.getConnectionType(tile, corner.side1, null); - RegionType.ConnectionType right = PathArea.getConnectionType(tile, corner.side2, null); + RegionType.ConnectionType left = PathArea.getConnectionType(tile, corner.side1, null, RegionType.ConnectionType.Closed); + RegionType.ConnectionType right = PathArea.getConnectionType(tile, corner.side2, null, RegionType.ConnectionType.Closed); RegionType.ConnectionType diagonal = PathArea.getConnectionType(tile, corner.side1, corner.side2); int index = getIndex(left, right, diagonal); return new Pair<>(selectors[index], rotationCorrections[index]); diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnArea.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnArea.java index 4318e8e5..02e8b23a 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnArea.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/spawn/SpawnArea.java @@ -19,32 +19,56 @@ package de.steamwar.bausystem.region.dynamic.spawn; +import de.steamwar.bausystem.region.DynamicRegionSystem; import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.RegionType; +import de.steamwar.bausystem.region.dynamic.DynamicRegion; +import de.steamwar.bausystem.region.dynamic.Tile; import de.steamwar.bausystem.utils.PasteBuilder; import lombok.NonNull; +import java.util.List; + public class SpawnArea extends Region.Area { + private final Tile tile; + + public SpawnArea(Tile tile) { + this.tile = tile; + } + @Override public @NonNull Point getMinPoint(boolean extension) { - return null; + return Point.fromLocation(tile.getMinLocation()); } @Override public @NonNull Point getMaxPoint(boolean extension) { - return null; + return Point.fromLocation(tile.getMaxLocation()); } @Override public @NonNull Point getCopyPoint(boolean extension) { - return null; + return Point.ZERO; } @Override public void reset(PasteBuilder pasteBuilder, boolean extension) { - // TODO: Implement! - super.reset(pasteBuilder, extension); + List regions = DynamicRegionSystem.INSTANCE.getNeighbours(DynamicRegionSystem.INSTANCE.get(Tile.ZERO)) + .map(DynamicRegionSystem.Neighbour::region) + .toList(); + + if (regions.stream().map(DynamicRegion::getType).allMatch(RegionType::isSpawn)) { + // TODO: Implement big spawn! + return; + } + + for (DynamicRegion region : regions) { + if (region.getArea() instanceof SpawnArea spawnArea) { + spawnArea.place(new PasteBuilder(), false); + } + } } @Override 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 dc1d3c0e..2e830de5 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 @@ -25,20 +25,39 @@ import de.steamwar.bausystem.region.RegionBackups; import de.steamwar.bausystem.region.RegionHistory; import de.steamwar.bausystem.region.RegionType; import de.steamwar.bausystem.region.dynamic.DynamicRegion; +import de.steamwar.bausystem.region.dynamic.RegionConstructorData; import de.steamwar.bausystem.region.dynamic.Tile; import de.steamwar.bausystem.region.dynamic.TileUtils; import de.steamwar.bausystem.region.dynamic.path.PathRegionData; +import de.steamwar.bausystem.region.dynamic.path.PathSide; import de.steamwar.sql.GameModeConfig; +import lombok.Getter; import lombok.NonNull; import org.bukkit.Material; import java.io.IOException; import java.util.UUID; +@RegionConstructorData( + identifier = "spawn", + name = "Spawn", + widthX = SpawnRegion.TILE_X, + widthZ = SpawnRegion.TILE_Z, + material = Material.LODESTONE, + placeable = false +) public class SpawnRegion extends DynamicRegion { + protected static final int TILE_X = 1; + protected static final int TILE_Z = 1; + + @Getter private final Tile tile; + @Getter + private final PathSide pathSide; + private final SpawnArea area; + public SpawnRegion(Tile tile) { this(UUID.randomUUID(), tile); finishCreate(); @@ -52,8 +71,19 @@ public class SpawnRegion extends DynamicRegion { private SpawnRegion(UUID id, Tile tile) { super(id, null); this.tile = tile; + if (tile.equals(Tile.TILE_PZ)) { + pathSide = PathSide.East; + } else if (tile.equals(Tile.TILE_NZ)) { + pathSide = PathSide.West; + } else if (tile.equals(Tile.TILE_ZP)) { + pathSide = PathSide.South; + } else if (tile.equals(Tile.TILE_ZN)) { + pathSide = PathSide.North; + } else { + pathSide = null; + } + area = new SpawnArea(tile); regionData = PathRegionData.INSTANCE; - // TODO: Initialize } @Override @@ -63,12 +93,18 @@ public class SpawnRegion extends DynamicRegion { @Override public @NonNull RegionType getType() { - return RegionType.SPAWN; + if (tile.equals(Tile.ZERO)) { + return RegionType.SPAWN; + } else if (pathSide != null) { + return RegionType.SPAWN_PATH; + } else { + return RegionType.SPAWN_EXTENSION; + } } @Override public @NonNull Area getArea() { - return null; + return area; } @Override