diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionCommand.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionCommand.java
index 064179b5..b0e7c6e5 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionCommand.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionCommand.java
@@ -36,15 +36,15 @@ public class DynamicRegionCommand extends SWCommand {
@Register({"dynamic"})
public void visualizeRegions(Player player) {
- Tile tile = Tile.fromLocation(player.getLocation()).orElse(null);
- if (tile == null) return;
SWPlayer swPlayer = SWPlayer.of(player);
if (swPlayer.hasComponent(DynamicRegionVisualizer.class)) {
swPlayer.removeComponent(DynamicRegionVisualizer.class);
- } else if (Permission.SUPERVISOR.hasPermission(player)) {
- swPlayer.setComponent(new DynamicRegionVisualizer());
+ swPlayer.removeComponent(DynamicRegionEditor.class);
} else {
- // TODO: Add Message
+ swPlayer.setComponent(DynamicRegionVisualizer.INSTANCE);
+ if (Permission.SUPERVISOR.hasPermission(player)) {
+ swPlayer.setComponent(new DynamicRegionEditor(player.getPlayer()));
+ }
}
}
}
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java
new file mode 100644
index 00000000..7ac91e95
--- /dev/null
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionEditor.java
@@ -0,0 +1,354 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2026 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bausystem.region;
+
+import com.comphenix.tinyprotocol.TinyProtocol;
+import de.steamwar.Reflection;
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.Permission;
+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.utils.PasteBuilder;
+import de.steamwar.core.SWPlayer;
+import de.steamwar.entity.CArea;
+import de.steamwar.entity.REntityServer;
+import de.steamwar.entity.RInteraction;
+import de.steamwar.inventory.SWInventory;
+import de.steamwar.inventory.SWItem;
+import de.steamwar.inventory.SWListInv;
+import lombok.NonNull;
+import net.md_5.bungee.api.ChatMessageType;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.event.player.PlayerSwapHandItemsEvent;
+import org.bukkit.scheduler.BukkitTask;
+import org.bukkit.util.Vector;
+import org.joml.RayAabIntersection;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class DynamicRegionEditor implements SWPlayer.Component, Listener {
+
+ private static final Class> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
+ private static final Class> look = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
+ private static final Class> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
+
+ static {
+ BiFunction function = (player, object) -> {
+ SWPlayer.of(player).getComponent(DynamicRegionEditor.class).ifPresent(DynamicRegionEditor::calcCursor);
+ return object;
+ };
+ TinyProtocol.instance.addFilter(position, function);
+ TinyProtocol.instance.addFilter(look, function);
+ TinyProtocol.instance.addFilter(positionLook, function);
+ }
+
+ private final REntityServer entityServer = new REntityServer();
+ private final CArea area = new CArea(entityServer);
+
+ private static final BlockData DELETE = Material.RED_CONCRETE.createBlockData();
+ private static final BlockData INVALID = Material.YELLOW_CONCRETE.createBlockData();
+ private static final BlockData PLACE = Material.LIME_CONCRETE.createBlockData();
+
+ {
+ area.hide(true);
+ }
+
+ private final Player player;
+
+ private final BukkitTask task;
+ private Type type = new Delete();
+
+ public DynamicRegionEditor(Player player) {
+ this.player = player;
+ entityServer.addPlayer(player);
+
+ Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
+
+ for (int i = 0; i < 121; i++) {
+ new RInteraction(entityServer, player.getLocation());
+ }
+ moveInteractionEntities(Point.fromLocation(player.getLocation()));
+
+ CArea area = new CArea(entityServer);
+ area.setPos1And2(new Location(null, -Tile.maxTile, 1, -Tile.maxTile), new Location(null, Tile.maxTile, 1, Tile.maxTile));
+ area.setBlock(Material.BEDROCK.createBlockData());
+
+ task = Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), this::showHotbar, 0, 20);
+ }
+
+ private void showHotbar() {
+ entityServer.tick();
+
+ StringBuilder st = new StringBuilder();
+ st.append(type.title());
+ st.append(" §8(§7Change with §eSwap Hands§8)");
+ player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(st.toString()));
+ }
+
+ @Override
+ public void onUnmount(SWPlayer player) {
+ entityServer.close();
+ task.cancel();
+ PlayerMoveEvent.getHandlerList().unregister(this);
+ }
+
+ @EventHandler
+ public void onPlayerMove(PlayerMoveEvent event) {
+ if (event.getPlayer() != player) return;
+ if (!Permission.SUPERVISOR.hasPermission(player)) {
+ SWPlayer.of(player).removeComponent(DynamicRegionEditor.class);
+ return;
+ }
+ if (event.getTo() == null) return;
+ if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
+ return;
+ }
+ moveInteractionEntities(Point.fromLocation(event.getTo()));
+ }
+
+ private void moveInteractionEntities(Point position) {
+ List interactionList = entityServer.getEntitiesByType(RInteraction.class);
+ for (int x = -5; x <= 5; x++) {
+ for (int z = -5; z <= 5; z++) {
+ interactionList.removeFirst().move(position.getX() + x + 0.5, 0, position.getZ() + z + 0.5, 0, 0, (byte) 0);
+ }
+ }
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
+ event.setCancelled(true);
+
+ List> list = new ArrayList<>();
+ list.add(new SWListInv.SWListEntry<>(new SWItem(Material.BARRIER, "§cDelete"), new Delete()));
+
+ DynamicRegionSystem.constructorDataMap.values()
+ .stream()
+ .sorted(Comparator.comparing(RegionConstructorData::name))
+ .forEach(data -> {
+ list.add(new SWListInv.SWListEntry<>(new SWItem(data.material(), "§f" + data.name()), new Place(data)));
+ });
+
+ SWListInv inventory = new SWListInv<>(player, "Select Region to place", list, (click, type) -> {
+ this.type = type;
+ player.closeInventory();
+ showHotbar();
+ });
+ inventory.open();
+ }
+
+ private void calcCursor() {
+ Location startPos = player.getLocation().clone().add(0.0, player.getEyeHeight(), 0.0);
+ 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);
+ if (intersection.test(x, (float) 0.95, z, x + 1, (float) 1.05, z + 1)) {
+ int tileX = (int) x;
+ int tileZ = (int) z;
+ if (type.visualize(area, tileX, tileZ)) {
+ hide = false;
+ break;
+ }
+ }
+ }
+ area.hide(hide);
+ }
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ Location startPos = player.getLocation().clone().add(0.0, player.getEyeHeight(), 0.0);
+ Vector direction = player.getLocation().getDirection();
+ if (direction.getY() > 0) return;
+
+ RayAabIntersection intersection = new RayAabIntersection((float) startPos.getX(), (float) startPos.getY(), (float) startPos.getZ(), (float) direction.getX(), (float) direction.getY(), (float) direction.getZ());
+ for (RInteraction interaction : entityServer.getEntitiesByType(RInteraction.class)) {
+ float x = (float) (interaction.getX() - 0.5);
+ float z = (float) (interaction.getZ() - 0.5);
+ if (intersection.test(x, (float) 0.95, z, x + 1, (float) 1.05, z + 1)) {
+ int tileX = (int) x;
+ int tileZ = (int) z;
+ type.run(event.getPlayer(), tileX, tileZ);
+ break;
+ }
+ }
+ }
+
+ private interface Type {
+
+ String title();
+
+ boolean visualize(CArea area, int tileX, int tileZ);
+
+ void run(Player player, int tileX, int tileZ);
+ }
+
+ private static class Delete implements Type {
+
+ private boolean valid = false;
+
+ private Delete() {
+ }
+
+ @Override
+ public String title() {
+ return "§cDelete";
+ }
+
+ @Override
+ public boolean visualize(CArea area, int tileX, int tileZ) {
+ 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()) {
+ valid = false;
+ return false;
+ }
+ 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) {
+ valid = false;
+ return false;
+ }
+ Location minLoc = new Location(null, minTile.getTileX(), 1, minTile.getTileZ());
+ Location maxLoc = new Location(null, maxTile.getTileX(), 1, maxTile.getTileZ());
+ area.setBlock(DELETE);
+ area.setPos1And2(minLoc, maxLoc);
+ valid = true;
+ return true;
+ }
+
+ @Override
+ public void run(Player player, int tileX, int tileZ) {
+ if (!valid) return;
+ 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().isPath()) {
+ region.delete();
+ return;
+ }
+
+ RegionConstructorData data = DynamicRegionSystem.constructorDataMap.get(region.getClass());
+ SWInventory inventory = new SWInventory(player, 9, "Confirm delete: " + data.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();
+ player.closeInventory();
+ }));
+ inventory.open();
+ }
+ }
+
+ private static class Place implements Type {
+
+ private final RegionConstructorData data;
+ private final int widthX;
+ private final int widthZ;
+
+ private boolean valid = false;
+
+ private Place(@NonNull RegionConstructorData data) {
+ this.data = data;
+ this.widthX = data.widthX() - 1;
+ this.widthZ = data.widthZ() - 1;
+ }
+
+ @Override
+ public String title() {
+ return "§ePlace§8: §a" + data.name();
+ }
+
+ private 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);
+ if (tile == null) return false;
+ Region region = DynamicRegionSystem.INSTANCE.get(tile);
+ if (!region.getType().isGlobal()) return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean visualize(CArea area, int tileX, int tileZ) {
+ Tile tile = Tile.fromTile(tileX, tileZ).orElse(null);
+ if (tile == null) {
+ valid = false;
+ return false;
+ }
+ // Center Tile placement!
+ tileX -= widthX / 2;
+ tileZ -= widthZ / 2;
+ // Validate placements!
+ if (validPlacement(tileX, tileZ)) {
+ area.setBlock(PLACE);
+ valid = true;
+ } else {
+ area.setBlock(INVALID);
+ valid = false;
+ }
+ area.setPos1And2(new Location(null, tileX, 1, tileZ), new Location(null, tileX + widthX, 1, tileZ + widthZ));
+ 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;
+ Tile tile = Tile.fromTile(tileX, tileZ).orElse(null);
+ if (tile == null) return;
+ DynamicRegion region = DynamicRegionRepository.constructRegion(DynamicRegionSystem.identifierDataMap.get(data.identifier()), tile);
+ if (region == null) return;
+ region.getArea().place(new PasteBuilder(), false);
+ region.updateNeighbours();
+ }
+ }
+}
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 22e0f8c8..199975c6 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java
@@ -56,12 +56,14 @@ public class DynamicRegionSystem implements RegionSystem {
regionCache.clear();
regionMap.put(region.getID(), region);
regionTypeMap.computeIfAbsent(region.getType(), __ -> new HashSet<>()).add(region);
+ DynamicRegionVisualizer.INSTANCE.addRegion(region);
}
public void remove(DynamicRegion region) {
regionCache.clear();
regionMap.remove(region.getID());
regionTypeMap.getOrDefault(region.getType(), Collections.emptySet()).remove(region);
+ DynamicRegionVisualizer.INSTANCE.removeRegion(region);
}
public static Map, RegionConstructorData> constructorDataMap = new HashMap<>();
@@ -197,31 +199,37 @@ public class DynamicRegionSystem implements RegionSystem {
Set> neighbours = new HashSet<>();
if (!noCorners) {
- neighbours.add(new Neighbour<>(get(minTile.add(-1, -1).orElseThrow(), fastCache, regions), minTile, NeighbourDirection.NorthWest));
+ neighbours.add(new Neighbour<>(get(minTile.add(-1, -1).orElse(null), fastCache, regions), minTile, NeighbourDirection.NorthWest));
- Tile cornerMinMaxSelf = Tile.fromTile(minTile.getTileX(), maxTile.getTileZ()).orElseThrow();
- neighbours.add(new Neighbour<>(get(cornerMinMaxSelf.add(-1, 1).orElseThrow(), fastCache, regions), cornerMinMaxSelf, NeighbourDirection.SouthWest));
+ Tile.fromTile(minTile.getTileX(), maxTile.getTileZ()).ifPresent(cornerMinMaxSelf -> {
+ neighbours.add(new Neighbour<>(get(cornerMinMaxSelf.add(-1, 1).orElse(null), fastCache, regions), cornerMinMaxSelf, NeighbourDirection.SouthWest));
+ });
- Tile cornerMaxMinSelf = Tile.fromTile(maxTile.getTileX(), minTile.getTileZ()).orElseThrow();
- neighbours.add(new Neighbour<>(get(cornerMaxMinSelf.add(1, -1).orElseThrow(), fastCache, regions), cornerMaxMinSelf, NeighbourDirection.NorthEast));
+ Tile.fromTile(maxTile.getTileX(), minTile.getTileZ()).ifPresent(cornerMaxMinSelf -> {
+ neighbours.add(new Neighbour<>(get(cornerMaxMinSelf.add(1, -1).orElse(null), fastCache, regions), cornerMaxMinSelf, NeighbourDirection.NorthEast));
+ });
- neighbours.add(new Neighbour<>(get(maxTile.add(1, 1).orElseThrow(), fastCache, regions), maxTile, NeighbourDirection.SouthEast));
+ neighbours.add(new Neighbour<>(get(maxTile.add(1, 1).orElse(null), fastCache, regions), maxTile, NeighbourDirection.SouthEast));
}
for (int x = minTile.getTileX(); x <= maxTile.getTileX(); x++) {
- Tile tileMinZSelf = Tile.fromTile(x, minTile.getTileZ()).orElseThrow();
- neighbours.add(new Neighbour<>(get(tileMinZSelf.add(0, -1).orElseThrow(), fastCache, regions), tileMinZSelf, NeighbourDirection.North));
+ Tile.fromTile(x, minTile.getTileZ()).ifPresent(tileMinZSelf -> {
+ neighbours.add(new Neighbour<>(get(tileMinZSelf.add(0, -1).orElse(null), fastCache, regions), tileMinZSelf, NeighbourDirection.North));
+ });
- Tile tileMaxZSelf = Tile.fromTile(x, maxTile.getTileZ()).orElseThrow();
- neighbours.add(new Neighbour<>(get(tileMaxZSelf.add(0, 1).orElseThrow(), fastCache, regions), tileMaxZSelf, NeighbourDirection.South));
+ Tile.fromTile(x, maxTile.getTileZ()).ifPresent(tileMaxZSelf -> {
+ neighbours.add(new Neighbour<>(get(tileMaxZSelf.add(0, 1).orElse(null), fastCache, regions), tileMaxZSelf, NeighbourDirection.South));
+ });
}
for (int z = minTile.getTileZ(); z <= maxTile.getTileZ(); z++) {
- Tile tileMinXSelf = Tile.fromTile(minTile.getTileX(), z).orElseThrow();
- neighbours.add(new Neighbour<>(get(tileMinXSelf.add(-1, 0).orElseThrow(), fastCache, regions), tileMinXSelf, NeighbourDirection.West));
+ Tile.fromTile(minTile.getTileX(), z).ifPresent(tileMinXSelf -> {
+ neighbours.add(new Neighbour<>(get(tileMinXSelf.add(-1, 0).orElse(null), fastCache, regions), tileMinXSelf, NeighbourDirection.West));
+ });
- Tile tileMaxXSelf = Tile.fromTile(maxTile.getTileX(), z).orElseThrow();
- neighbours.add(new Neighbour<>(get(tileMaxXSelf.add(1, 0).orElseThrow(), fastCache, regions), tileMaxXSelf, NeighbourDirection.East));
+ Tile.fromTile(maxTile.getTileX(), z).ifPresent(tileMaxXSelf -> {
+ neighbours.add(new Neighbour<>(get(tileMaxXSelf.add(1, 0).orElse(null), fastCache, regions), tileMaxXSelf, NeighbourDirection.East));
+ });
}
neighbours.removeIf(neighbour -> neighbour.region.getType().isGlobal());
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionVisualizer.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionVisualizer.java
index 160e1a0b..994dbc4e 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionVisualizer.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionVisualizer.java
@@ -19,313 +19,96 @@
package de.steamwar.bausystem.region;
-import de.steamwar.bausystem.BauSystem;
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.utils.PasteBuilder;
import de.steamwar.core.SWPlayer;
import de.steamwar.entity.*;
-import de.steamwar.inventory.SWInventory;
-import de.steamwar.inventory.SWItem;
-import de.steamwar.inventory.SWListInv;
-import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.World;
+import org.bukkit.entity.Display;
+import org.bukkit.util.Transformation;
+import org.joml.Quaternionf;
+import org.joml.Vector3f;
-import java.util.*;
-import java.util.stream.Collectors;
+public class DynamicRegionVisualizer implements SWPlayer.Component {
-public class DynamicRegionVisualizer implements SWPlayer.Component, Listener {
+ public static final DynamicRegionVisualizer INSTANCE = new DynamicRegionVisualizer();
- private final REntityServer entityServer;
- private Player player;
- private Location sourceLocation;
- private Tile sourceTile;
+ private final REntityServer entityServer = new REntityServer();
- private Placement placement = null;
+ private DynamicRegionVisualizer() {
+ RTextDisplay text = new RTextDisplay(entityServer, new Location(null, 0.5, 1.1, 0.5));
+ text.setText("Spawn");
+ text.setBillboard(Display.Billboard.VERTICAL);
+ text.setBackgroundColor(0);
+ text.setShadowed(false);
+ text.setTransform(new Transformation(new Vector3f(0, 0, 0), new Quaternionf().rotationX((float) Math.toRadians(270)), new Vector3f(1, 1, 1), new Quaternionf()));
+ }
- public DynamicRegionVisualizer() {
- this.entityServer = new REntityServer();
+ public void addRegion(DynamicRegion region) {
+ new CRegion(entityServer, region);
+ }
+
+ public void removeRegion(DynamicRegion region) {
+ entityServer.getEntitiesByType(CRegion.class)
+ .stream()
+ .filter(cRegion -> cRegion.region == region)
+ .forEach(CRegion::die);
}
@Override
public void onMount(SWPlayer player) {
- this.player = player.getPlayer();
- sourceTile = Tile.fromLocation(player.getLocation()).orElse(null);
- if (sourceTile == null) {
- player.removeComponent(DynamicRegionVisualizer.class);
- return;
- }
- sourceLocation = player.getLocation().add(0, -5, 0).getBlock().getLocation();
entityServer.addPlayer(player.getPlayer());
-
- Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
-
- renderTiles(0, 0);
}
@Override
public void onUnmount(SWPlayer player) {
- Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
- entityServer.close();
+ entityServer.removePlayer(player.getPlayer());
}
- @EventHandler
- public void onPlayerMove(PlayerMoveEvent event) {
- if (event.getPlayer() != player) return;
- Location position = event.getTo().getBlock().getLocation();
- int dx = position.getBlockX() - sourceLocation.getBlockX();
- int dz = position.getBlockZ() - sourceLocation.getBlockZ();
- renderTiles(dx, dz);
+ private static final Vector3f VEC_ZERO = new Vector3f(0, 0, 0);
+ private static final Quaternionf QUT_ZERO = new Quaternionf(0, 0, 0, 1);
+
+ public static Point toVisualization(Location worldLocation) {
+ Tile tile = Tile.fromLocation(worldLocation).orElseThrow();
+ return new Point(tile.getTileX(), 0, tile.getTileZ());
}
- private void renderTiles(int dx, int dz) {
- Set tileSet = entityServer.getEntitiesByType(CTile.class)
- .stream()
- .filter(cTile -> {
- if (Math.abs(cTile.tile.getTileX() - dx) > 40 || Math.abs(cTile.tile.getTileZ() - dz) > 40) {
- cTile.die();
- return false;
- } else {
- return true;
- }
- })
- .map(cTile -> cTile.tile)
- .collect(Collectors.toSet());
+ private static class CRegion extends CEntity {
- for (int x = dx - 20; x <= dx + 20; x++) {
- for (int z = dz - 20; z <= dz + 20; z++) {
- Tile tile = sourceTile.add(x, z).orElse(null);
- if (tile == null || tileSet.contains(tile)) continue;
- new CTile(entityServer, tile);
- }
- }
- }
+ private final DynamicRegion region;
- private void resetTiles(Set tiles) {
- entityServer.getEntitiesByType(CTile.class)
- .stream()
- .filter(cTile -> tiles.contains(cTile.tile))
- .peek(CTile::die)
- .map(cTile -> cTile.tile)
- .forEach(tile -> {
- new CTile(entityServer, tile);
- });
-
- if (placement != null) {
- placement.check();
- }
- }
-
- private class CTile extends CEntity {
-
- private final Tile tile;
-
- public CTile(REntityServer server, Tile tile) {
+ private CRegion(REntityServer server, DynamicRegion region) {
super(server);
- this.tile = tile;
+ this.region = region;
- RegionType regionType = DynamicRegionSystem.INSTANCE.get(tile).getType();
- Material material = switch (regionType) {
- case SPAWN, SPAWN_EXTENSION -> Material.LODESTONE;
- case SPAWN_PATH, PATH -> Material.DIRT_PATH;
- case DRY, DRY_SPECIAL -> Material.IRON_BLOCK;
- case WET, WET_SPECIAL -> Material.LAPIS_BLOCK;
- default -> Material.WHITE_CARPET;
- };
- Location location = sourceLocation.clone().add(tile.getTileX() - sourceTile.getTileX(), 0, tile.getTileZ() - sourceTile.getTileZ());
- if (tile.equals(Tile.ZERO)) {
- CCubedTextDisplay spawn = new CCubedTextDisplay(entityServer, location);
- spawn.setText("§eSPAWN");
- spawn.setBackgroundColor(0);
- spawn.setShadowed(false);
- entities.add(spawn);
- } else if (tile.equals(sourceTile)) {
- CCubedTextDisplay origin = new CCubedTextDisplay(entityServer, location);
- origin.setText("§eORIGIN");
- origin.setBackgroundColor(0);
- origin.setShadowed(false);
- entities.add(origin);
+ RegionConstructorData data = DynamicRegionSystem.constructorDataMap.get(region.getClass());
+ int widthX = data.widthX();
+ int widthZ = data.widthZ();
+
+ Point point = toVisualization(region.getArea().getMinPoint(false).toLocation((World) null));
+
+ if (widthX != 1 || widthZ != 1) {
+ CArea area = new CArea(server);
+ area.setBlock(Material.WHITE_CONCRETE.createBlockData());
+ area.setPos1And2(point.toLocation((World) null).add(0, 1 - CArea.DEFAULT_WIDTH, 0), point.toLocation((World) null).add(widthX - 1, 1 - CArea.DEFAULT_WIDTH, widthZ - 1));
+ entities.add(area);
+
+ RTextDisplay text = new RTextDisplay(server, point.toLocation((World) null).add(widthX / 2.0, 1.1, widthZ / 2.0));
+ text.setText(data.name());
+ text.setBillboard(Display.Billboard.VERTICAL);
+ text.setBackgroundColor(0);
+ text.setShadowed(false);
+ text.setTransform(new Transformation(new Vector3f(0, 0, 0), new Quaternionf().rotationX((float) Math.toRadians(270)), new Vector3f(1, 1, 1), new Quaternionf()));
+ entities.add(text);
}
- RBlockDisplay blockDisplay = new RBlockDisplay(entityServer, location);
- blockDisplay.setBlock(material.createBlockData());
- entities.add(blockDisplay);
-
- RInteraction interaction = new RInteraction(entityServer, location.clone().add(0.5, 0, 0.5));
- interaction.setInteraction((player, entityAction) -> {
- if (placement != null) {
- placement.click(tile, regionType.isGlobal());
- return;
- }
-
- if (!regionType.isGlobal()) {
- SWInventory inv = new SWInventory(player, 9, "Delete Region: " + tile.display());
- inv.setItem(0, new SWItem(SWItem.getDye(10), "§8Cancel", click -> {
- player.closeInventory();
- }));
- inv.setItem(8, new SWItem(SWItem.getDye(1), "§cDelete", click -> {
- player.closeInventory();
- Region region = DynamicRegionSystem.INSTANCE.get(tile);
- Set tiles = DynamicRegionSystem.INSTANCE.getTilesOfRegion(region);
- region.delete();
-
- SWPlayer.allWithSingleComponent(DynamicRegionVisualizer.class)
- .forEach(pair -> {
- pair.getComponent().resetTiles(tiles);
- });
- }));
- inv.open();
- } else {
- List, RegionConstructorData>>> entries = new ArrayList<>();
- DynamicRegionSystem.constructorDataMap.entrySet()
- .stream()
- .filter(entry -> entry.getValue().placeable())
- .sorted(Comparator.comparing(entry -> entry.getValue().name()))
- .forEach(entry -> {
- entries.add(new SWListInv.SWListEntry<>(new SWItem(entry.getValue().material(), entry.getValue().name()), entry));
- });
-
- SWListInv, RegionConstructorData>> listInv = new SWListInv<>(player, "Select Region for: " + tile.display(), entries, (click, entry) -> {
- new Placement(entry.getKey(), entry.getValue(), tile);
- player.closeInventory();
- });
- listInv.open();
- }
- });
- entities.add(interaction);
- }
- }
-
- private class Placement {
- private final Class extends DynamicRegion> regionType;
- private final RegionConstructorData constructorData;
-
- private CWireframe wireframe;
- private Tile sourceTile;
- private int dx;
- private int dz;
- private boolean valid = false;
-
- private Location getMinLocation() {
- Tile tile = sourceTile.add(-DynamicRegionVisualizer.this.sourceTile.getTileX(), -DynamicRegionVisualizer.this.sourceTile.getTileZ()).orElse(null);
- if (tile == null) tile = Tile.ZERO;
- return sourceLocation.clone().add(tile.getTileX(), 0, tile.getTileZ());
- }
-
- private Location getMaxLocation() {
- Tile tile = sourceTile.add(-DynamicRegionVisualizer.this.sourceTile.getTileX(), -DynamicRegionVisualizer.this.sourceTile.getTileZ()).orElse(null);
- if (tile == null) tile = Tile.ZERO;
- return sourceLocation.clone().add(tile.getTileX(), 0, tile.getTileZ()).add(dx, 0, dz);
- }
-
- public Placement(Class extends DynamicRegion> regionType, RegionConstructorData constructorData, Tile sourceTile) {
- this.regionType = regionType;
- this.constructorData = constructorData;
- this.sourceTile = sourceTile;
- dx = constructorData.widthX() / Tile.tileSize - 1;
- dz = constructorData.widthZ() / Tile.tileSize - 1;
- if (dx == 0 && dz == 0) {
- place();
- return;
- }
-
- placement = this;
- wireframe = new CWireframe(entityServer);
- check();
- }
-
- private void check() {
- wireframe.setPos1And2(getMinLocation(), getMaxLocation());
- for (int x = 0; x <= dx; x++) {
- for (int z = 0; z <= dz; z++) {
- Tile tile = sourceTile.add(x, z).orElse(null);
- if (tile == null || !DynamicRegionSystem.INSTANCE.get(tile).getType().isGlobal()) {
- wireframe.setBlock(Material.RED_CONCRETE.createBlockData());
- valid = false;
- return;
- }
- }
- }
- wireframe.setBlock(Material.LIME_CONCRETE.createBlockData());
- valid = true;
- }
-
- public void click(Tile tile, boolean global) {
- if (tile.getTileX() >= sourceTile.getTileX() && tile.getTileX() <= sourceTile.getTileX() + dx && tile.getTileZ() >= sourceTile.getTileZ() && tile.getTileZ() <= sourceTile.getTileZ() + dz) {
- SWInventory inv = new SWInventory(player, 9, "Place Region: " + constructorData.name());
- inv.setItem(0, new SWItem(SWItem.getDye(1), "§cDeselect", click -> {
- placement = null;
- wireframe.die();
- player.closeInventory();
- }));
- if (valid) {
- inv.setItem(8, new SWItem(SWItem.getDye(10), "§aPlace", click -> {
- player.closeInventory();
- place();
- }));
- } else {
- inv.setItem(8, new SWItem(SWItem.getDye(8), "§8Place", click -> {
- }));
- }
- inv.open();
- return;
- }
-
- if (!global) {
- return;
- }
-
- Set tiles = new HashSet<>();
- for (int x = 0; x <= dx; x++) {
- for (int z = 0; z <= dz; z++) {
- tiles.add(Tile.fromTile(x + sourceTile.getTileX(), z + sourceTile.getTileZ()).orElse(null));
- }
- }
- tiles.remove(null);
- Tile selected = tiles.stream().min(Comparator.comparing(current -> {
- int dx = current.getTileX() - tile.getTileX();
- int dz = current.getTileZ() - tile.getTileZ();
- return dx * dx + dz * dz;
- }))
- .orElse(null);
- if (selected == null) return;
-
- int dx = tile.getTileX() - selected.getTileX();
- int dz = tile.getTileZ() - selected.getTileZ();
- Tile newSourceTile = sourceTile.add(dx, dz).orElse(null);
- if (newSourceTile == null) return;
- sourceTile = newSourceTile;
- check();
- }
-
- private void place() {
- DynamicRegion dynamicRegion = DynamicRegionRepository.constructRegion(regionType, sourceTile);
- if (dynamicRegion == null) {
- // TODO: Give error to user
- return;
- }
-
- dynamicRegion.getArea().place(new PasteBuilder(), false);
- dynamicRegion.updateNeighbours();
-
- placement = null;
- if (wireframe != null) wireframe.die();
- Set tiles = new HashSet<>();
- for (int x = 0; x <= dx; x++) {
- for (int z = 0; z <= dz; z++) {
- tiles.add(Tile.fromTile(x + sourceTile.getTileX(), z + sourceTile.getTileZ()).orElse(null));
- }
- }
- tiles.remove(null);
- SWPlayer.allWithSingleComponent(DynamicRegionVisualizer.class)
- .forEach(pair -> pair.getComponent().resetTiles(tiles));
+ RBlockDisplay display = new RBlockDisplay(server, point.toLocation((World) null));
+ display.setTransform(new Transformation(VEC_ZERO, QUT_ZERO, new Vector3f(widthX, 1, widthZ), QUT_ZERO));
+ display.setBlock(data.material().createBlockData());
+ entities.add(display);
}
}
}
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 a498c130..6055543f 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,11 +33,9 @@ import java.util.stream.Stream;
@EqualsAndHashCode
public class Tile {
- public static final Tile ZERO = new Tile(0, 0);
-
public static final int tileSize = 21;
public static final int tileOffset = tileSize / 2;
- public static final int maxTile = 255;
+ public static final int maxTile = 127;
public static final int minTile = -maxTile;
public static final int tilesPerAxis = maxTile * 2 + 1;
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/GlobalRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/GlobalRegion.java
index 79652ccb..1028cc9b 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/GlobalRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/GlobalRegion.java
@@ -29,7 +29,6 @@ import org.bukkit.Location;
import org.bukkit.Material;
import javax.annotation.Nullable;
-import java.io.File;
import java.util.UUID;
import java.util.function.BiConsumer;
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/AreaBlock.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/AreaBlock.java
index d6a3f75a..eb25edcb 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/AreaBlock.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/AreaBlock.java
@@ -28,7 +28,6 @@ import de.steamwar.bausystem.utils.PasteBuilder;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NonNull;
-import org.bukkit.Location;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class AreaBlock implements Region.Area {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7DisplayRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7DisplayRegion.java
index 9fb0c9fa..fb17b630 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7DisplayRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7DisplayRegion.java
@@ -40,9 +40,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "microwargear_display_7",
name = "MicroWarGearDisplay",
- material = Material.STONE_BUTTON,
- widthX = MiWG7DisplayRegion.TILE_X * Tile.tileSize,
- widthZ = MiWG7DisplayRegion.TILE_Z * Tile.tileSize
+ material = Material.GRAY_CONCRETE,
+ widthX = MiWG7DisplayRegion.TILE_X,
+ widthZ = MiWG7DisplayRegion.TILE_Z
)
public class MiWG7DisplayRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7PlotRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7PlotRegion.java
index 4f698d6c..24284c8b 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7PlotRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/microwargear_7/MiWG7PlotRegion.java
@@ -41,9 +41,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "microwargear_plot_7",
name = "MicroWarGearPlot",
- material = Material.STONE_BUTTON,
- widthX = Tile.tileSize * MiWG7PlotRegion.TILE_X,
- widthZ = Tile.tileSize * MiWG7PlotRegion.TILE_Z
+ material = Material.GRAY_CONCRETE,
+ widthX = MiWG7PlotRegion.TILE_X,
+ widthZ = MiWG7PlotRegion.TILE_Z
)
public class MiWG7PlotRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGDisplayRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGDisplayRegion.java
index 707f7e5a..f601ec0b 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGDisplayRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGDisplayRegion.java
@@ -40,9 +40,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "miniwargear_display",
name = "MiniWarGearDisplay",
- material = Material.END_STONE_BRICK_SLAB,
- widthX = MWGDisplayRegion.TILE_X * Tile.tileSize,
- widthZ = MWGDisplayRegion.TILE_Z * Tile.tileSize
+ material = Material.YELLOW_CONCRETE,
+ widthX = MWGDisplayRegion.TILE_X,
+ widthZ = MWGDisplayRegion.TILE_Z
)
public class MWGDisplayRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGPlotRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGPlotRegion.java
index f581bd8e..46fe88f4 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGPlotRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/miniwargear/MWGPlotRegion.java
@@ -41,9 +41,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "miniwargear_plot",
name = "MiniWarGearPlot",
- material = Material.END_STONE_BRICK_SLAB,
- widthX = Tile.tileSize * MWGPlotRegion.TILE_X,
- widthZ = Tile.tileSize * MWGPlotRegion.TILE_Z
+ material = Material.YELLOW_CONCRETE,
+ widthX = MWGPlotRegion.TILE_X,
+ widthZ = MWGPlotRegion.TILE_Z
)
public class MWGPlotRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45DisplayRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45DisplayRegion.java
index 06d13033..1f47110e 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45DisplayRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45DisplayRegion.java
@@ -40,9 +40,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "wargear_display_45",
name = "WarGearDisplay 45",
- material = Material.END_STONE_BRICKS,
- widthX = WG45DisplayRegion.TILE_X * Tile.tileSize,
- widthZ = WG45DisplayRegion.TILE_Z * Tile.tileSize
+ material = Material.YELLOW_CONCRETE,
+ widthX = WG45DisplayRegion.TILE_X,
+ widthZ = WG45DisplayRegion.TILE_Z
)
public class WG45DisplayRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45PlotRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45PlotRegion.java
index 164018a6..7f026876 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45PlotRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/wargear_45/WG45PlotRegion.java
@@ -41,9 +41,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "wargear_plot_45",
name = "WarGearPlot 45",
- material = Material.END_STONE_BRICKS,
- widthX = Tile.tileSize * WG45PlotRegion.TILE_X,
- widthZ = Tile.tileSize * WG45PlotRegion.TILE_Z
+ material = Material.YELLOW_CONCRETE,
+ widthX = WG45PlotRegion.TILE_X,
+ widthZ = WG45PlotRegion.TILE_Z
)
public class WG45PlotRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175DisplayRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175DisplayRegion.java
index a5726290..534f9712 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175DisplayRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175DisplayRegion.java
@@ -40,9 +40,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "warship_display_175",
name = "WarShipDisplay 175",
- material = Material.BIRCH_BOAT,
- widthX = WS175DisplayRegion.TILE_X * Tile.tileSize,
- widthZ = WS175DisplayRegion.TILE_Z * Tile.tileSize
+ material = Material.BLUE_CONCRETE,
+ widthX = WS175DisplayRegion.TILE_X,
+ widthZ = WS175DisplayRegion.TILE_Z
)
public class WS175DisplayRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175PlotRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175PlotRegion.java
index 7473006c..c12dc67b 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175PlotRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_175/WS175PlotRegion.java
@@ -41,9 +41,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "warship_plot_175",
name = "WarShipPlot 175",
- material = Material.BIRCH_BOAT,
- widthX = Tile.tileSize * WS175PlotRegion.TILE_X,
- widthZ = Tile.tileSize * WS175PlotRegion.TILE_Z
+ material = Material.BLUE_CONCRETE,
+ widthX = WS175PlotRegion.TILE_X,
+ widthZ = WS175PlotRegion.TILE_Z
)
public class WS175PlotRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230DisplayRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230DisplayRegion.java
index 9596cb8f..6b867725 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230DisplayRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230DisplayRegion.java
@@ -40,9 +40,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "warship_display_230",
name = "WarShipDisplay 230",
- material = Material.BIRCH_BOAT,
- widthX = WS230DisplayRegion.TILE_X * Tile.tileSize,
- widthZ = WS230DisplayRegion.TILE_Z * Tile.tileSize
+ material = Material.BLUE_CONCRETE,
+ widthX = WS230DisplayRegion.TILE_X,
+ widthZ = WS230DisplayRegion.TILE_Z
)
public class WS230DisplayRegion extends DynamicRegion {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230PlotRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230PlotRegion.java
index 76296145..58bf13a2 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230PlotRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/modes/warship_230/WS230PlotRegion.java
@@ -41,9 +41,9 @@ import java.util.UUID;
@RegionConstructorData(
identifier = "warship_plot_230",
name = "WarShipPlot 230",
- material = Material.BIRCH_BOAT,
- widthX = Tile.tileSize * WS230PlotRegion.TILE_X,
- widthZ = Tile.tileSize * WS230PlotRegion.TILE_Z
+ material = Material.BLUE_CONCRETE,
+ widthX = WS230PlotRegion.TILE_X,
+ widthZ = WS230PlotRegion.TILE_Z
)
public class WS230PlotRegion extends DynamicRegion {
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 7cf28877..3d80f402 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
@@ -37,11 +37,14 @@ import java.util.stream.Collectors;
identifier = "path",
name = "Path",
material = Material.DIRT_PATH,
- widthX = Tile.tileSize,
- widthZ = Tile.tileSize
+ widthX = PathRegion.TILE_X,
+ widthZ = PathRegion.TILE_Z
)
public class PathRegion extends DynamicRegion {
+ protected static final int TILE_X = 1;
+ protected static final int TILE_Z = 1;
+
private final PathArea area;
@Getter
private final Tile tile;
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/SpecialArea.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/SpecialArea.java
index 116c978a..ffa68666 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/SpecialArea.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/SpecialArea.java
@@ -31,12 +31,9 @@ import de.steamwar.bausystem.utils.PasteBuilder;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
-import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
public class SpecialArea implements Region.Area {
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/dry/DryRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/dry/DryRegion.java
index 470d5cce..5a570841 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/dry/DryRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/dry/DryRegion.java
@@ -26,8 +26,6 @@ import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.*;
-import de.steamwar.bausystem.region.dynamic.modes.AreaTile;
-import de.steamwar.bausystem.region.dynamic.modes.DisplayRegionData;
import de.steamwar.bausystem.region.dynamic.special.SpecialArea;
import de.steamwar.bausystem.region.dynamic.special.SpecialRegionData;
import de.steamwar.sql.GameModeConfig;
@@ -43,12 +41,15 @@ import static de.steamwar.bausystem.region.dynamic.special.SpecialArea.SPECIAL_P
@RegionConstructorData(
identifier = "special_dry",
name = "Dry",
- material = Material.SAND,
- widthX = Tile.tileSize,
- widthZ = Tile.tileSize
+ material = Material.IRON_BLOCK,
+ widthX = DryRegion.TILE_X,
+ widthZ = DryRegion.TILE_Z
)
public class DryRegion extends DynamicRegion {
+ protected static final int TILE_X = 1;
+ protected static final int TILE_Z = 1;
+
private static final VariantSelector DRY = VariantSelector.Get(new File(SPECIAL_PATH_DIR, "dry"));
private final SpecialArea area;
diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/wet/WetRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/wet/WetRegion.java
index 183e7a57..bae2f070 100644
--- a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/wet/WetRegion.java
+++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/special/wet/WetRegion.java
@@ -27,7 +27,6 @@ import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.*;
import de.steamwar.bausystem.region.dynamic.special.SpecialArea;
-import de.steamwar.bausystem.region.dynamic.special.SpecialRegionData;
import de.steamwar.sql.GameModeConfig;
import lombok.NonNull;
import org.bukkit.Material;
@@ -41,12 +40,15 @@ import static de.steamwar.bausystem.region.dynamic.special.SpecialArea.SPECIAL_P
@RegionConstructorData(
identifier = "special_wet",
name = "Wet",
- material = Material.LIGHT_BLUE_CONCRETE_POWDER,
- widthX = Tile.tileSize,
- widthZ = Tile.tileSize
+ material = Material.LAPIS_BLOCK,
+ widthX = WetRegion.TILE_X,
+ widthZ = WetRegion.TILE_Z
)
public class WetRegion extends DynamicRegion {
+ protected static final int TILE_X = 1;
+ protected static final int TILE_Z = 1;
+
private static final VariantSelector WET = VariantSelector.Get(new File(SPECIAL_PATH_DIR, "wet"));
private final SpecialArea area;
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/CArea.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/CArea.java
new file mode 100644
index 00000000..635b45b2
--- /dev/null
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/CArea.java
@@ -0,0 +1,83 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2026 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.entity;
+
+import org.bukkit.Location;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.util.Vector;
+
+import java.util.List;
+
+public class CArea extends CEntity {
+
+ public static final float DEFAULT_WIDTH = 1 / 16f;
+
+ private Location pos1;
+ private Location pos2;
+ private float width = DEFAULT_WIDTH;
+
+ public CArea(REntityServer server) {
+ super(server);
+ for (int i = 0; i < 4; i++) {
+ entities.add(new CLine(server));
+ }
+ }
+
+ public CArea setPos1And2(Location pos1, Location pos2) {
+ if (pos1.getY() != pos2.getY()) return this;
+ this.pos1 = pos1;
+ this.pos2 = pos2;
+ updateAndSpawnLines();
+ return this;
+ }
+
+ public CArea setWidth(float width) {
+ this.width = width;
+ updateAndSpawnLines();
+ getEntitiesByType(CLine.class).forEach(haaLine -> {
+ haaLine.setWidth(width);
+ });
+ return this;
+ }
+
+ public CArea setBlock(BlockData blockData) {
+ getEntitiesByType(CLine.class).forEach(haaLine -> {
+ haaLine.setBlock(blockData);
+ });
+ return this;
+ }
+
+ private void updateAndSpawnLines() {
+ List lines = getEntitiesByType(CLine.class);
+ if (pos1 == null || pos2 == null) {
+ lines.forEach(line -> line.setFromAndTo(null, null));
+ return;
+ }
+
+ Vector min = Vector.getMinimum(pos1.toVector(), pos2.toVector());
+ Vector max = Vector.getMaximum(pos1.toVector(), pos2.toVector())
+ .add(new Vector(1 - width, 0, 1 - width));
+
+ lines.get(0).setFromAndTo(new Location(null, min.getX(), min.getY(), min.getZ()), new Location(null, max.getX() + width, min.getY(), min.getZ()));
+ lines.get(1).setFromAndTo(new Location(null, min.getX(), min.getY(), max.getZ()), new Location(null, max.getX() + width, min.getY(), max.getZ()));
+ lines.get(2).setFromAndTo(new Location(null, min.getX(), min.getY(), min.getZ()), new Location(null, min.getX(), min.getY(), max.getZ() + width));
+ lines.get(3).setFromAndTo(new Location(null, max.getX(), min.getY(), min.getZ()), new Location(null, max.getX(), min.getY(), max.getZ() + width));
+ }
+}
diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java
index 530aca91..29281372 100644
--- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java
+++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RInteraction.java
@@ -22,7 +22,6 @@ package de.steamwar.entity;
import de.steamwar.core.BountifulWrapper;
import lombok.AccessLevel;
import lombok.Getter;
-import lombok.Setter;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@@ -40,9 +39,8 @@ public class RInteraction extends REntity {
protected final Consumer