Add lobby/game worlds, void generator, dbd reload, and fix plugin loading
- Add VoidWorldGenerator for empty void worlds - Add LobbyManager with auto-creation of lobby world (stone platform 7x7, built once) and game world - Add /dbd reload command to reload all configs at runtime - Add plugin.yml for proper command registration, remove paper-plugin.yml - Fix mdbdBootstrap/mdbdLoader public constructors (Paper requirement) - Fix command registration (getCommand null on Paper plugin system)
This commit is contained in:
parent
76e0c1e167
commit
34e0aebd5d
27 changed files with 767 additions and 85 deletions
|
|
@ -10,7 +10,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.20.6-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0")
|
||||
}
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ java {
|
|||
|
||||
tasks {
|
||||
runServer {
|
||||
minecraftVersion("1.20.6")
|
||||
minecraftVersion("1.21.1")
|
||||
jvmArgs("-Xms2G", "-Xmx2G")
|
||||
}
|
||||
|
||||
|
|
|
|||
202
src/main/java/dev/loki/command/DBDAdminCommand.java
Normal file
202
src/main/java/dev/loki/command/DBDAdminCommand.java
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
package dev.loki.command;
|
||||
|
||||
import dev.loki.data.GeneratorDataManager;
|
||||
import dev.loki.mdbd;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DBDAdminCommand implements TabExecutor {
|
||||
|
||||
private final mdbd plugin;
|
||||
private final GeneratorDataManager generatorData;
|
||||
private final Set<UUID> selectingGenerator;
|
||||
private final MiniMessage mm;
|
||||
private BukkitTask actionBarTask;
|
||||
|
||||
public DBDAdminCommand(mdbd plugin, GeneratorDataManager generatorData) {
|
||||
this.plugin = plugin;
|
||||
this.generatorData = generatorData;
|
||||
this.selectingGenerator = new HashSet<>();
|
||||
this.mm = MiniMessage.miniMessage();
|
||||
startActionBarTask();
|
||||
}
|
||||
|
||||
private void startActionBarTask() {
|
||||
this.actionBarTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
|
||||
for (UUID uuid : selectingGenerator) {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p != null && p.isOnline()) {
|
||||
p.sendActionBar(mm.deserialize(
|
||||
"&#FFA500⚒ Режим установки: �FF00сломайте блок для генератора &#FFA500⚒"));
|
||||
}
|
||||
}
|
||||
}, 0L, 20L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args) {
|
||||
if (!sender.hasPermission("mdbd.admin")) {
|
||||
sender.sendMessage(Component.text("Нет прав!", NamedTextColor.RED));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(Component.text("Только игроки!", NamedTextColor.RED));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sendUsage(sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
return switch (args[0].toLowerCase()) {
|
||||
case "create" -> handleCreate(player, args);
|
||||
case "list" -> handleList(player);
|
||||
case "remove" -> handleRemove(player, args);
|
||||
case "clear" -> handleClear(player);
|
||||
default -> {
|
||||
sendUsage(sender);
|
||||
yield true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnreachableBranchError")
|
||||
private boolean handleCreate(Player player, String[] args) {
|
||||
if (args.length < 2) {
|
||||
player.sendMessage(Component.text("&#FF0000Использование: /dbdadmin create <generator>"));
|
||||
return true;
|
||||
}
|
||||
|
||||
String type = args[1].toLowerCase();
|
||||
switch (type) {
|
||||
case "generator" -> {
|
||||
if (selectingGenerator.contains(player.getUniqueId())) {
|
||||
selectingGenerator.remove(player.getUniqueId());
|
||||
player.sendMessage(Component.text("&#FFA500Режим выбора генератора отключен"));
|
||||
} else {
|
||||
selectingGenerator.add(player.getUniqueId());
|
||||
player.sendMessage(Component.text("�FF00Режим выбора генератора включен!"));
|
||||
player.sendMessage(Component.text("&#FFD700Сломайте блок, чтобы установить генератор"));
|
||||
player.sendMessage(Component.text("&#FFD700(блок не сломается, а сохранятся его координаты)"));
|
||||
player.sendMessage(Component.text("&#FFA500Введите /dbdadmin create generator снова, чтобы отключить режим"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default -> {
|
||||
player.sendMessage(Component.text("&#FF0000Неизвестный тип: " + type));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleList(Player player) {
|
||||
var entries = generatorData.getGeneratorEntries();
|
||||
player.sendMessage(Component.text("&#FFD700=== Генераторы (" + entries.size() + ") ==="));
|
||||
if (entries.isEmpty()) {
|
||||
player.sendMessage(Component.text("󅑀Нет установленных генераторов"));
|
||||
} else {
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
player.sendMessage(Component.text("�CED1[" + i + "] " + entries.get(i)));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleRemove(Player player, String[] args) {
|
||||
if (args.length < 2) {
|
||||
player.sendMessage(Component.text("&#FF0000Использование: /dbdadmin remove <id>"));
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
int id = Integer.parseInt(args[1]);
|
||||
var entries = generatorData.getGeneratorEntries();
|
||||
if (id < 0 || id >= entries.size()) {
|
||||
player.sendMessage(Component.text("&#FF0000Генератор с ID " + id + " не найден"));
|
||||
return true;
|
||||
}
|
||||
String removed = entries.get(id);
|
||||
generatorData.removeGenerator(id);
|
||||
player.sendMessage(Component.text("�FF00Генератор удален: " + removed));
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage(Component.text("&#FF0000ID должен быть числом"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleClear(Player player) {
|
||||
generatorData.clearGenerators();
|
||||
player.sendMessage(Component.text("&#FFA500Все генераторы удалены"));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendUsage(CommandSender sender) {
|
||||
sender.sendMessage(Component.text("&#FF6B00=== DBD Admin ==="));
|
||||
sender.sendMessage(Component.text("&#FFD700/dbdadmin create generator — Режим установки генератора"));
|
||||
sender.sendMessage(Component.text("&#FFD700/dbdadmin list — Список генераторов"));
|
||||
sender.sendMessage(Component.text("&#FFD700/dbdadmin remove <id> — Удалить генератор"));
|
||||
sender.sendMessage(Component.text("&#FFD700/dbdadmin clear — Очистить все генераторы"));
|
||||
}
|
||||
|
||||
public boolean isSelectingGenerator(UUID uuid) {
|
||||
return selectingGenerator.contains(uuid);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
if (actionBarTask != null) {
|
||||
actionBarTask.cancel();
|
||||
actionBarTask = null;
|
||||
}
|
||||
selectingGenerator.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args) {
|
||||
if (!sender.hasPermission("mdbd.admin")) return List.of();
|
||||
|
||||
if (args.length == 1) {
|
||||
return Arrays.asList("create", "list", "remove", "clear").stream()
|
||||
.filter(s -> s.startsWith(args[0].toLowerCase()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
if (args.length == 2 && args[0].equalsIgnoreCase("create")) {
|
||||
return List.of("generator").stream()
|
||||
.filter(s -> s.startsWith(args[1].toLowerCase()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
if (args.length == 2 && args[0].equalsIgnoreCase("remove")) {
|
||||
var entries = generatorData.getGeneratorEntries();
|
||||
List<String> ids = new ArrayList<>();
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
ids.add(String.valueOf(i));
|
||||
}
|
||||
return ids.stream()
|
||||
.filter(s -> s.startsWith(args[1]))
|
||||
.toList();
|
||||
}
|
||||
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package dev.loki.command;
|
||||
|
||||
import dev.loki.core.GameState;
|
||||
import dev.loki.core.GameManager;
|
||||
import dev.loki.mdbd;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
|
@ -39,6 +40,7 @@ public class DBDCommand implements TabExecutor {
|
|||
case "forcestart" -> handleForceStart(sender);
|
||||
case "create" -> handleCreate(sender);
|
||||
case "stop" -> handleStop(sender);
|
||||
case "reload" -> handleReload(sender);
|
||||
default -> {
|
||||
sendUsage(sender);
|
||||
yield true;
|
||||
|
|
@ -82,9 +84,8 @@ public class DBDCommand implements TabExecutor {
|
|||
sender.sendMessage(Component.text("Нет активной игры!", NamedTextColor.RED));
|
||||
return true;
|
||||
}
|
||||
var phase = session.getCurrentPhase();
|
||||
if (phase instanceof dev.loki.phase.LobbyPhase lobby) {
|
||||
lobby.forceStart();
|
||||
if (session.getState() == GameState.LOBBY) {
|
||||
session.forceStart();
|
||||
sender.sendMessage(Component.text("[DBD] Игра форсирована!", NamedTextColor.GREEN));
|
||||
} else {
|
||||
sender.sendMessage(Component.text("Нельзя форсировать сейчас", NamedTextColor.RED));
|
||||
|
|
@ -105,6 +106,16 @@ public class DBDCommand implements TabExecutor {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean handleReload(CommandSender sender) {
|
||||
if (!sender.hasPermission("mdbd.admin")) {
|
||||
sender.sendMessage(Component.text("Нет прав!", NamedTextColor.RED));
|
||||
return true;
|
||||
}
|
||||
plugin.reloadConfigs();
|
||||
sender.sendMessage(Component.text("[DBD] Конфиги перезагружены!", NamedTextColor.GREEN));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleStop(CommandSender sender) {
|
||||
if (!sender.hasPermission("mdbd.admin")) {
|
||||
sender.sendMessage(Component.text("Нет прав!", NamedTextColor.RED));
|
||||
|
|
@ -123,6 +134,7 @@ public class DBDCommand implements TabExecutor {
|
|||
sender.sendMessage(Component.text("/dbd create - создать игру", NamedTextColor.GRAY));
|
||||
sender.sendMessage(Component.text("/dbd forcestart - форс старт", NamedTextColor.GRAY));
|
||||
sender.sendMessage(Component.text("/dbd stop - остановить", NamedTextColor.GRAY));
|
||||
sender.sendMessage(Component.text("/dbd reload - перезагрузить конфиги", NamedTextColor.GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +144,7 @@ public class DBDCommand implements TabExecutor {
|
|||
if (args.length == 1) {
|
||||
List<String> completions = new ArrayList<>(Arrays.asList("join", "leave"));
|
||||
if (sender.hasPermission("mdbd.admin")) {
|
||||
completions.addAll(Arrays.asList("create", "forcestart", "stop"));
|
||||
completions.addAll(Arrays.asList("create", "forcestart", "stop", "reload"));
|
||||
}
|
||||
return completions.stream()
|
||||
.filter(s -> s.startsWith(args[0].toLowerCase()))
|
||||
|
|
|
|||
|
|
@ -115,6 +115,12 @@ public class GameSession {
|
|||
return plugin.getConfigManager().getGame();
|
||||
}
|
||||
|
||||
public void forceStart() {
|
||||
if (currentPhase instanceof dev.loki.phase.LobbyPhase lobby) {
|
||||
lobby.forceStart();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTicksElapsed() {
|
||||
return ticksElapsed;
|
||||
}
|
||||
|
|
|
|||
148
src/main/java/dev/loki/data/GeneratorDataManager.java
Normal file
148
src/main/java/dev/loki/data/GeneratorDataManager.java
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
package dev.loki.data;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GeneratorDataManager {
|
||||
|
||||
private static final double ZONE_RADIUS = 3.0;
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
private final File dataFile;
|
||||
private FileConfiguration data;
|
||||
|
||||
public GeneratorDataManager(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.dataFile = new File(plugin.getDataFolder(), "generators.yml");
|
||||
load();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
if (!dataFile.exists()) {
|
||||
try {
|
||||
dataFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().warning("Could not create generators.yml");
|
||||
}
|
||||
}
|
||||
this.data = YamlConfiguration.loadConfiguration(dataFile);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
data.save(dataFile);
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().warning("Could not save generators.yml");
|
||||
}
|
||||
}
|
||||
|
||||
public void addGenerator(Location location) {
|
||||
List<String> list = data.getStringList("generators");
|
||||
String entry = formatLocation(location);
|
||||
if (!list.contains(entry)) {
|
||||
list.add(entry);
|
||||
data.set("generators", list);
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeGenerator(int index) {
|
||||
List<String> list = data.getStringList("generators");
|
||||
if (index >= 0 && index < list.size()) {
|
||||
list.remove(index);
|
||||
data.set("generators", list);
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearGenerators() {
|
||||
data.set("generators", null);
|
||||
save();
|
||||
}
|
||||
|
||||
public List<Location> getGenerators() {
|
||||
List<Location> result = new ArrayList<>();
|
||||
List<String> list = data.getStringList("generators");
|
||||
for (String entry : list) {
|
||||
Location loc = parseLocation(entry);
|
||||
if (loc != null) {
|
||||
result.add(loc);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<String> getGeneratorEntries() {
|
||||
return data.getStringList("generators");
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return data.getStringList("generators").size();
|
||||
}
|
||||
|
||||
public static String formatLocation(Location loc) {
|
||||
return String.format("%s:%.0f,%.0f,%.0f",
|
||||
loc.getWorld().getName(),
|
||||
loc.getX(),
|
||||
loc.getY(),
|
||||
loc.getZ());
|
||||
}
|
||||
|
||||
private Location parseLocation(String str) {
|
||||
String[] parts = str.split(":");
|
||||
if (parts.length < 2) return null;
|
||||
|
||||
World world = Bukkit.getWorld(parts[0].trim());
|
||||
if (world == null) return null;
|
||||
|
||||
String[] coords = parts[1].split(",");
|
||||
if (coords.length < 3) return null;
|
||||
|
||||
try {
|
||||
double x = Double.parseDouble(coords[0].trim());
|
||||
double y = Double.parseDouble(coords[1].trim());
|
||||
double z = Double.parseDouble(coords[2].trim());
|
||||
return new Location(world, x, y, z);
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static double getZoneRadius() {
|
||||
return ZONE_RADIUS;
|
||||
}
|
||||
|
||||
public boolean isInZone(Location location, List<Location> generators) {
|
||||
for (Location genLoc : generators) {
|
||||
if (!genLoc.getWorld().equals(location.getWorld())) continue;
|
||||
if (genLoc.distance(location) <= ZONE_RADIUS) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Location getNearestGenerator(Location location, List<Location> generators) {
|
||||
Location nearest = null;
|
||||
double nearestDist = ZONE_RADIUS;
|
||||
|
||||
for (Location genLoc : generators) {
|
||||
if (!genLoc.getWorld().equals(location.getWorld())) continue;
|
||||
double dist = genLoc.distance(location);
|
||||
if (dist <= nearestDist) {
|
||||
nearestDist = dist;
|
||||
nearest = genLoc;
|
||||
}
|
||||
}
|
||||
return nearest;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ public class PlayerStats {
|
|||
public UUID getPlayerId() { return playerId; }
|
||||
public int getTotalMatches() { return totalMatches; }
|
||||
public void incrementMatches() { this.totalMatches++; }
|
||||
public void setTotalMatches(int matches) { this.totalMatches = matches; }
|
||||
public int getEscapes() { return escapes; }
|
||||
public void incrementEscapes() { this.escapes++; }
|
||||
public int getDeaths() { return deaths; }
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class YamlStorage implements DataStorage {
|
|||
}
|
||||
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
|
||||
PlayerStats stats = new PlayerStats(playerId);
|
||||
stats.incrementMatches(config.getInt("matches", 0));
|
||||
stats.setTotalMatches(config.getInt("matches", 0));
|
||||
for (int i = 0; i < config.getInt("escapes", 0); i++) stats.incrementEscapes();
|
||||
for (int i = 0; i < config.getInt("deaths", 0); i++) stats.incrementDeaths();
|
||||
for (int i = 0; i < config.getInt("kills", 0); i++) stats.incrementKills();
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public class KillerAttack {
|
|||
}
|
||||
|
||||
private void applyCooldown(Killer killer) {
|
||||
cooldowns.put(killer.getUuid(), Bukkit.getCurrentTick());
|
||||
cooldowns.put(killer.getUuid(), (long) Bukkit.getCurrentTick());
|
||||
}
|
||||
|
||||
public double getCooldownProgress(Killer killer) {
|
||||
|
|
|
|||
46
src/main/java/dev/loki/listener/GeneratorSelectListener.java
Normal file
46
src/main/java/dev/loki/listener/GeneratorSelectListener.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package dev.loki.listener;
|
||||
|
||||
import dev.loki.command.DBDAdminCommand;
|
||||
import dev.loki.data.GeneratorDataManager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
|
||||
public class GeneratorSelectListener implements Listener {
|
||||
|
||||
private final DBDAdminCommand adminCommand;
|
||||
private final GeneratorDataManager generatorData;
|
||||
|
||||
public GeneratorSelectListener(DBDAdminCommand adminCommand, GeneratorDataManager generatorData) {
|
||||
this.adminCommand = adminCommand;
|
||||
this.generatorData = generatorData;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (!adminCommand.isSelectingGenerator(player.getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
Location loc = event.getBlock().getLocation();
|
||||
Location genLoc = new Location(loc.getWorld(),
|
||||
loc.getX() + 0.5,
|
||||
loc.getY(),
|
||||
loc.getZ() + 0.5);
|
||||
|
||||
generatorData.addGenerator(genLoc);
|
||||
|
||||
player.sendMessage(Component.text("�FF00Генератор установлен!"));
|
||||
player.sendMessage(Component.text("�CED1Координаты: " + GeneratorDataManager.formatLocation(genLoc)));
|
||||
player.sendMessage(Component.text("&#FFD700Всего генераторов: " + generatorData.getCount()));
|
||||
player.sendMessage(Component.text("&#FFA500Режим выбора остается активным. Ломайте следующий блок или"));
|
||||
player.sendMessage(Component.text("&#FFA500введите /dbdadmin create generator для отключения"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package dev.loki.listener;
|
||||
|
||||
import dev.loki.core.GameManager;
|
||||
import dev.loki.objective.GeneratorManager;
|
||||
import dev.loki.player.BasePlayer;
|
||||
import dev.loki.player.PlayerState;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
@ -19,6 +20,7 @@ import java.util.function.BiConsumer;
|
|||
public class PlayerInteractListener implements Listener {
|
||||
private final Plugin plugin;
|
||||
private final GameManager gameManager;
|
||||
private final GeneratorManager generatorManager;
|
||||
|
||||
private BiConsumer<Player, Action> onGeneratorInteract;
|
||||
private BiConsumer<Player, Boolean> onAttack;
|
||||
|
|
@ -30,9 +32,10 @@ public class PlayerInteractListener implements Listener {
|
|||
private final Map<UUID, Long> lastClick = new ConcurrentHashMap<>();
|
||||
private static final long COOLDOWN_MS = 200;
|
||||
|
||||
public PlayerInteractListener(Plugin plugin, GameManager gameManager) {
|
||||
public PlayerInteractListener(Plugin plugin, GameManager gameManager, GeneratorManager generatorManager) {
|
||||
this.plugin = plugin;
|
||||
this.gameManager = gameManager;
|
||||
this.generatorManager = generatorManager;
|
||||
}
|
||||
|
||||
public void setOnGeneratorInteract(BiConsumer<Player, Action> h) { this.onGeneratorInteract = h; }
|
||||
|
|
@ -72,11 +75,20 @@ public class PlayerInteractListener implements Listener {
|
|||
|
||||
private void handleRightClick(PlayerInteractEvent event, Player player, BasePlayer bp) {
|
||||
if (event.getClickedBlock() == null) {
|
||||
if (!bp.isKiller() && onGeneratorInteract != null && generatorManager.isInAnyZone(player)) {
|
||||
onGeneratorInteract.accept(player, event.getAction());
|
||||
return;
|
||||
}
|
||||
if (onAttack != null && bp.isKiller()) onAttack.accept(player, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bp.isKiller() && onGeneratorInteract != null && generatorManager.isInAnyZone(player)) {
|
||||
onGeneratorInteract.accept(player, event.getAction());
|
||||
return;
|
||||
}
|
||||
|
||||
String type = event.getClickedBlock().getType().toString();
|
||||
if (type.contains("TRAPDOOR") && onGeneratorInteract != null) onGeneratorInteract.accept(player, event.getAction());
|
||||
if ((type.contains("FENCE") || type.contains("PLANKS")) && onPalletInteract != null && !bp.isKiller()) onPalletInteract.accept(player, true);
|
||||
if (!bp.isKiller() && onRescueAttempt != null) onRescueAttempt.accept(player, true);
|
||||
if (type.contains("CHEST") && onChestInteract != null) onChestInteract.accept(player, true);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package dev.loki.map;
|
||||
|
||||
import dev.loki.data.GeneratorDataManager;
|
||||
import dev.loki.mdbd;
|
||||
import dev.loki.config.LocationsConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
|
|
@ -76,6 +77,23 @@ public class MapBuilder {
|
|||
plugin.getLogger().info("Map built successfully!");
|
||||
}
|
||||
|
||||
public void buildGenerators(GeneratorDataManager dataManager) {
|
||||
List<Location> generators = dataManager.getGenerators();
|
||||
for (int i = 0; i < generators.size(); i++) {
|
||||
Location loc = generators.get(i);
|
||||
if (loc == null) continue;
|
||||
placeGeneratorMarker(loc);
|
||||
}
|
||||
}
|
||||
|
||||
public void placeGeneratorMarker(Location location) {
|
||||
World world = location.getWorld();
|
||||
if (world == null) return;
|
||||
|
||||
world.getBlockAt(location).setType(org.bukkit.Material.SEA_LANTERN);
|
||||
world.getBlockAt(location.clone().add(0, 1, 0)).setType(org.bukkit.Material.REDSTONE_LAMP);
|
||||
}
|
||||
|
||||
public void clearMap(LocationsConfig config) {
|
||||
// Clear all objects (set to air)
|
||||
clearLocations(config.getGenerators());
|
||||
|
|
@ -169,8 +187,8 @@ public class MapBuilder {
|
|||
world.getBlockAt(loc.clone().add(0, 1, 1)).setType(org.bukkit.Material.REDSTONE_LAMP);
|
||||
world.getBlockAt(loc.clone().add(0, 1, -1)).setType(org.bukkit.Material.REDSTONE_LAMP);
|
||||
// Control panel: Lever
|
||||
world.getBlockAt(loc.clone().add(1, 0, 1)).setType(org.bukkit Material.OAK_PLANKS);
|
||||
world.getBlockAt(loc.clone().add(1, 1, 1)).setType(org.bukkit Material.LEVER);
|
||||
world.getBlockAt(loc.clone().add(1, 0, 1)).setType(org.bukkit.Material.OAK_PLANKS);
|
||||
world.getBlockAt(loc.clone().add(1, 1, 1)).setType(org.bukkit.Material.LEVER);
|
||||
}
|
||||
|
||||
private void buildDefaultHook(Location loc) {
|
||||
|
|
@ -181,7 +199,7 @@ public class MapBuilder {
|
|||
world.getBlockAt(loc.clone().add(0, y, 0)).setType(org.bukkit.Material.IRON_BARS);
|
||||
}
|
||||
// Hook at top: Tripwire hook
|
||||
world.getBlockAt(loc.clone().add(0, 3, 0)).setType(org.bukkit Material.TRIPWIRE_HOOK);
|
||||
world.getBlockAt(loc.clone().add(0, 3, 0)).setType(org.bukkit.Material.TRIPWIRE_HOOK);
|
||||
}
|
||||
|
||||
private void buildDefaultPallet(Location loc) {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ import org.bukkit.structure.StructureManager;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class MapTemplate {
|
||||
|
|
@ -27,7 +26,7 @@ public class MapTemplate {
|
|||
|
||||
public boolean loadFromFile(File file) {
|
||||
try {
|
||||
this.structure = structureManager.loadStructure(file.toPath());
|
||||
this.structure = structureManager.loadStructure(file);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to load template: " + name, e);
|
||||
|
|
@ -41,7 +40,7 @@ public class MapTemplate {
|
|||
if (!file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
structureManager.saveStructure(file.toPath(), structure);
|
||||
structureManager.saveStructure(file, structure);
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to save template: " + name, e);
|
||||
}
|
||||
|
|
@ -59,23 +58,24 @@ public class MapTemplate {
|
|||
int maxZ = Math.max(corner1.getBlockZ(), corner2.getBlockZ());
|
||||
|
||||
Location origin = new Location(world, minX, minY, minZ);
|
||||
Location farCorner = new Location(world, maxX, maxY, maxZ);
|
||||
int sizeX = maxX - minX + 1;
|
||||
int sizeY = maxY - minY + 1;
|
||||
int sizeZ = maxZ - minZ + 1;
|
||||
|
||||
this.structure = structureManager.createStructure();
|
||||
structure.fill(origin, sizeX, sizeY, sizeZ, true);
|
||||
structure.fill(origin, farCorner, true);
|
||||
}
|
||||
|
||||
public void place(Location location, boolean includeEntities) {
|
||||
if (structure == null) return;
|
||||
structure.place(location, true, StructureRotation.NONE, Mirror.NONE,
|
||||
0, 1.0f, includeEntities ? 1.0f : 0.0f);
|
||||
0, 1.0f, new Random());
|
||||
}
|
||||
|
||||
public void placeWithRotation(Location location, StructureRotation rotation, Mirror mirror) {
|
||||
if (structure == null) return;
|
||||
structure.place(location, true, rotation, mirror, 0, 1.0f, 0.0f);
|
||||
structure.place(location, true, rotation, mirror, 0, 1.0f, new Random());
|
||||
}
|
||||
|
||||
public void remove(Location location) {
|
||||
|
|
@ -83,15 +83,11 @@ public class MapTemplate {
|
|||
World world = location.getWorld();
|
||||
if (world == null) return;
|
||||
|
||||
Location rel = structure.getRelativePosition();
|
||||
for (int x = 0; x < structure.getSize().getBlockX(); x++) {
|
||||
for (int y = 0; y < structure.getSize().getBlockY(); y++) {
|
||||
for (int z = 0; z < structure.getSize().getBlockZ(); z++) {
|
||||
Location blockLoc = location.clone().add(
|
||||
x - rel.getBlockX(),
|
||||
y - rel.getBlockY(),
|
||||
z - rel.getBlockZ()
|
||||
);
|
||||
org.bukkit.util.Vector size = structure.getSize();
|
||||
for (int x = 0; x < size.getBlockX(); x++) {
|
||||
for (int y = 0; y < size.getBlockY(); y++) {
|
||||
for (int z = 0; z < size.getBlockZ(); z++) {
|
||||
Location blockLoc = location.clone().add(x, y, z);
|
||||
world.getBlockAt(blockLoc).setType(org.bukkit.Material.AIR);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
package dev.loki;
|
||||
|
||||
import dev.loki.command.DBDAdminCommand;
|
||||
import dev.loki.command.DBDCommand;
|
||||
import dev.loki.command.SetupCommand;
|
||||
import dev.loki.config.ConfigManager;
|
||||
import dev.loki.core.GameManager;
|
||||
import dev.loki.data.GeneratorDataManager;
|
||||
import dev.loki.listener.GeneratorSelectListener;
|
||||
import dev.loki.map.MapBuilder;
|
||||
import dev.loki.map.TemplateManager;
|
||||
import dev.loki.world.LobbyManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public final class mdbd extends JavaPlugin {
|
||||
|
|
@ -14,6 +18,9 @@ public final class mdbd extends JavaPlugin {
|
|||
private GameManager gameManager;
|
||||
private TemplateManager templateManager;
|
||||
private MapBuilder mapBuilder;
|
||||
private GeneratorDataManager generatorData;
|
||||
private DBDAdminCommand dbdAdminCommand;
|
||||
private LobbyManager lobbyManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
|
@ -29,6 +36,12 @@ public final class mdbd extends JavaPlugin {
|
|||
|
||||
this.mapBuilder = new MapBuilder(this, templateManager);
|
||||
|
||||
this.generatorData = new GeneratorDataManager(this);
|
||||
|
||||
this.lobbyManager = new LobbyManager(this);
|
||||
this.lobbyManager.createLobbyWorld();
|
||||
this.lobbyManager.createGameWorld();
|
||||
|
||||
this.gameManager = new GameManager(this);
|
||||
|
||||
getCommand("dbd").setExecutor(new DBDCommand(this, gameManager));
|
||||
|
|
@ -36,8 +49,16 @@ public final class mdbd extends JavaPlugin {
|
|||
getCommand("dbdsetup").setExecutor(new SetupCommand(this));
|
||||
getCommand("dbdsetup").setTabCompleter(new SetupCommand(this));
|
||||
|
||||
this.dbdAdminCommand = new DBDAdminCommand(this, generatorData);
|
||||
getCommand("dbdadmin").setExecutor(dbdAdminCommand);
|
||||
getCommand("dbdadmin").setTabCompleter(dbdAdminCommand);
|
||||
|
||||
getServer().getPluginManager().registerEvents(
|
||||
new GeneratorSelectListener(dbdAdminCommand, generatorData), this);
|
||||
|
||||
getLogger().info("Mdbd Plugin enabled successfully!");
|
||||
getLogger().info("Loaded " + templateManager.getAllTemplates().size() + " templates");
|
||||
getLogger().info("Loaded " + generatorData.getCount() + " generators from data");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -49,6 +70,9 @@ public final class mdbd extends JavaPlugin {
|
|||
if (configManager != null) {
|
||||
configManager.saveAllConfigs();
|
||||
}
|
||||
if (generatorData != null) {
|
||||
generatorData.save();
|
||||
}
|
||||
instance = null;
|
||||
}
|
||||
|
||||
|
|
@ -71,4 +95,23 @@ public final class mdbd extends JavaPlugin {
|
|||
public MapBuilder getMapBuilder() {
|
||||
return mapBuilder;
|
||||
}
|
||||
|
||||
public GeneratorDataManager getGeneratorData() {
|
||||
return generatorData;
|
||||
}
|
||||
|
||||
public DBDAdminCommand getDbdAdminCommand() {
|
||||
return dbdAdminCommand;
|
||||
}
|
||||
|
||||
public LobbyManager getLobbyManager() {
|
||||
return lobbyManager;
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
configManager.loadConfigs();
|
||||
templateManager.loadAllTemplates();
|
||||
generatorData.load();
|
||||
getLogger().info("All configs reloaded!");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ package dev.loki;
|
|||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
|
||||
|
||||
class mdbdBootstrap implements PluginBootstrap {
|
||||
public class mdbdBootstrap implements PluginBootstrap {
|
||||
|
||||
public mdbdBootstrap() {}
|
||||
|
||||
@Override
|
||||
public void bootstrap(final BootstrapContext context) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ package dev.loki;
|
|||
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
|
||||
import io.papermc.paper.plugin.loader.PluginLoader;
|
||||
|
||||
class mdbdLoader implements PluginLoader {
|
||||
public class mdbdLoader implements PluginLoader {
|
||||
|
||||
public mdbdLoader() {}
|
||||
|
||||
@Override
|
||||
public void classloader(final PluginClasspathBuilder builder) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
package dev.loki.objective;
|
||||
|
||||
import dev.loki.data.GeneratorDataManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class Generator {
|
||||
private final int id;
|
||||
private final Location location;
|
||||
private final double zoneRadius;
|
||||
private double progress;
|
||||
private boolean isCompleted;
|
||||
private boolean isBlocked;
|
||||
|
|
@ -15,8 +19,13 @@ public class Generator {
|
|||
private boolean wasKicked;
|
||||
|
||||
public Generator(int id, Location location) {
|
||||
this(id, location, GeneratorDataManager.getZoneRadius());
|
||||
}
|
||||
|
||||
public Generator(int id, Location location, double zoneRadius) {
|
||||
this.id = id;
|
||||
this.location = location;
|
||||
this.zoneRadius = zoneRadius;
|
||||
this.progress = 0.0;
|
||||
this.isCompleted = false;
|
||||
this.isBlocked = false;
|
||||
|
|
@ -33,6 +42,20 @@ public class Generator {
|
|||
return location;
|
||||
}
|
||||
|
||||
public double getZoneRadius() {
|
||||
return zoneRadius;
|
||||
}
|
||||
|
||||
public boolean isPlayerInZone(Player player) {
|
||||
if (!player.getWorld().equals(location.getWorld())) return false;
|
||||
return player.getLocation().distance(location) <= zoneRadius;
|
||||
}
|
||||
|
||||
public boolean isLocationInZone(Location loc) {
|
||||
if (!loc.getWorld().equals(location.getWorld())) return false;
|
||||
return loc.distance(location) <= zoneRadius;
|
||||
}
|
||||
|
||||
public double getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
|
@ -107,6 +130,7 @@ public class Generator {
|
|||
return !isCompleted && !isBlocked;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Block getBlock() {
|
||||
return location.getBlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package dev.loki.objective;
|
||||
|
||||
import dev.loki.config.LocationsConfig;
|
||||
import dev.loki.data.GeneratorDataManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -13,19 +14,17 @@ public class GeneratorManager {
|
|||
private final int requiredCount;
|
||||
private int completedCount;
|
||||
|
||||
public GeneratorManager(LocationsConfig locationsConfig, int requiredCount) {
|
||||
public GeneratorManager(GeneratorDataManager dataManager, int requiredCount) {
|
||||
this.generators = new HashMap<>();
|
||||
this.requiredCount = requiredCount;
|
||||
this.completedCount = 0;
|
||||
loadGenerators(locationsConfig);
|
||||
loadGenerators(dataManager);
|
||||
}
|
||||
|
||||
private void loadGenerators(LocationsConfig config) {
|
||||
List<Location> locations = config.getGenerators();
|
||||
int id = 0;
|
||||
for (Location loc : locations) {
|
||||
generators.put(id, new Generator(id, loc));
|
||||
id++;
|
||||
private void loadGenerators(GeneratorDataManager dataManager) {
|
||||
List<Location> locations = dataManager.getGenerators();
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
generators.put(i, new Generator(i, locations.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -35,13 +34,32 @@ public class GeneratorManager {
|
|||
|
||||
public Generator getGeneratorAt(Location location) {
|
||||
for (Generator gen : generators.values()) {
|
||||
if (gen.getLocation().distance(location) < 2.0) {
|
||||
if (gen.isLocationInZone(location)) {
|
||||
return gen;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Generator getNearestGenerator(Location location, double maxDistance) {
|
||||
Generator nearest = null;
|
||||
double nearestDist = maxDistance;
|
||||
|
||||
for (Generator gen : generators.values()) {
|
||||
if (!gen.getLocation().getWorld().equals(location.getWorld())) continue;
|
||||
double dist = gen.getDistance(location);
|
||||
if (dist < nearestDist) {
|
||||
nearestDist = dist;
|
||||
nearest = gen;
|
||||
}
|
||||
}
|
||||
return nearest;
|
||||
}
|
||||
|
||||
public boolean isInAnyZone(Player player) {
|
||||
return getGeneratorAt(player.getLocation()) != null;
|
||||
}
|
||||
|
||||
public List<Generator> getAllGenerators() {
|
||||
return new ArrayList<>(generators.values());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class GeneratorRepair {
|
|||
this.plugin = plugin;
|
||||
this.manager = manager;
|
||||
this.sessions = new HashMap<>();
|
||||
this.skillCheck = new SkillCheck(plugin);
|
||||
this.skillCheck = new SkillCheck(plugin, this);
|
||||
}
|
||||
|
||||
public void startRepair(Player player, Generator generator) {
|
||||
|
|
|
|||
|
|
@ -9,13 +9,15 @@ import java.util.UUID;
|
|||
|
||||
public class SkillCheck {
|
||||
private final mdbd plugin;
|
||||
private final GeneratorRepair generatorRepair;
|
||||
private final Map<UUID, CheckState> activeChecks;
|
||||
|
||||
private static final double ZONE_SIZE = 0.15;
|
||||
private static final double ROTATION_SPEED = 3.0;
|
||||
|
||||
public SkillCheck(mdbd plugin) {
|
||||
public SkillCheck(mdbd plugin, GeneratorRepair generatorRepair) {
|
||||
this.plugin = plugin;
|
||||
this.generatorRepair = generatorRepair;
|
||||
this.activeChecks = new HashMap<>();
|
||||
}
|
||||
|
||||
|
|
@ -58,26 +60,16 @@ public class SkillCheck {
|
|||
|
||||
private void onSuccess(CheckState state) {
|
||||
activeChecks.remove(state.playerId);
|
||||
GeneratorRepair repair = getGeneratorRepair();
|
||||
if (repair != null) {
|
||||
Bukkit.getScheduler().runTask(plugin, () ->
|
||||
repair.onSkillCheckResult(state.playerId, true, state.generator)
|
||||
);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(plugin, () ->
|
||||
generatorRepair.onSkillCheckResult(state.playerId, true, state.generator)
|
||||
);
|
||||
}
|
||||
|
||||
private void onFail(CheckState state) {
|
||||
activeChecks.remove(state.playerId);
|
||||
GeneratorRepair repair = getGeneratorRepair();
|
||||
if (repair != null) {
|
||||
Bukkit.getScheduler().runTask(plugin, () ->
|
||||
repair.onSkillCheckResult(state.playerId, false, state.generator)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private GeneratorRepair getGeneratorRepair() {
|
||||
return null;
|
||||
Bukkit.getScheduler().runTask(plugin, () ->
|
||||
generatorRepair.onSkillCheckResult(state.playerId, false, state.generator)
|
||||
);
|
||||
}
|
||||
|
||||
public boolean isActive(UUID playerId) {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class CorruptInterventionPerk extends BasePerk {
|
|||
|
||||
private void spawnBlockEffect(Player player) {
|
||||
Location loc = player.getLocation();
|
||||
player.getWorld().spawnParticle(Particle.BARRIER, loc.add(0, 1, 0), 5, 0.5, 0.5, 0.5, 0);
|
||||
player.getWorld().spawnParticle(Particle.WITCH, loc.add(0, 1, 0), 5, 0.5, 0.5, 0.5, 0);
|
||||
}
|
||||
|
||||
private void startEffectTimer() {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class BorrowedTimePerk extends BasePerk {
|
|||
if (bukkitPlayer == null) return;
|
||||
|
||||
bukkitPlayer.addPotionEffect(new PotionEffect(
|
||||
PotionEffectType.DAMAGE_RESISTANCE,
|
||||
PotionEffectType.RESISTANCE,
|
||||
ENDURANCE_DURATION_SECONDS * 20,
|
||||
4,
|
||||
false, false, true));
|
||||
|
|
@ -65,7 +65,7 @@ public class BorrowedTimePerk extends BasePerk {
|
|||
public void onRemove(BasePlayer player) {
|
||||
Player bukkitPlayer = player.getPlayer();
|
||||
if (bukkitPlayer != null) {
|
||||
bukkitPlayer.removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE);
|
||||
bukkitPlayer.removePotionEffect(PotionEffectType.RESISTANCE);
|
||||
}
|
||||
sendPerkMessage(player, "Перк деактивирован");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public final class LocationUtil {
|
|||
|
||||
public static boolean hasEntityLineOfSight(Entity from, Entity to, double maxDistance) {
|
||||
if (from == null || to == null) return false;
|
||||
return from.hasLineOfSight(to) && distanceSquared(from.getLocation(), to.getLocation()) <= maxDistance * maxDistance;
|
||||
return hasLineOfSight(from.getLocation(), to.getLocation(), maxDistance);
|
||||
}
|
||||
|
||||
public static boolean isLookingAt(Entity entity, Location target, double angleThreshold) {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ public final class ParticleUtil {
|
|||
|
||||
public static void blood(Location loc) {
|
||||
World w = loc.getWorld(); if (w == null) return;
|
||||
w.spawnParticle(Particle.BLOCK_CRUMBLE, loc, 20, 0.2, 0.2, 0.2, 0,
|
||||
w.spawnParticle(Particle.BLOCK, loc, 20, 0.2, 0.2, 0.2, 0,
|
||||
org.bukkit.Material.REDSTONE_BLOCK.createBlockData());
|
||||
}
|
||||
|
||||
|
|
|
|||
149
src/main/java/dev/loki/world/LobbyManager.java
Normal file
149
src/main/java/dev/loki/world/LobbyManager.java
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
package dev.loki.world;
|
||||
|
||||
import dev.loki.mdbd;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.WorldType;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LobbyManager {
|
||||
private final mdbd plugin;
|
||||
private World lobbyWorld;
|
||||
private World gameWorld;
|
||||
|
||||
public LobbyManager(mdbd plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void createLobbyWorld() {
|
||||
World existing = Bukkit.getWorld("lobby");
|
||||
if (existing != null) {
|
||||
lobbyWorld = existing;
|
||||
plugin.getLogger().info("Lobby world already loaded, using existing");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isNew = !worldFolderExists("lobby");
|
||||
|
||||
WorldCreator creator = new WorldCreator("lobby");
|
||||
creator.generator(new VoidWorldGenerator());
|
||||
creator.type(WorldType.FLAT);
|
||||
creator.environment(World.Environment.NORMAL);
|
||||
creator.generateStructures(false);
|
||||
|
||||
lobbyWorld = creator.createWorld();
|
||||
if (lobbyWorld == null) {
|
||||
plugin.getLogger().severe("Failed to create lobby world!");
|
||||
return;
|
||||
}
|
||||
|
||||
lobbyWorld.setAutoSave(false);
|
||||
lobbyWorld.setMonsterSpawnLimit(0);
|
||||
lobbyWorld.setAnimalSpawnLimit(0);
|
||||
lobbyWorld.setGameRule(GameRule.DO_MOB_SPAWNING, false);
|
||||
lobbyWorld.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
|
||||
lobbyWorld.setGameRule(GameRule.DO_WEATHER_CYCLE, false);
|
||||
lobbyWorld.setGameRule(GameRule.KEEP_INVENTORY, true);
|
||||
lobbyWorld.setGameRule(GameRule.DO_FIRE_TICK, false);
|
||||
lobbyWorld.setGameRule(GameRule.ANNOUNCE_ADVANCEMENTS, false);
|
||||
lobbyWorld.setTime(6000);
|
||||
|
||||
if (isNew) {
|
||||
buildPlatform();
|
||||
}
|
||||
|
||||
lobbyWorld.setSpawnLocation(0, 65, 0);
|
||||
|
||||
if (isNew) {
|
||||
plugin.getLogger().info("Lobby world created with stone platform!");
|
||||
} else {
|
||||
plugin.getLogger().info("Lobby world loaded (platform already exists)");
|
||||
}
|
||||
}
|
||||
|
||||
public void createGameWorld() {
|
||||
World existing = Bukkit.getWorld("game");
|
||||
if (existing != null) {
|
||||
gameWorld = existing;
|
||||
plugin.getLogger().info("Game world already loaded, using existing");
|
||||
return;
|
||||
}
|
||||
|
||||
WorldCreator creator = new WorldCreator("game");
|
||||
creator.environment(World.Environment.NORMAL);
|
||||
creator.generateStructures(false);
|
||||
|
||||
gameWorld = creator.createWorld();
|
||||
if (gameWorld == null) {
|
||||
plugin.getLogger().severe("Failed to create game world!");
|
||||
return;
|
||||
}
|
||||
|
||||
gameWorld.setAutoSave(false);
|
||||
gameWorld.setMonsterSpawnLimit(0);
|
||||
gameWorld.setAnimalSpawnLimit(0);
|
||||
gameWorld.setGameRule(GameRule.DO_MOB_SPAWNING, false);
|
||||
gameWorld.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
|
||||
gameWorld.setGameRule(GameRule.DO_WEATHER_CYCLE, false);
|
||||
gameWorld.setGameRule(GameRule.KEEP_INVENTORY, true);
|
||||
gameWorld.setGameRule(GameRule.DO_FIRE_TICK, false);
|
||||
gameWorld.setGameRule(GameRule.ANNOUNCE_ADVANCEMENTS, false);
|
||||
gameWorld.setTime(6000);
|
||||
|
||||
if (worldFolderExists("game")) {
|
||||
plugin.getLogger().info("Game world loaded");
|
||||
} else {
|
||||
plugin.getLogger().info("Game world created!");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean worldFolderExists(String worldName) {
|
||||
File worldDir = new File(Bukkit.getWorldContainer(), worldName);
|
||||
return worldDir.isDirectory();
|
||||
}
|
||||
|
||||
private void buildPlatform() {
|
||||
int y = 64;
|
||||
|
||||
for (int x = -3; x <= 3; x++) {
|
||||
for (int z = -3; z <= 3; z++) {
|
||||
lobbyWorld.getBlockAt(x, y, z).setType(Material.STONE);
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = -3; x <= 3; x++) {
|
||||
for (int z = -3; z <= 3; z++) {
|
||||
lobbyWorld.getBlockAt(x, y - 1, z).setType(Material.BLACK_STAINED_GLASS);
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = -4; x <= 4; x++) {
|
||||
lobbyWorld.getBlockAt(x, y, -4).setType(Material.OAK_FENCE);
|
||||
lobbyWorld.getBlockAt(x, y, 4).setType(Material.OAK_FENCE);
|
||||
}
|
||||
for (int z = -4; z <= 4; z++) {
|
||||
lobbyWorld.getBlockAt(-4, y, z).setType(Material.OAK_FENCE);
|
||||
lobbyWorld.getBlockAt(4, y, z).setType(Material.OAK_FENCE);
|
||||
}
|
||||
|
||||
lobbyWorld.getBlockAt(0, y + 1, 0).setType(Material.GLOWSTONE);
|
||||
}
|
||||
|
||||
public World getLobbyWorld() {
|
||||
return lobbyWorld;
|
||||
}
|
||||
|
||||
public World getGameWorld() {
|
||||
return gameWorld;
|
||||
}
|
||||
|
||||
public void teleportToLobby(org.bukkit.entity.Player player) {
|
||||
if (lobbyWorld != null) {
|
||||
player.teleport(lobbyWorld.getSpawnLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/main/java/dev/loki/world/VoidWorldGenerator.java
Normal file
14
src/main/java/dev/loki/world/VoidWorldGenerator.java
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package dev.loki.world;
|
||||
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class VoidWorldGenerator extends ChunkGenerator {
|
||||
|
||||
@Override
|
||||
public void generateNoise(@NotNull WorldInfo worldInfo, @NotNull Random random, int chunkX, int chunkZ, @NotNull ChunkData chunkData) {
|
||||
}
|
||||
}
|
||||
|
|
@ -12,12 +12,8 @@ lobby:
|
|||
yaw: 0.0
|
||||
pitch: 0.0
|
||||
|
||||
# Генераторы (7 штук)
|
||||
# Формат: "world,x,y,yaw,pitch"
|
||||
generators: []
|
||||
# Пример:
|
||||
# - "world,100.5,64.0,200.5,0.0,0.0"
|
||||
# - "world,150.5,64.0,250.5,90.0,0.0"
|
||||
# Генераторы — настраиваются через /dbdadmin create generator
|
||||
# и сохраняются в data/generators.yml
|
||||
|
||||
# Крюки (обычно 4-6)
|
||||
hooks: []
|
||||
|
|
@ -49,11 +45,14 @@ survivor-spawns: []
|
|||
|
||||
# ============================================
|
||||
# Команды для настройки:
|
||||
# /dbdsetup set generator - Установить генератор
|
||||
# /dbdsetup set hook - Установить крюк
|
||||
# /dbdsetup set pallet - Установить паллет
|
||||
# /dbdsetup set chest - Установить сундук
|
||||
# /dbdsetup set totem - Установить тотем
|
||||
# /dbdsetup set gate - Установить ворота
|
||||
# /dbdsetup set lobby - Установить лобби
|
||||
# /dbdadmin create generator - Войти в режим выбора генератора (сломайте блок)
|
||||
# /dbdadmin list - Список всех генераторов
|
||||
# /dbdadmin remove <id> - Удалить генератор по ID
|
||||
# /dbdadmin clear - Очистить все генераторы
|
||||
# /dbdsetup set hook - Установить крюк
|
||||
# /dbdsetup set pallet - Установить паллет
|
||||
# /dbdsetup set chest - Установить сундук
|
||||
# /dbdsetup set totem - Установить тотем
|
||||
# /dbdsetup set gate - Установить ворота
|
||||
# /dbdsetup set lobby - Установить лобби
|
||||
# ============================================
|
||||
|
|
|
|||
|
|
@ -1,23 +1,21 @@
|
|||
name: Mdbd
|
||||
version: '${version}'
|
||||
|
||||
main: dev.loki.mdbd
|
||||
bootstrapper: dev.loki.mdbdBootstrap
|
||||
loader: dev.loki.mdbdLoader
|
||||
api-version: '1.20.6'
|
||||
load: POSTWORLD
|
||||
|
||||
authors: [ loki ]
|
||||
api-version: '1.21'
|
||||
|
||||
commands:
|
||||
dbd:
|
||||
description: "Главная команда DBD плагина"
|
||||
usage: "/dbd <join|leave|create|forcestart|stop>"
|
||||
usage: "/dbd <join|leave|create|forcestart|stop|reload>"
|
||||
permission: mdbd.player
|
||||
dbdsetup:
|
||||
description: "Команды настройки карты и объектов"
|
||||
usage: "/dbdsetup <wand|pos1|pos2|save|load|set|build|clear|lobby>"
|
||||
permission: mdbd.admin
|
||||
dbdadmin:
|
||||
description: "Админ-команды для управления генераторами и объектами"
|
||||
usage: "/dbdadmin <create|list|remove|clear>"
|
||||
permission: mdbd.admin
|
||||
|
||||
permissions:
|
||||
mdbd.admin:
|
||||
Loading…
Add table
Add a link
Reference in a new issue