/* * 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 de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.dynamic.Tile; import de.steamwar.core.SWPlayer; import de.steamwar.entity.*; import de.steamwar.inventory.SWInventory; 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.inventory.InventoryType; import org.bukkit.event.player.PlayerMoveEvent; import java.util.Set; import java.util.stream.Collectors; public class DynamicRegionVisualizer implements SWPlayer.Component, Listener { private final REntityServer entityServer; private Player player; private Location sourceLocation; private Tile sourceTile; public DynamicRegionVisualizer() { this.entityServer = new REntityServer(); } @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(); } @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 void renderTiles(int dx, int dz) { Set tileSet = entityServer.getEntitiesByType(CTile.class) .stream() .filter(cTile -> { if (Math.abs(cTile.tile.getTileX() - dx) > 20 || Math.abs(cTile.tile.getTileZ() - dz) > 20) { cTile.die(); return false; } else { return true; } }) .map(cTile -> cTile.tile) .collect(Collectors.toSet()); for (int x = dx - 10; x <= dx + 10; x++) { for (int z = dz - 10; z <= dz + 10; z++) { Tile tile = sourceTile.add(x, z).orElse(null); if (tile == null || tileSet.contains(tile)) continue; new CTile(entityServer, tile); } } } private class CTile extends CEntity { private final Tile tile; public CTile(REntityServer server, Tile tile) { super(server); this.tile = tile; Material material = switch (DynamicRegionSystem.INSTANCE.get(tile).getType()) { 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 spawn = new CCubedTextDisplay(entityServer, location); spawn.setText("§eORIGIN"); spawn.setBackgroundColor(0); spawn.setShadowed(false); entities.add(spawn); } RBlockDisplay entity = new RBlockDisplay(entityServer, location); entity.setBlock(material.createBlockData()); entities.add(entity); RInteraction interaction = new RInteraction(entityServer, location.clone().add(0.5, 0, 0.5)); interaction.setInteraction((player, entityAction) -> { SWInventory swInv = new SWInventory(player, () -> Bukkit.createInventory(null, InventoryType.DROPPER, tile.toString())); swInv.open(); }); entities.add(entity); } } }