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 7610e461..c4050b0b 100644 --- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java @@ -27,6 +27,7 @@ import de.steamwar.bausystem.region.dynamic.DynamicRegion; import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository; import de.steamwar.bausystem.region.dynamic.RegionConstructorData; import de.steamwar.bausystem.region.dynamic.Tile; +import de.steamwar.bausystem.region.dynamic.spawn.SpawnRegion; import de.steamwar.bausystem.utils.PasteBuilder; import de.steamwar.core.SWPlayer; import de.steamwar.entity.CArea; @@ -156,6 +157,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener { List> list = new ArrayList<>(); list.add(new SWListInv.SWListEntry<>(new SWItem(Material.BARRIER, "§cDelete"), new Delete())); + list.add(new SWListInv.SWListEntry<>(new SWItem(Material.LODESTONE, "§fBig Spawn"), new Spawn())); DynamicRegionSystem.constructorDataMap.values() .stream() @@ -236,18 +238,50 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener { return "§cDelete"; } + private boolean isBigSpawn() { + if (!DynamicRegionSystem.INSTANCE.get(Tile.ZERO).getType().isSpawn()) return false; + return Tile.ZERO.neighboursRing() + .map(DynamicRegionSystem.INSTANCE::get) + .map(Region::getType) + .allMatch(RegionType::isSpawn); + } + @Override public boolean visualize(CArea area, int tileX, int tileZ) { + // TODO: Special case for big Spawn! + Tile tile = Tile.fromTile(tileX, tileZ).orElse(null); if (tile == null) { valid = false; return false; } Region region = DynamicRegionSystem.INSTANCE.get(tile); - if (region.getType().isGlobal() || region.getType().isSpawn()) { + if (region.getType().isGlobal()) { valid = false; return false; } + + if (region.getType().isSpawn()) { + if (!isBigSpawn()) { + valid = false; + return false; + } + return selectSpawn(area); + } else { + return selectRegion(area, region); + } + } + + private boolean selectSpawn(CArea area) { + Location minLoc = new Location(null, -1, 1, -1); + Location maxLoc = new Location(null, 1, 1, 1); + area.setBlock(DELETE); + area.setPos1And2(minLoc, maxLoc); + valid = true; + return true; + } + + private boolean selectRegion(CArea area, Region region) { Tile minTile = Tile.fromPoint(region.getArea().getMinPoint(false)).orElse(null); Tile maxTile = Tile.fromPoint(region.getArea().getMaxPoint(false)).orElse(null); if (minTile == null || maxTile == null) { @@ -268,39 +302,118 @@ 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() || region.getType().isSpawn()) return; + if (region.getType().isGlobal()) return; - if (region.getType().isPath()) { - region.delete(); + if (region.getType().isSpawn()) { + if (isBigSpawn()) deleteSpawn(player); return; } + if (region.getType().isPath()) { + region.delete(); + } else { + deleteRegion(player, tile, region); + } + } + + private void deleteSpawn(Player player) { + confirmInventory(player, "Big Spawn", () -> { + checkSpawnRegionAndDelete(Tile.TILE_NN); + checkSpawnRegionAndDelete(Tile.TILE_NP); + checkSpawnRegionAndDelete(Tile.TILE_PN); + checkSpawnRegionAndDelete(Tile.TILE_PP); + }); + } + + private void checkSpawnRegionAndDelete(Tile tile) { + Region region = DynamicRegionSystem.INSTANCE.get(tile); + if (region.getType().isSpawn()) region.delete(); + } + + private void deleteRegion(Player player, Tile tile, Region region) { RegionConstructorData data = DynamicRegionSystem.constructorDataMap.get(region.getClass()); - SWInventory inventory = new SWInventory(player, 9, "Confirm delete: " + data.name()); + confirmInventory(player, data.name(), () -> { + Region checkRegion = DynamicRegionSystem.INSTANCE.get(tile); + if (region == checkRegion) region.delete(); + }); + } + + private void confirmInventory(Player player, String name, Runnable deleteCallback) { + SWInventory inventory = new SWInventory(player, 9, "Confirm delete: " + name); inventory.setItem(0, new SWItem(Material.GRAY_CONCRETE, "§7Cancel", click -> { player.closeInventory(); })); - inventory.setItem(8, new SWItem(Material.RED_CONCRETE, "§cDelete: " + data.name(), click -> { - Region checkRegion = DynamicRegionSystem.INSTANCE.get(tile); - if (region == checkRegion) region.delete(); + inventory.setItem(8, new SWItem(Material.RED_CONCRETE, "§cDelete: " + name, click -> { player.closeInventory(); + deleteCallback.run(); })); inventory.open(); } } + private static class Spawn extends Place { + + private Spawn() { + super(3, 3); + } + + @Override + public String title() { + return "§ePlace§8: §aBig Spawn"; + } + + @Override + public boolean validPlacement(int tileX, int tileZ) { + if (tileX != -1 || tileZ != -1) return false; + if (!DynamicRegionSystem.INSTANCE.get(Tile.TILE_NN).getType().isGlobal()) return false; + if (!DynamicRegionSystem.INSTANCE.get(Tile.TILE_NP).getType().isGlobal()) return false; + if (!DynamicRegionSystem.INSTANCE.get(Tile.TILE_PN).getType().isGlobal()) return false; + if (!DynamicRegionSystem.INSTANCE.get(Tile.TILE_PP).getType().isGlobal()) return false; + return true; + } + + @Override + public void run(Player player, int tileX, int tileZ) { + if (!valid) return; + // Center Tile placement! + tileX -= widthX / 2; + tileZ -= widthZ / 2; + if (!validPlacement(tileX, tileZ)) return; + + constructSpawnRegion(Tile.TILE_NN); + constructSpawnRegion(Tile.TILE_NP); + constructSpawnRegion(Tile.TILE_PN); + constructSpawnRegion(Tile.TILE_PP); + } + + private void constructSpawnRegion(Tile tile) { + DynamicRegion region = DynamicRegionRepository.constructRegion(SpawnRegion.class, tile); + if (region == null) return; + region.getArea().place(new PasteBuilder(), false); + region.updateNeighbours(); + } + } + private static class Place implements Type { private final RegionConstructorData data; - private final int widthX; - private final int widthZ; + protected final int widthX; + protected final int widthZ; - private boolean valid = false; + protected boolean valid = false; private Place(@NonNull RegionConstructorData data) { + this(data, data.widthX(), data.widthZ()); + } + + private Place(int widthX, int widthZ) { + this(null, widthX, widthZ); + } + + private Place(RegionConstructorData data, int widthX, int widthZ) { this.data = data; - this.widthX = data.widthX() - 1; - this.widthZ = data.widthZ() - 1; + this.widthX = widthX - 1; + this.widthZ = widthZ - 1; } @Override @@ -308,7 +421,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener { return "§ePlace§8: §a" + data.name(); } - private boolean validPlacement(int tileX, int tileZ) { + public boolean validPlacement(int tileX, int tileZ) { for (int x = 0; x <= widthX; x++) { for (int z = 0; z <= widthZ; z++) { Tile tile = Tile.fromTile(tileX + x, tileZ + z).orElse(null);