Add editor for SpawnRegion

This commit is contained in:
2026-03-29 16:51:44 +02:00
parent bb85187434
commit 11056a2a8e
@@ -27,6 +27,7 @@ import de.steamwar.bausystem.region.dynamic.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository; import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData; import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.Tile; import de.steamwar.bausystem.region.dynamic.Tile;
import de.steamwar.bausystem.region.dynamic.spawn.SpawnRegion;
import de.steamwar.bausystem.utils.PasteBuilder; import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.core.SWPlayer; import de.steamwar.core.SWPlayer;
import de.steamwar.entity.CArea; import de.steamwar.entity.CArea;
@@ -156,6 +157,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener {
List<SWListInv.SWListEntry<Type>> list = new ArrayList<>(); List<SWListInv.SWListEntry<Type>> list = new ArrayList<>();
list.add(new SWListInv.SWListEntry<>(new SWItem(Material.BARRIER, "§cDelete"), new Delete())); 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() DynamicRegionSystem.constructorDataMap.values()
.stream() .stream()
@@ -236,18 +238,50 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener {
return "§cDelete"; 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 @Override
public boolean visualize(CArea area, int tileX, int tileZ) { public boolean visualize(CArea area, int tileX, int tileZ) {
// TODO: Special case for big Spawn!
Tile tile = Tile.fromTile(tileX, tileZ).orElse(null); Tile tile = Tile.fromTile(tileX, tileZ).orElse(null);
if (tile == null) { if (tile == null) {
valid = false; valid = false;
return false; return false;
} }
Region region = DynamicRegionSystem.INSTANCE.get(tile); Region region = DynamicRegionSystem.INSTANCE.get(tile);
if (region.getType().isGlobal() || region.getType().isSpawn()) { if (region.getType().isGlobal()) {
valid = false; valid = false;
return 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 minTile = Tile.fromPoint(region.getArea().getMinPoint(false)).orElse(null);
Tile maxTile = Tile.fromPoint(region.getArea().getMaxPoint(false)).orElse(null); Tile maxTile = Tile.fromPoint(region.getArea().getMaxPoint(false)).orElse(null);
if (minTile == null || maxTile == 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); Tile tile = Tile.fromTile(tileX, tileZ).orElse(null);
if (tile == null) return; if (tile == null) return;
Region region = DynamicRegionSystem.INSTANCE.get(tile); Region region = DynamicRegionSystem.INSTANCE.get(tile);
if (region.getType().isGlobal() || region.getType().isSpawn()) return; if (region.getType().isGlobal()) return;
if (region.getType().isPath()) { if (region.getType().isSpawn()) {
region.delete(); if (isBigSpawn()) deleteSpawn(player);
return; 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()); 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 -> { inventory.setItem(0, new SWItem(Material.GRAY_CONCRETE, "§7Cancel", click -> {
player.closeInventory(); player.closeInventory();
})); }));
inventory.setItem(8, new SWItem(Material.RED_CONCRETE, "§cDelete: " + data.name(), click -> { inventory.setItem(8, new SWItem(Material.RED_CONCRETE, "§cDelete: " + name, click -> {
Region checkRegion = DynamicRegionSystem.INSTANCE.get(tile);
if (region == checkRegion) region.delete();
player.closeInventory(); player.closeInventory();
deleteCallback.run();
})); }));
inventory.open(); 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 static class Place implements Type {
private final RegionConstructorData data; private final RegionConstructorData data;
private final int widthX; protected final int widthX;
private final int widthZ; protected final int widthZ;
private boolean valid = false; protected boolean valid = false;
private Place(@NonNull RegionConstructorData data) { 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.data = data;
this.widthX = data.widthX() - 1; this.widthX = widthX - 1;
this.widthZ = data.widthZ() - 1; this.widthZ = widthZ - 1;
} }
@Override @Override
@@ -308,7 +421,7 @@ public class DynamicRegionEditor implements SWPlayer.Component, Listener {
return "§ePlace§8: §a" + data.name(); 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 x = 0; x <= widthX; x++) {
for (int z = 0; z <= widthZ; z++) { for (int z = 0; z <= widthZ; z++) {
Tile tile = Tile.fromTile(tileX + x, tileZ + z).orElse(null); Tile tile = Tile.fromTile(tileX + x, tileZ + z).orElse(null);