dev #1

Merged
hdvt merged 2 commits from dev into main 2025-11-30 19:48:07 +03:00
43 changed files with 1048 additions and 1354 deletions
Showing only changes of commit c7ca8aad20 - Show all commits

1
.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
BlockAndSeek

14
.idea/discord.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT" />
<option name="description" value="" />
<option name="applicationTheme" value="default" />
<option name="iconsTheme" value="default" />
<option name="button1Title" value="" />
<option name="button1Url" value="" />
<option name="button2Title" value="" />
<option name="button2Url" value="" />
<option name="customApplicationId" value="" />
</component>
</project>

13
.idea/modules/BlockAndSeek.test.iml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration>
</facet>
</component>
</module>

View File

@@ -1,84 +0,0 @@
package hdvtdev.blockAndSeek;
import hdvtdev.blockAndSeek.eventListeners.DefaultEventListener;
import hdvtdev.blockAndSeek.eventListeners.EventListener;
import hdvtdev.blockAndSeek.eventListeners.ForceControlEventListener;
import hdvtdev.blockAndSeek.managers.ConfigManager;
import me.libraryaddict.disguise.LibsDisguises;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.logging.Logger;
public class BlockAndSeek extends JavaPlugin {
private static JavaPlugin javaPlugin;
public static Plugin getInstance() {
return javaPlugin;
}
public static File getPluginDataFolder() {
return javaPlugin.getDataFolder();
}
public static File getServerDataFolder() {
return javaPlugin.getServer().getPluginsFolder().getParentFile();
}
public static InputStream getPluginResource(String resource) {
return javaPlugin.getResource(resource);
}
public static void saveResource(String file) {
javaPlugin.saveResource(file, false);
}
public static Logger getPluginLogger() {
return javaPlugin.getLogger();
}
@Override
public void onEnable() {
javaPlugin = this;
ConfigurationSerialization.registerClass(BlockAndSeekMap.class, "BlockAndSeekMap");
ConfigurationSerialization.registerClass(Config.class, "BlockAndSeekConfig");
LibsDisguises libsDisguises = (LibsDisguises) Bukkit.getPluginManager().getPlugin("LibsDisguises");
if (libsDisguises == null) {
getLogger().severe("LibsDisguises not found! It's required for the plugin to work!");
super.onDisable();
}
try {
ConfigManager.loadAll();
} catch (IOException e) {
getLogger().severe("Failed to save some .yml configs!");
}
PluginCommand command = Objects.requireNonNull(getCommand("blockandseek"));
command.setExecutor(new CommandListener());
PluginManager manager = getServer().getPluginManager();
manager.registerEvents(ConfigManager.getConfig().forceControl() ? new ForceControlEventListener() : new EventListener(), this);
manager.registerEvents(new DefaultEventListener(), this);
}
@Override
public void onDisable() {
}
}

View File

@@ -1,280 +0,0 @@
package hdvtdev.blockAndSeek;
//import com.mojang.brigadier.arguments.StringArgumentType;
//import com.mojang.brigadier.builder.LiteralArgumentBuilder;
//import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import hdvtdev.blockAndSeek.managers.*;
import hdvtdev.blockAndSeek.roulette.RouletteCreator;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.*;
public class CommandListener implements TabExecutor {
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
int argsLen = args.length;
if (argsLen == 0) {
sender.sendMessage(Localization.get("bs-usage"));
return true;
}
switch (args[0]) {
case "test" -> {
if (sender instanceof Player player) {
GamesManager.createGame("dust2");
GamesManager.get("dust2").addPlayer(player);
}
}
case "locale" -> {
if (sender instanceof Player player) {
player.sendMessage(player.locale().toLanguageTag());
player.sendMessage("eq: " + player.locale().toLanguageTag().equals("en-US"));
}
}
case "menu" -> {
if (sender instanceof Player player) {
GuiManager.Menu.open(player);
}
}
case "morph" -> {
if (sender instanceof Player player && args.length == 2) {
Material material = Material.valueOf(args[1].toUpperCase());
PropManager.addPlayerDisguise(player, material.createBlockData());
DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, new ItemStack(material)));
}
}
case "damage" -> {
if (sender instanceof Player player && args.length == 2) {
player.damage(Double.parseDouble(args[1]));
}
}
case "health" -> {
if (sender instanceof Player player && args.length == 2) {
player.setHealth(Double.parseDouble(args[1]));
}
}
case "new" -> {
if (sender instanceof Player player) {
new RouletteCreator(player, List.of(
new BlockAndSeekMap.Block(new ItemStack(Material.STONE), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.DIRT), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.LANTERN), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.TARGET), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.SCULK_SHRIEKER), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.FLOWER_POT), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.AZALEA_LEAVES), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.PUMPKIN), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.MELON), 10),
new BlockAndSeekMap.Block(new ItemStack(Material.DIAMOND_BLOCK), 10)
));
}
}
case "foo" -> {
if (sender instanceof Player player) {
ItemStack foo = new ItemStack(Material.BROWN_DYE);
ItemMeta fooMeta = foo.getItemMeta();
fooMeta.displayName(MiniMessage.miniMessage().deserialize("<gradient:#00FF00:#01A368><bold>SoundMaker3000"));
fooMeta.getPersistentDataContainer().set(Keys.SOUND_ITEM, PersistentDataType.BOOLEAN, true);
foo.setItemMeta(fooMeta);
player.getInventory().addItem(foo);
}
}
case "bbb" -> {
if (sender instanceof Player player) {
PropManager.changePropDirection(player);
}
}
case "container" -> {
if (sender instanceof Player player) {
var container = player.getPersistentDataContainer();
player.sendMessage("containers: " + container.getKeys());
}
}
case "def" -> {
if (sender instanceof Player player) {
player.setVisibleByDefault(true);
player.setInvisible(false);
player.setInvulnerable(false);
player.setGameMode(GameMode.SURVIVAL);
player.setGlowing(false);
player.clearActivePotionEffects();
player.setHealth(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getDefaultValue());
player.setFoodLevel(20);
Utils.setLevelWithBar(player, 0);
DisguiseAPI.undisguiseToAll(player);
PersistentDataContainer dataContainer = player.getPersistentDataContainer();
for (var key : dataContainer.getKeys()) {
dataContainer.remove(key);
}
}
}
case "map" -> {
if (sender.hasPermission("blockandseek.manage")) {
if (argsLen > 1) {
switch (args[1]) {
case "list" -> {
StringBuilder buffer = new StringBuilder(Localization.get("maps-available"));
String listElement = Localization.get("maps-available-element");
Set<String> readyMaps = null; //TODO ConfigManager.getReadyMaps();
for (String map : ConfigManager.getAllMaps()) {
buffer.append("\n").append(listElement.replace("{map}", map).replace("{color-status}",
readyMaps.contains(map) ? "<green>" : "<red>"));
}
sender.sendMessage(miniMessage.deserialize(buffer.toString()));
}
default -> {
if (ConfigManager.getAllMaps().contains(args[1])) {
if (argsLen > 3) {
switch (args[2]) {
case "setduration" -> {
try {
int duration = Integer.parseInt(args[3]);
if (duration > 0) {
sender.sendMessage(args[1]);
var map = MapsManager.getMap(args[1]);
map.setDuration(duration);
MapsManager.saveMap(args[1], map);
sender.sendMessage("duration set");
} else sender.sendMessage("idk");
} catch (NumberFormatException | IOException e) {
sender.sendMessage("idk");
}
}
}
}
}
}
}
} else
sender.sendMessage(Localization.getComponent("not-enough-arguments", "{command}", "/blockandseek map", "{help}", "[MAP NAME | COMMANDS]"));
} else sender.sendMessage(Localization.getComponent("not-enough-permissions"));
}
case "reload" -> {
if (sender.hasPermission("blockandseek.manage")) {
if (argsLen > 1) {
switch (args[1]) {
case "localization" -> {
try {
ConfigManager.load("localization.yml");
sender.sendMessage(Localization.getComponentWithPrefix("successful-reload", "{config}", "localization.yml"));
} catch (IOException e) {
sender.sendMessage(Localization.getComponentWithPrefix("failed-reload", "{config}", "localization.yml", "{e}", e.getMessage()));
}
}
case "maps" -> {
try {
ConfigManager.load(null);
} catch (IOException e) {
throw new RuntimeException(e);
}
sender.sendMessage(Localization.get("maps-reload"));
}
}
} else
sender.sendMessage(Localization.get("not-enough-arguments", "{usage}", "<green>/blockandseek reload <gold>[messages | maps]<white>"));
} else sender.sendMessage(Localization.get("not-enough-permissions"));
}
}
return true;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
return !sender.hasPermission("blockandseek.manage") ? List.of() : switch (args.length) {
case 1 -> List.of("info", "map", "reload");
case 2 -> switch (args[0]) {
case "reload" -> List.of("localization", "config");
case "map" -> {
List<String> mapCommands = new ArrayList<>(MapsManager.getAllMaps());
mapCommands.add("create");
mapCommands.add("list");
yield mapCommands;
}
default -> List.of();
};
case 3 -> {
if (MapsManager.getAllMaps().contains(args[1])) {
yield List.of("status", "setspawn", "setlobby", "setduration", "setminplayers", "setmaxplayers", "addblock", "deleteblock");
}
yield List.of();
}
case 4 -> switch (args[2]) {
case "setspawn", "setlobby" -> {
if (sender instanceof Player player) {
Location location = player.getLocation().toCenterLocation();
yield List.of(String.format("%s %s %s", location.getX(), location.getY(), location.getZ()));
} else yield List.of();
}
case "setduration" -> List.of("[<duration>]");
case "setminplayers", "setmaxplayers" -> List.of("[<count>]");
case "addblock", "removeblock" ->
Arrays.stream(Material.values()).map(Objects::toString).map(String::toLowerCase).toList();
default -> List.of();
};
case 5 -> args[2].equalsIgnoreCase("addblock") ? List.of("[<chance>]") : List.of();
default -> List.of();
};
}
/* TODO
public static void registerCompletions(Commodore commodore, PluginCommand command) {
commodore.register(command, LiteralArgumentBuilder.literal("blockandseek")
.then(RequiredArgumentBuilder.argument("idk", StringArgumentType.greedyString()).suggests((a, b) -> {
b.suggest("sometextidk");
return b.buildFuture();
}).executes(o -> {
System.out.println(23238923);
return 1;
})));
}
*/
}

View File

@@ -1,41 +0,0 @@
package hdvtdev.blockAndSeek;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public record Config(@NotNull Location defaultSpawn, boolean forceControl) implements ConfigurationSerializable {
@Override
public @NotNull Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
map.put("default-spawn", defaultSpawn.serialize());
map.put("force-control", Boolean.valueOf(forceControl));
return map;
}
@NotNull
@SuppressWarnings("unchecked")
public static Config deserialize(@NotNull Map<String, Object> args) {
Map<String, Object> location = (Map<String, Object>) args.get("default-spawn");
List<Integer> cords = location == null || location.isEmpty() ? List.of() : (List<Integer>) location.get("location");
World world = location == null || location.isEmpty() ? null : Bukkit.getWorld((String) location.get("world"));
if (world == null) {
world = Bukkit.createWorld(new WorldCreator("world"));
}
if (cords.isEmpty() || cords.size() < 3) {
Location spawn = world.getSpawnLocation();
cords = List.of((int) spawn.getX(), (int) spawn.getY(), (int) spawn.getZ());
}
return new Config(new Location(world, cords.getFirst(), cords.get(1), cords.get(2)), (Boolean) args.get("force-control"));
}
}

View File

@@ -1,109 +0,0 @@
package hdvtdev.blockAndSeek;
import hdvtdev.blockAndSeek.managers.ConfigManager;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.kyori.adventure.title.Title;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Map;
public class Localization {
private static volatile Map<String, Map<String, String>> localization = Collections.unmodifiableMap(ConfigManager.getLocalization());
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
private static final PlainTextComponentSerializer plainText = PlainTextComponentSerializer.plainText();
private static final Component prefix = miniMessage.deserialize("<gold>[<bold><blue>BlockAndSeek<reset><gold>] ");
private static final Component empty = Component.empty();
public static void update() {
localization = Collections.unmodifiableMap(ConfigManager.getLocalization());
}
public static ItemStack translateItem(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull String... replacements) {
ItemStack translatedItem = itemStack.clone();
ItemMeta itemMeta = translatedItem.getItemMeta();
String key = plainText.serialize(itemMeta.displayName());
itemMeta.displayName(getComponent(player.locale().toLanguageTag(), key, replacements));
translatedItem.setItemMeta(itemMeta);
return translatedItem;
}
public static void sendMessage(@NotNull Iterable<Player> players, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
for (Player player : players) {
sendMessage(player, addPrefix, key, replacements);
}
}
public static void sendMessage(@NotNull Player player, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
Component component = getComponent(player.locale().toLanguageTag(), key, replacements);
player.sendMessage(addPrefix ? prefix.append(component) : component);
}
public static void sendActionBar(@NotNull Iterable<Player> players, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
for (Player player : players) {
sendActionBar(player, addPrefix, key, replacements);
}
}
@Deprecated
public static String get(String a) {
return "";
}
@Deprecated
public static Component getComponent(String a) {
return empty;
}
@Deprecated
public static Component getComponentWithPrefix(String... a) {
return empty;
}
public static void sendActionBar(@NotNull Player player, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
Component component = getComponent(player.locale().toLanguageTag(), key, replacements);
player.sendActionBar(addPrefix ? prefix.append(component) : component);
}
public static void sendTitle(@NotNull Iterable<Player> players, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
for (Player player : players) {
sendTitle(player, addPrefix, key, replacements);
}
}
public static void sendTitle(@NotNull Player player, boolean addPrefix, @NotNull String key, @NotNull String... replacements) {
Component component = getComponent(player.locale().toLanguageTag(), key, replacements);
player.showTitle(Title.title(addPrefix ? prefix.append(component) : component, empty));
}
public static @NotNull Component getComponent(@NotNull Player p, @NotNull String key, @NotNull String... replacements) {
return getComponent(p.locale().toLanguageTag(), key, replacements);
}
public static @NotNull Component getComponent(@NotNull String lang, @NotNull String key, @NotNull String... replacements) {
return miniMessage.deserialize(get(lang, key, replacements));
}
public static @NotNull String get(@NotNull String lang, @NotNull String key, @NotNull String... replacements) {
String s = localization.getOrDefault(lang, localization.get("en-US")).get(key);
if (s != null) {
for (int i = 0; i < replacements.length; i += 2) {
s = s.replace(replacements[i], replacements[i + 1]);
}
} else return "Unknown localization: " + key;
return s;
}
}

View File

@@ -1,279 +0,0 @@
package hdvtdev.blockAndSeek.eventListeners;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.Keys;
import hdvtdev.blockAndSeek.Utils;
import hdvtdev.blockAndSeek.managers.GamesManager;
import hdvtdev.blockAndSeek.managers.GuiManager;
import hdvtdev.blockAndSeek.managers.PropManager;
import hdvtdev.blockAndSeek.roulette.RouletteCreator;
import org.bukkit.Bukkit;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDismountEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static hdvtdev.blockAndSeek.Utils.isInOneTeam;
import static hdvtdev.blockAndSeek.Utils.playerInGame;
public class DefaultEventListener implements Listener {
private static final BukkitScheduler scheduler = Bukkit.getScheduler();
private static final Set<Player> coolDown = ConcurrentHashMap.newKeySet();
@Deprecated(forRemoval = true)
private static final ConcurrentHashMap<Player, BukkitTask> tasks = new ConcurrentHashMap<>();
@Deprecated(forRemoval = true)
public static void createTask(Player player, BukkitTask bukkitTask) {
tasks.put(player, bukkitTask);
}
@Deprecated(forRemoval = true)
public static void stopTask(Player player) {
BukkitTask task = tasks.remove(player);
task.cancel();
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (player.getVehicle() instanceof ArmorStand armorStand) {
PersistentDataContainer armorStandContainer = armorStand.getPersistentDataContainer();
if (armorStandContainer.has(Keys.FROZEN_PLAYER)) {
armorStandContainer.remove(Keys.FROZEN_PLAYER);
armorStand.remove();
}
}
}
@EventHandler
public void onBlockDamage(BlockDamageEvent event) {
Player player = event.getPlayer();
if (player.getPersistentDataContainer().has(Keys.SEEKER)) {
if (PropManager.unfreeze(event.getBlock().getBlockData())) {
event.setCancelled(true);
} else {
player.damage(2);
Utils.setLevelWithBar(player, (int) Math.round(player.getHealth() * 5));
}
}
}
@EventHandler
public void onRightClick(PlayerInteractEvent event) {
if (event.getHand() != EquipmentSlot.HAND) return;
Action action = event.getAction();
Player player = event.getPlayer();
if (action.isRightClick() && !coolDown.contains(player)) {
ItemStack itemInHand = player.getInventory().getItemInMainHand();
ItemMeta meta = itemInHand.getItemMeta();
if (meta != null) {
PersistentDataContainer itemData = meta.getPersistentDataContainer();
if (itemData.has(Keys.FREEZE_ITEM) && playerInGame(player)) {
coolDown.add(player);
scheduler.runTaskLater(BlockAndSeek.getInstance(), () -> coolDown.remove(player), 3L);
PropManager.freeze(player);
event.setCancelled(true);
} else if (itemData.has(Keys.MENU_ITEM)) {
GuiManager.Menu.open(player);
event.setCancelled(true);
} else if (itemData.has(Keys.LEAVE_ITEM)) {
String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING);
GamesManager.get(game).removePlayer(player);
event.setCancelled(true);
} else if (itemData.has(Keys.FACE_CHANGING_ITEM)) {
PropManager.changePropDirection(player);
event.setCancelled(true);
}
}
}
}
@EventHandler
public void onEntityDismount(EntityDismountEvent event) {
Player player = (Player) event.getEntity();
if (event.getDismounted() instanceof ArmorStand armorStand && armorStand.getPersistentDataContainer().has(Keys.FROZEN_PLAYER)) {
PropManager.freeze(player);
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
PersistentDataContainer container = player.getPersistentDataContainer();
String arena = container.get(Keys.GAME, PersistentDataType.STRING);
if (arena != null) {
GamesManager.get(arena).removePlayer(player);
PropManager.removePlayerDisguise(player);
}
}
@EventHandler
public void onPlayerDeath(PlayerDeathEvent event) {
Player player = event.getPlayer();
String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING);
if (game != null) {
event.deathMessage(null);
event.setDroppedExp(0);
event.getDrops().clear();
scheduler.runTask(BlockAndSeek.getInstance(), () -> GamesManager.get(game).setSpectator(player, player.getKiller()));
//without scheduler strange things are happening idk
}
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
InventoryHolder holder = event.getInventory().getHolder();
if (holder instanceof RouletteCreator rouletteCreator) {
Boolean isClosedByPlayer = rouletteCreator.isClosedByPlayer();
if (isClosedByPlayer != null) {
RouletteCreator.Task task = rouletteCreator.getTask();
if (isClosedByPlayer) {
if (!task.rouletteTask().isCancelled()) {
Utils.firstDisguise(player, rouletteCreator.randomPropItem());
} else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem());
task.cancelBoth();
} else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem());
}
}
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
Inventory inventory = event.getClickedInventory();
if (inventory != null) {
InventoryHolder holder = inventory.getHolder();
int slot = event.getSlot();
ItemStack item = inventory.getItem(slot);
if (holder instanceof RouletteCreator rouletteCreator) {
RouletteCreator.Task task = rouletteCreator.getTask();
if (task.rouletteTask().isCancelled()) {
if (slot == 21 || slot == 23 || slot == 25) {
task.autoCloseTask().cancel();
Utils.firstDisguise(player, inventory.getItem(slot));
rouletteCreator.closeInventory();
}
event.setCancelled(true);
return;
} else {
if (slot == 36) {
task.cancelBoth();
Utils.firstDisguise(player, rouletteCreator.randomPropItem());
rouletteCreator.closeInventory();
event.setCancelled(true);
return;
}
}
}
if (item != null) {
ItemMeta meta = item.getItemMeta();
if (meta != null) {
PersistentDataContainer itemData = meta.getPersistentDataContainer();
if (itemData.has(Keys.GAME_PAGE)) {
GuiManager.Menu.Games.open(player);
event.setCancelled(true);
} else if (itemData.has(Keys.GAME)) {
String game = itemData.get(Keys.GAME, PersistentDataType.STRING);
if (game != null) {
GamesManager.get(game).addPlayer(player);
event.setCancelled(true);
}
}
}
}
}
//TODO MOVE TO EVENT LISTENER
if (player.getPersistentDataContainer().has(Keys.GAME)) {
event.setCancelled(true);
}
}
@EventHandler
public void onRegainHealth(EntityRegainHealthEvent event) {
if (event.getEntity() instanceof Player player) {
PersistentDataContainer container = player.getPersistentDataContainer();
if (container.has(Keys.SEEKER)) {
event.setCancelled(true);
} else if (container.has(Keys.HIDER)) {
if (!PropManager.isPlayerDisguised(player)) event.setCancelled(true);
}
}
}
@EventHandler
public void onPlayerDamage(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) {
if (isInOneTeam(damager, victim)) {
event.setCancelled(true);
} else if (victim.getPersistentDataContainer().has(Keys.SEEKER)) {
event.setDamage(0);
} else if (damager.getPersistentDataContainer().has(Keys.SEEKER)) {
double maxHealth = 20.0;
double currentHealth = damager.getHealth();
if (currentHealth < maxHealth) {
double newHealth = Math.min(currentHealth + event.getDamage(), maxHealth);
damager.setHealth(newHealth);
Utils.setLevelWithBar(damager, (int) Math.round(damager.getHealth() * 5));
}
}
}
}
}

View File

@@ -1,134 +0,0 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import hdvtdev.blockAndSeek.Config;
import hdvtdev.blockAndSeek.Localization;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class ConfigManager {
private static volatile Map<String, Map<String, String>> localization;
private static volatile Config config;
private static Map<String, BlockAndSeekMap> maps = new ConcurrentHashMap<>();
private static final File mapsFile = new File(BlockAndSeek.getPluginDataFolder(), "maps.yml");
public static Config getConfig() {
return config;
}
public static Set<String> getAllMaps() {
return YamlConfiguration.loadConfiguration(mapsFile).getKeys(false);
}
public static void loadAll() throws IOException {
load("config.yml");
load("localization.yml");
load("maps.yml");
}
public static void load(String file) throws IOException {
File conf = new File(BlockAndSeek.getPluginDataFolder(), file);
YamlConfiguration defaultConfiguration = YamlConfiguration.loadConfiguration(
new InputStreamReader(BlockAndSeek.getPluginResource(file)));
if (!conf.exists()) {
BlockAndSeek.saveResource(file);
/*
switch (file) {
case "config.yml" -> config = defaultConfiguration.getSerializable("config", Config.class);
case "localization.yml" -> {
Map<String, Map<String, String>> confMap = new HashMap<>();
Map<String, String> lang = new HashMap<>();
for (String key : defaultConfiguration.getConfigurationSection("en-US").getKeys(false)) {
lang.put(key, defaultConfiguration.getString(key, "NULL"));
}
confMap.put("en-US", lang);
localization = confMap;
Localization.update();
}
}
*/
}
switch (file) {
case "config.yml" -> loadConfig(conf, defaultConfiguration);
case "localization.yml" -> loadLocalization(conf, defaultConfiguration);
case "maps.yml" -> MapsManager.loadMaps();
}
}
private static void loadConfig(File configurationFile, YamlConfiguration defaultConfiguration) {
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configurationFile);
configuration.setDefaults(defaultConfiguration);
config = configuration.getSerializable("config", Config.class);
}
private static void loadLocalization(File configurationFile, YamlConfiguration defaultConfiguration) throws IOException {
Map<String, Map<String, String>> confMap = new HashMap<>();
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configurationFile);
ConfigurationSection defaultSection = defaultConfiguration.getConfigurationSection("en-US");
for (String langKey : configuration.getKeys(false)) {
ConfigurationSection configSection = configuration.getConfigurationSection(langKey);
Map<String, String> langMap = new HashMap<>();
if (configSection != null) {
for (String key : defaultSection.getKeys(false)) {
if (configSection.contains(key)) {
langMap.put(key, configSection.getString(key, defaultSection.getString(key, "NULL")));
} else {
String value = defaultSection.getString(key, "NULL");
configSection.set(key, value);
langMap.put(key, value);
}
}
} else {
BlockAndSeek.getPluginLogger().warning("No any language found in the configuration! Using default en-US.");
for (String key : defaultSection.getKeys(false)) {
langMap.put(key, defaultSection.getString(key, "NULL"));
}
}
confMap.put(langKey, langMap);
}
configuration.save(configurationFile);
localization = confMap;
Localization.update();
}
public static Map<String, Map<String, String>> getLocalization() {
return localization;
}
}

View File

@@ -1,115 +0,0 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeekGame;
import hdvtdev.blockAndSeek.Keys;
import hdvtdev.blockAndSeek.Localization;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class GuiManager {
private static final ItemStack filler1 = new ItemStack(Material.ORANGE_STAINED_GLASS_PANE);
private static final ItemStack filler2 = new ItemStack(Material.BLUE_STAINED_GLASS_PANE);
private static final ItemStack filler3 = new ItemStack(Material.GREEN_STAINED_GLASS_PANE);
private GuiManager() {
}
public static void fill(Inventory inventory) {
int size = inventory.getSize();
for (int i = 0; i < size; i++) {
inventory.setItem(i, i % 2 == 0 ? filler1 : filler2);
}
}
public static void fillAlt(Inventory inventory) {
int size = inventory.getSize();
for (int i = 0; i < size; i++) {
inventory.setItem(i, i % 2 == 0 ? filler3 : filler2);
}
}
public static class Menu implements InventoryHolder {
public static final Menu instance = new Menu();
private Menu() {
}
public static void open(Player player) {
Inventory inventory = Bukkit.createInventory(instance, 27, Localization.getComponent(player, "menu-item"));
inventory.setItem(13, Localization.translateItem(player, ItemManager.getGamesPageItem()));
player.openInventory(inventory);
}
@Override
public @NotNull Inventory getInventory() {
return Bukkit.createInventory(instance, 27, Component.text("raw"));
}
public static class Games implements InventoryHolder {
private static final ItemStack defaultGameItem = new ItemStack(Material.CLOCK);
private Games() {
}
public static void open(Player player) {
Inventory gamesMenu = Bukkit.createInventory(new Games(), 45, Localization.getComponent(player, "games-page-item"));
for (String game : GamesManager.getAvailableGames()) {
BlockAndSeekGame blockAndSeekGame = GamesManager.get(game);
ItemStack gameItem = defaultGameItem.clone();
ItemMeta meta = gameItem.getItemMeta();
meta.getPersistentDataContainer().set(Keys.GAME, PersistentDataType.STRING, game);
meta.displayName(Component.text("game-name"));
meta.lore(List.of(Localization.getComponent(
player,
"game-player-count",
"{players}", String.valueOf(blockAndSeekGame.playerCount()),
"{max-players}", String.valueOf(blockAndSeekGame.maxPlayers())
)));
gameItem.setItemMeta(meta);
gamesMenu.addItem(Localization.translateItem(player, gameItem, "{name}", game));
}
if (player.hasPermission("blockandseek.manage")) {
gamesMenu.setItem(44, ItemManager.getCreateGameButton());
}
player.openInventory(gamesMenu);
}
@Override
public @NotNull Inventory getInventory() {
return Bukkit.createInventory(null, 9);
}
public static abstract class Maps implements InventoryHolder {
}
}
}
}

View File

@@ -1,53 +0,0 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class MapsManager {
private static volatile Map<String, BlockAndSeekMap> allMaps = new ConcurrentHashMap<>();
private static final Map<String, BlockAndSeekMap> readyMaps = new ConcurrentHashMap<>();
private static final File mapsFile = new File(BlockAndSeek.getPluginDataFolder(), "maps.yml");
public static Set<String> getAllMaps() {
return allMaps.keySet();
}
public static BlockAndSeekMap getMap(String name) {
return allMaps.get(name);
}
public static void saveMap(String name, BlockAndSeekMap map) throws IOException {
var conf = YamlConfiguration.loadConfiguration(mapsFile);
if (conf.contains(name)) conf.set(name, null);
conf.set(name, map);
conf.save(mapsFile);
}
public static void loadMaps() {
Map<String, BlockAndSeekMap> confMap = new ConcurrentHashMap<>();
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(mapsFile);
for (String map : configuration.getKeys(false)) {
BlockAndSeekMap blockAndSeekMap = configuration.getSerializable(map, BlockAndSeekMap.class, BlockAndSeekMap.defaultMap());
if (blockAndSeekMap.isReady()) readyMaps.put(map, blockAndSeekMap);
confMap.put(map, blockAndSeekMap);
}
allMaps = confMap;
}
}

View File

@@ -1,159 +0,0 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.Keys;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.util.Vector;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class PropManager {
private static final Map<Player, FreezeData> frozenPlayers = new ConcurrentHashMap<>();
private static final Map<Player, BlockData> playerDisguise = new ConcurrentHashMap<>();
private static final Map<BlockData, Player> disguisePlayer = new ConcurrentHashMap<>();
private static final Disguise hideDisguise = new MiscDisguise(DisguiseType.LLAMA_SPIT);
private static final Vector zeroVelocity = new Vector(0, 0, 0);
public static boolean isPlayerDisguised(Player player) {
return frozenPlayers.containsKey(player);
}
public static void addPlayerDisguise(Player player, BlockData blockData) {
disguisePlayer.put(blockData, player);
playerDisguise.put(player, blockData);
}
public static void removePlayerDisguise(Player player) {
disguisePlayer.remove(playerDisguise.remove(player));
}
public static void changePropDirection(Player player) {
if (frozenPlayers.containsKey(player)) {
Block block = player.getLocation().getBlock();
BlockData blockData = block.getBlockData();
if (blockData instanceof Directional directional) {
BlockFace face = switch (directional.getFacing()) {
case NORTH -> BlockFace.EAST;
case EAST -> BlockFace.SOUTH;
case SOUTH -> BlockFace.WEST;
case WEST -> directional.getFaces().contains(BlockFace.UP) ? BlockFace.UP : BlockFace.NORTH;
case UP -> BlockFace.DOWN;
case DOWN -> BlockFace.NORTH;
default -> null;
};
if (face != null && directional.getFaces().contains(face)) {
directional.setFacing(face);
block.setBlockData(blockData);
}
}
}
}
public static void unfreezeIfFrozen(Player player) {
Location location = player.getLocation();
FreezeData data = frozenPlayers.remove(player);
if (data != null) {
unfreeze(player, location, data);
}
}
public static boolean unfreeze(BlockData blockData) {
Player player = disguisePlayer.get(blockData);
if (player != null) {
freeze(player);
return true;
} else return false;
}
private static void unfreeze(Player player, Location location, FreezeData data) {
Location blockLocation = location.getBlock().getLocation();
location.getWorld().setBlockData(blockLocation, data.blockData);
player.getPersistentDataContainer().remove(Keys.FROZEN_PLAYER);
player.setFreezeTicks(0);
data.armorStand.remove();
player.setInvulnerable(false);
Keys.NO_COLLIDE_TEAM.removeEntry(player.getName());
if (data.disguise != null) DisguiseAPI.disguiseToAll(player, data.disguise);
}
public static boolean freeze(Player player) {
Location location = player.getLocation();
FreezeData data = frozenPlayers.remove(player);
if (data != null) {
unfreeze(player, location, data);
} else {
Block block = location.getBlock();
BlockData blockData = block.getBlockData();
Location blockLocation = block.getLocation();
Location centerLocation = blockLocation.toCenterLocation();
Location upperBlockLocation = centerLocation.clone();
upperBlockLocation.setY(upperBlockLocation.getY() + 0.25);
if (!upperBlockLocation.getBlock().isSolid() && !blockLocation.getBlock().isSolid()) {
location.getWorld().setBlockData(blockLocation, playerDisguise.get(player));
centerLocation.setY(centerLocation.getY() - 0.85);
player.setVelocity(zeroVelocity);
player.setInvulnerable(true);
player.getPersistentDataContainer().set(Keys.FROZEN_PLAYER, PersistentDataType.BOOLEAN, true);
Keys.NO_COLLIDE_TEAM.addEntry(player.getName());
ArmorStand armorStand = location.getWorld().spawn(centerLocation, ArmorStand.class, stand -> {
stand.setVisible(false);
stand.setVisible(false);
stand.setCollidable(false);
stand.setGravity(true);
stand.setSmall(true);
stand.setCanMove(false);
stand.addPassenger(player);
stand.getPersistentDataContainer().set(Keys.FROZEN_PLAYER, PersistentDataType.BOOLEAN, true);
stand.setInvulnerable(true);
});
Disguise disguise = DisguiseAPI.getDisguise(player);
DisguiseAPI.disguiseToAll(player, hideDisguise);
player.setFreezeTicks(40);
frozenPlayers.put(player, new FreezeData(armorStand, blockData, disguise));
} else return false;
}
return true;
}
private record FreezeData(ArmorStand armorStand, BlockData blockData, Disguise disguise) {
}
}

View File

@@ -0,0 +1,182 @@
package hdvtdev.blockAndSeek;
import hdvtdev.blockAndSeek.eventListeners.RequiredEventListener;
import hdvtdev.blockAndSeek.eventListeners.EventListener;
import hdvtdev.blockAndSeek.eventListeners.ForceControlEventListener;
import me.libraryaddict.disguise.LibsDisguises;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.incendo.cloud.Command;
import org.incendo.cloud.bukkit.CloudBukkitCapabilities;
import org.incendo.cloud.bukkit.parser.PlayerParser;
import org.incendo.cloud.execution.ExecutionCoordinator;
import org.incendo.cloud.paper.LegacyPaperCommandManager;
import org.incendo.cloud.parser.standard.IntegerParser;
import org.incendo.cloud.parser.standard.StringParser;
import java.io.File;
import java.util.Objects;
import java.util.logging.Logger;
public class BlockAndSeek extends JavaPlugin {
private static JavaPlugin javaPlugin;
private static LegacyPaperCommandManager<CommandSender> commandManager;
private static final String perm = "blockandseek.manage";
public static Plugin getInstance() {
return javaPlugin;
}
public static File getPluginDataFolder() {
return javaPlugin.getDataFolder();
}
public static File getServerDataFolder() {
return javaPlugin.getServer().getPluginsFolder().getParentFile();
}
public static void saveResource(String file) {
javaPlugin.saveResource(file, false);
}
public static Logger getPluginLogger() {
return javaPlugin.getLogger();
}
@Override
public void onEnable() {
javaPlugin = this;
LibsDisguises libsDisguises = (LibsDisguises) Bukkit.getPluginManager().getPlugin("LibsDisguises");
if (libsDisguises == null) {
getLogger().severe("LibsDisguises not found! It's required for the plugin to work!");
super.onDisable();
}
this.init();
if (!Config.loadConfig()) getPluginLogger().warning("Failed to load BlockAndSeek config.toml! Using default config...");
PluginCommand command = Objects.requireNonNull(getCommand("blockandseek"));
PluginManager manager = getServer().getPluginManager();
manager.registerEvents(Config.forceControl() ? new ForceControlEventListener() : new EventListener(), this);
manager.registerEvents(new RequiredEventListener(), this);
}
private void init() {
try {
File dataFolder = getDataFolder();
if (!dataFolder.exists()) {
dataFolder.mkdirs();
}
File mapsFolder = new File(dataFolder, "maps");
if (!mapsFolder.exists()) {
mapsFolder.mkdirs();
}
File langsFolder = new File(dataFolder, "languages");
if (!langsFolder.exists()) {
langsFolder.mkdirs();
}
File defaultLangFile = new File(langsFolder, "en_US.yml");
if (!defaultLangFile.exists()) {
saveResource("languages/en_US.yml", false);
}
commandManager = LegacyPaperCommandManager.createNative(
this,
ExecutionCoordinator.simpleCoordinator()
);
if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) {
try {
commandManager.registerBrigadier();
} catch (IllegalStateException ignored) {
}
}
this.registerCommands();
} catch (Exception e) {
getLogger().severe("Cloud err: " + e.getMessage());
e.printStackTrace();
}
}
private void registerCommands() {
Command.Builder<CommandSender> root = commandManager.commandBuilder("blockandseek");
commandManager.command(root
.literal("reload")
.permission(perm)
.handler(context -> {
})
);
commandManager.command(root
.literal("inttest")
.required("text", IntegerParser.integerParser(0, 64))
.handler(context -> {
String text = context.get("text");
context.sender().sendMessage(text);
})
);
commandManager.command(root
.literal("map")
.permission(perm)
.required("map", StringParser.stringParser())
.required("action", StringParser.stringParser())
.handler(context -> {
Player target = context.get("target");
int amount = context.getOrDefault("amount", 1);
})
);
}
}

View File

@@ -0,0 +1,113 @@
package hdvtdev.blockAndSeek;
import org.bukkit.*;
import org.bukkit.block.data.AnaloguePowerable;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Openable;
import org.bukkit.block.data.Powerable;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@ApiStatus.Experimental
public class BlocksGenerator {
private static boolean isSupported(Material type, BlockData data) {
if (type.isAir() || type.hasGravity() || !type.isSolid()) {
return false;
}
if (data instanceof Powerable
|| data instanceof Openable
|| data instanceof AnaloguePowerable) {
return false;
}
return switch (type) {
case CACTUS, FARMLAND,
TNT, DISPENSER, DROPPER, HOPPER,
PISTON, STICKY_PISTON, OBSERVER,
COMMAND_BLOCK, REPEATING_COMMAND_BLOCK,
CHAIN_COMMAND_BLOCK,
SCULK_SENSOR, SCULK_SHRIEKER,
DAYLIGHT_DETECTOR, JUKEBOX,
TURTLE_EGG, DRAGON_EGG,
BAMBOO, BAMBOO_SAPLING,
CAKE, LECTERN, COMPOSTER,
CAMPFIRE, SOUL_CAMPFIRE,
BEEHIVE, BEE_NEST
-> false;
default -> true;
};
}
public static void getSortedBlockStats(Location center, int chunkRadius, Consumer<List<Map.Entry<Material, Long>>> callback) {
World world = center.getWorld();
if (world == null) return;
List<ChunkSnapshot> snapshots = new ArrayList<>();
int centerX = center.getBlockX() >> 4;
int centerZ = center.getBlockZ() >> 4;
for (int x = centerX - chunkRadius; x <= centerX + chunkRadius; x++) {
for (int z = centerZ - chunkRadius; z <= centerZ + chunkRadius; z++) {
if (world.isChunkLoaded(x, z)) {
Chunk chunk = world.getChunkAt(x, z);
snapshots.add(chunk.getChunkSnapshot(false, false, false));
}
}
}
new BukkitRunnable() {
@Override
public void run() {
Map<Material, Long> counts = new HashMap<>();
int minH = world.getMinHeight();
int maxH = world.getMaxHeight();
for (ChunkSnapshot snap : snapshots) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = minH; y < maxH; y++) {
BlockData data = snap.getBlockData(x, y, z);
Material type = data.getMaterial();
if (isSupported(type, data)) {
counts.put(type, counts.getOrDefault(type, 0L) + 1);
}
}
}
}
}
List<Map.Entry<Material, Long>> sortedList = new ArrayList<>(counts.entrySet());
sortedList.sort(Map.Entry.comparingByValue());
new BukkitRunnable() {
@Override
public void run() {
callback.accept(sortedList);
}
}.runTask(BlockAndSeek.getInstance());
}
}.runTaskAsynchronously(BlockAndSeek.getInstance());
}
}

View File

@@ -0,0 +1,58 @@
package hdvtdev.blockAndSeek;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class CommandBuilder {
private final List<Node> forest = new ArrayList<>();
public Node addNode(String name) {
Node node = new Node(name);
forest.add(node);
return node;
}
@Nullable
public String tryGet(String fullPath) {
return null;
}
public static void printTree(Node node, String indent) {
System.out.println(indent + "- " + node.getName());
for (Node child : node.getChildren()) {
printTree(child, indent + " ");
}
}
public static class Node {
private final String name;
private final List<Node> children;
public Node(String name) {
this.name = name;
this.children = new ArrayList<>();
}
public void addChild(Node child) {
this.children.add(child);
}
public List<Node> getChildren() {
return children;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
}

View File

@@ -0,0 +1,21 @@
package hdvtdev.blockAndSeek;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class CommandListener implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
return false;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
return List.of();
}
}

View File

@@ -0,0 +1,80 @@
package hdvtdev.blockAndSeek;
import eu.okaeri.configs.ConfigManager;
import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import eu.okaeri.configs.annotation.Exclude;
import eu.okaeri.configs.serdes.commons.SerdesCommons;
import eu.okaeri.configs.yaml.bukkit.YamlBukkitConfigurer;
import eu.okaeri.configs.yaml.bukkit.serdes.SerdesBukkit;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.WorldCreator;
import java.io.File;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
public class Config extends OkaeriConfig {
@Exclude
private static final AtomicReference<Config> config = new AtomicReference<>(new Config());
@Comment("Server options.")
private Server server = new Server(false);
@Comment("Spawn location. Useless if the Server.forceControl is false.")
private Location spawn = Objects.requireNonNull(Bukkit.createWorld(new WorldCreator("world"))).getSpawnLocation();
@Comment("Show hidden BlockAndSeek commands.")
private boolean enableDebugCommands = false;
public static boolean debugEnabled() {
return config.get().enableDebugCommands;
}
public static boolean forceControl() {
return config.get().server.forceControl;
}
public static Location spawn() {
return config.get().spawn;
}
public static boolean loadConfig() {
try {
Config conf = ConfigManager.create(Config.class, (it) -> {
it.withConfigurer(
new YamlBukkitConfigurer(),
new SerdesBukkit(),
new SerdesCommons()
);
it.withBindFile(new File(BlockAndSeek.getPluginDataFolder(), "config.yml"));
it.withLogger(BlockAndSeek.getPluginLogger());
it.saveDefaults();
});
config.setRelease(conf);
} catch (Exception e) {
BlockAndSeek.getPluginLogger().severe("Failed to load config.yml: " + e.getMessage());
return false;
}
return true;
}
private static class Server {
private boolean forceControl = false;
public Server(boolean forceControl) {
this.forceControl = forceControl;
}
public boolean isForceControl() {
return forceControl;
}
}
}

View File

@@ -0,0 +1,12 @@
package hdvtdev.blockAndSeek;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.InventoryHolder;
public interface GuiHolder extends InventoryHolder {
void onClick(InventoryClickEvent event);
default void showInventory(Player player) {
player.openInventory(getInventory());
}
}

View File

@@ -20,6 +20,10 @@ public class Keys {
public static final NamespacedKey HIDER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekHider");
public static final NamespacedKey SEEKER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekSeeker");
public static final NamespacedKey LANG_KEY = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekLangKey");
public static final Team NO_COLLIDE_TEAM;
static {

View File

@@ -0,0 +1,83 @@
package hdvtdev.blockAndSeek;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
public final class Localization {
private Localization() {}
private static final String defaultLanguage = "en_US";
private static final MiniMessage mm = MiniMessage.miniMessage();
private static final AtomicReference<Map<String, Map<String, String>>> translations = new AtomicReference<>();
public static Component get(Player player, String key, String... placeholders) {
return get(player.locale().toString(), key, placeholders);
}
public static Component get(String lang, String key, String... placeholders) {
String raw = translations.get().get(lang).getOrDefault(key, "?" + key + "?");
if (placeholders.length % 2 == 0) {
for (int i = 0; i < placeholders.length; i++) {
raw = raw.replace(placeholders[i], placeholders[++i]);
}
} else BlockAndSeek.getPluginLogger().warning("Wrong amount of placeholders for key: " + key);
return mm.deserialize(raw);
}
public static ItemStack translateItem(Player player, ItemStack itemStack, String key) {
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(get(player, key));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public static boolean loadTranslations() {
/*
Path path = BlockAndSeek.getPluginDataFolder().toPath().resolve("translations");
if (Files.notExists(path)) {
try {
Files.createDirectories(path);
} catch (IOException e) {
BlockAndSeek.getPluginLogger().severe("Failed to create \"translations\" dir: " + e);
return false;
}
}
File[] files = path.toFile().listFiles();
if (files != null) {
for (File file : files) {
String lang = file.getName().split(".toml")[0];
Map<String, String> translation = new HashMap<>();
for (Map.Entry<String, Object> entry : new Toml().read(file).entrySet()) {
translation.put(entry.getKey(), entry.getValue().toString());
}
translations.get().put(lang, translation);
}
} else {
BlockAndSeek.getPluginLogger().severe("Failed to load translations! " + path + " returned null.");
}
*/
return true;
}
}

View File

@@ -1,12 +1,20 @@
package hdvtdev.blockAndSeek;
import hdvtdev.blockAndSeek.managers.PropManager;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher;
import org.bukkit.Bukkit;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public final class Utils {
@@ -28,15 +36,17 @@ public final class Utils {
return player.getPersistentDataContainer().has(Keys.GAME);
}
public static void firstDisguise(Player player, ItemStack prop) {
DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, prop));
PropManager.addPlayerDisguise(player, prop.getType().createBlockData());
}
public static boolean hasPermsToDamage(Player p1, Player p2) {
PersistentDataContainer c1 = p1.getPersistentDataContainer();
PersistentDataContainer c2 = p2.getPersistentDataContainer();
return (c1.has(Keys.SEEKER) || c1.has(Keys.HIDER)) && (c2.has(Keys.SEEKER) || c2.has(Keys.HIDER));
}
public static void clearPlayer(Player p) {
PersistentDataContainer container = p.getPersistentDataContainer();
container.remove(Keys.SEEKER);
container.remove(Keys.HIDER);
}
}

View File

@@ -8,6 +8,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerJoinEvent;
@@ -58,6 +59,7 @@ public class ForceControlEventListener implements Listener {
@EventHandler
public void onPlayerDamage(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) {
if (!Utils.hasPermsToDamage(damager, victim)) {
event.setCancelled(true);
@@ -65,5 +67,14 @@ public class ForceControlEventListener implements Listener {
}
}
@EventHandler
public void onFallDamage(EntityDamageEvent e) {
if (e.getEntity() instanceof Player) {
if (e.getCause() == EntityDamageEvent.DamageCause.FALL) {
e.setCancelled(true);
}
}
}
}

View File

@@ -0,0 +1,98 @@
package hdvtdev.blockAndSeek.eventListeners;
import hdvtdev.blockAndSeek.Keys;
import hdvtdev.blockAndSeek.Utils;
import hdvtdev.blockAndSeek.GuiHolder;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDismountEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.EquipmentSlot;
import static hdvtdev.blockAndSeek.Utils.isInOneTeam;
public class RequiredEventListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
}
@EventHandler
public void onBlockDamage(BlockDamageEvent event) {
}
@EventHandler
public void onRightClick(PlayerInteractEvent event) {
if (event.getHand() != EquipmentSlot.HAND) return;
}
@EventHandler
public void onEntityDismount(EntityDismountEvent event) {
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
}
@EventHandler
public void onPlayerDeath(PlayerDeathEvent event) {
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
if (e.getInventory().getHolder() instanceof GuiHolder gui) {
e.setCancelled(true);
gui.onClick(e);
}
}
@EventHandler
public void onRegainHealth(EntityRegainHealthEvent event) {
}
@EventHandler
public void onPlayerDamage(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) {
if (isInOneTeam(damager, victim)) {
event.setCancelled(true);
} else if (victim.getPersistentDataContainer().has(Keys.SEEKER)) {
event.setDamage(0);
} else if (damager.getPersistentDataContainer().has(Keys.SEEKER)) {
double maxHealth = 20.0;
double currentHealth = damager.getHealth();
if (currentHealth < maxHealth) {
double newHealth = Math.min(currentHealth + event.getDamage(), maxHealth);
damager.setHealth(newHealth);
Utils.setLevelWithBar(damager, (int) Math.round(damager.getHealth() * 5));
}
}
}
}
}

View File

@@ -1,8 +1,6 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekGame;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import hdvtdev.blockAndSeek.objects.BlockAndSeekGame;
import org.bukkit.Bukkit;
import org.bukkit.WorldCreator;
import org.bukkit.entity.Player;
@@ -32,16 +30,7 @@ public class GamesManager {
public static @Nullable String createGame(String name) {
if (games.containsKey(name)) return name; //TODO use copy or create copy
if (Bukkit.getWorld(name) == null) {
if (new File(BlockAndSeek.getServerDataFolder(), name).exists()) {
Bukkit.createWorld(new WorldCreator(name));
} else return null;
}
BlockAndSeekMap map = MapsManager.getMap(name);
BlockAndSeekGame game = new BlockAndSeekGame(name, map);
games.put(name, game);
return null;
}

View File

@@ -34,41 +34,34 @@ public class ItemManager {
static {
ItemMeta freezeMeta = freezeItem.getItemMeta();
freezeMeta.displayName(Component.text("freeze-item"));
freezeMeta.getPersistentDataContainer().set(Keys.FREEZE_ITEM, PersistentDataType.BOOLEAN, true);
freezeItem.setItemMeta(freezeMeta);
ItemMeta faceChangingMeta = faceChangingItem.getItemMeta();
faceChangingMeta.displayName(Component.text("face-changing-item"));
faceChangingMeta.getPersistentDataContainer().set(Keys.FACE_CHANGING_ITEM, PersistentDataType.BOOLEAN, true);
faceChangingItem.setItemMeta(faceChangingMeta);
ItemMeta swordMeta = seekerSword.getItemMeta();
swordMeta.displayName(Component.text("seeker-sword"));
swordMeta.addEnchant(Enchantment.DAMAGE_ALL, 2, false);
swordMeta.setUnbreakable(true);
swordMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_ATTRIBUTES);
seekerSword.setItemMeta(swordMeta);
ItemMeta menuMeta = menuItem.getItemMeta();
menuMeta.displayName(Component.text("menu-item"));
menuMeta.getPersistentDataContainer().set(Keys.MENU_ITEM, PersistentDataType.BOOLEAN, true);
menuMeta.addEnchant(Enchantment.ARROW_INFINITE, 1, true);
menuMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
menuItem.setItemMeta(menuMeta);
ItemMeta gamesMeta = games.getItemMeta();
gamesMeta.displayName(Component.text("games-page-item"));
gamesMeta.getPersistentDataContainer().set(Keys.GAME_PAGE, PersistentDataType.BOOLEAN, true);
games.setItemMeta(gamesMeta);
ItemMeta leaveMeta = leaveItem.getItemMeta();
leaveMeta.displayName(Component.text("leave-item"));
leaveMeta.getPersistentDataContainer().set(Keys.LEAVE_ITEM, PersistentDataType.BOOLEAN, true);
leaveItem.setItemMeta(leaveMeta);
ItemMeta createGameButtonMeta = createGameButton.getItemMeta();
createGameButtonMeta.displayName(Component.text("create-game-item"));
createGameButton.setItemMeta(createGameButtonMeta);
@@ -82,12 +75,12 @@ public class ItemManager {
public static void setSeekerSet(Player seeker) {
PlayerInventory inventory = seeker.getInventory();
inventory.clear();
inventory.addItem(Localization.translateItem(seeker, seekerSword));
inventory.addItem(Localization.translateItem(seeker, seekerSword, "seeker_sword"));
ItemStack[] armor = new ItemStack[]{
Localization.translateItem(seeker, seekerBoots),
Localization.translateItem(seeker, seekerLeggings),
Localization.translateItem(seeker, seekerChestplate),
Localization.translateItem(seeker, seekerHelmet)
Localization.translateItem(seeker, seekerBoots, "seeker_boots"),
Localization.translateItem(seeker, seekerLeggings, "seeker_leggings"),
Localization.translateItem(seeker, seekerChestplate, "seeker_chestplate"),
Localization.translateItem(seeker, seekerHelmet, "seeker_helmet")
};
inventory.setArmorContents(armor);
@@ -109,11 +102,11 @@ public class ItemManager {
public static void defaultInventory(Player player) {
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.addItem(Localization.translateItem(player, menuItem));
inventory.addItem(Localization.translateItem(player, menuItem, "menu_item"));
}
public static ItemStack getFaceChangingItem() {
return faceChangingItem;
public static void giveFaceChangingItem(Player player) {
player.getInventory().addItem(Localization.translateItem(player, faceChangingItem, "face_changing_item"));
}
public static ItemStack getLeaveItem() {

View File

@@ -0,0 +1,54 @@
package hdvtdev.blockAndSeek.managers;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.incendo.cloud.suggestion.Suggestion;
import org.incendo.cloud.suggestion.SuggestionProvider;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public final class MapsManager {
private MapsManager() {
}
public static SuggestionProvider<CommandSender> worldSuggestions = (context, input) ->
CompletableFuture.supplyAsync(() -> {
List<Suggestion> suggestions = new ArrayList<>();
File container = Bukkit.getWorldContainer();
File[] files = container.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory() && new File(file, "level.dat").exists()) {
suggestions.add(Suggestion.suggestion(file.getName()));
}
}
}
return suggestions;
});
public static SuggestionProvider<CommandSender> mapSuggestions = (context, input) ->
CompletableFuture.supplyAsync(() -> {
List<Suggestion> suggestions = new ArrayList<>();
File container = new File(Bukkit.getPluginsFolder(), "maps");
File[] files = container.listFiles();
if (files != null) {
for (File file : files) {
String name = file.getName();
if (file.isFile() && name.endsWith(".toml")) {
suggestions.add(Suggestion.suggestion(name.replace(".toml", ""))); //baddd
}
}
}
return suggestions;
});
}

View File

@@ -0,0 +1,76 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeek;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public final class PropManager {
private final Map<UUID, PropData> players = new HashMap<>();
public PropState freezeOrUnfreeze(Player player) {
UUID uuid = player.getUniqueId();
PropData propData = players.remove(uuid);
Location location = player.getLocation();
Block originalBlock = location.getBlock();
if (propData != null) {
originalBlock.setBlockData(propData.blockData);
} else {
BlockData originalBlockData = originalBlock.getBlockData();
BlockData disguiseBlockData = getPlayerDisguiseData(player);
players.put(uuid, new PropData(null, originalBlockData, null));
}
return PropState.FAILED;
}
@Nullable
private static BlockData getPlayerDisguiseData(Player player) {
Disguise disguise = DisguiseAPI.getDisguise(player);
if (disguise instanceof MiscDisguise miscDisguise && miscDisguise.getType() == DisguiseType.FALLING_BLOCK) {
FallingBlockWatcher watcher = (FallingBlockWatcher) miscDisguise.getWatcher();
return watcher.getBlockData();
}
return null;
}
public enum PropState {
FROZEN,
UNFROZEN,
FAILED
}
private record PropData(ArmorStand armorStand, BlockData blockData, Disguise disguise) {
}
}

View File

@@ -0,0 +1,57 @@
package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.objects.BlockAndSeekGame;
import java.util.*;
public class StateManager {
private final Map<UUID, BlockAndSeekGame.PlayerType> playerToState = new HashMap<>();
private final Map<BlockAndSeekGame.PlayerType, Set<UUID>> stateToPlayers = new HashMap<>();
public void setPlayerState(UUID uuid, BlockAndSeekGame.PlayerType newState) {
BlockAndSeekGame.PlayerType oldState = playerToState.get(uuid);
if (oldState != null && oldState.equals(newState)) {
return;
}
if (oldState != null) {
removeUuidFromStateSet(oldState, uuid);
}
playerToState.put(uuid, newState);
stateToPlayers.computeIfAbsent(newState, k -> new HashSet<>()).add(uuid);
}
public int playerCount() {
return playerToState.size();
}
public BlockAndSeekGame.PlayerType getState(UUID uuid) {
return playerToState.get(uuid);
}
public Set<UUID> getPlayersInState(BlockAndSeekGame.PlayerType state) {
return Collections.unmodifiableSet(stateToPlayers.getOrDefault(state, Collections.emptySet()));
}
public void removePlayer(UUID uuid) {
BlockAndSeekGame.PlayerType oldState = playerToState.remove(uuid);
if (oldState != null) {
removeUuidFromStateSet(oldState, uuid);
}
}
private void removeUuidFromStateSet(BlockAndSeekGame.PlayerType state, UUID uuid) {
Set<UUID> uuids = stateToPlayers.get(state);
if (uuids != null) {
uuids.remove(uuid);
if (uuids.isEmpty()) {
stateToPlayers.remove(state);
}
}
}
}

View File

@@ -2,7 +2,9 @@ package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.BlockAndSeek;
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;

View File

@@ -0,0 +1,38 @@
package hdvtdev.blockAndSeek.menus;
import hdvtdev.blockAndSeek.Localization;
import hdvtdev.blockAndSeek.GuiHolder;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class GamesMenu implements GuiHolder {
private final Inventory inventory;
public GamesMenu(Player player) {
Component title = Localization.get(player, "games_menu");
this.inventory = Bukkit.createInventory(this, 54, title);
initInventory();
}
private void initInventory() {
}
@Override
public void onClick(InventoryClickEvent event) {
}
@Override
public @NotNull Inventory getInventory() {
return inventory;
}
}

View File

@@ -0,0 +1,43 @@
package hdvtdev.blockAndSeek.objects;
import hdvtdev.blockAndSeek.managers.StateManager;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.*;
public class BlockAndSeekGame {
private final BlockAndSeekMap map;
private final World world;
private final StateManager stateManager = new StateManager();
public BlockAndSeekGame(BlockAndSeekMap blockAndSeekMap) {
this.map = blockAndSeekMap;
this.world = Objects.requireNonNull(Bukkit.getWorld(blockAndSeekMap.world()));
}
public boolean addPlayer(Player player) {
if (stateManager.playerCount() < map.maxPlayers()) {
stateManager.setPlayerState(player.getUniqueId(), PlayerType.NONE);
return true;
}
return false;
}
public void removePlayer(Player player) {
stateManager.removePlayer(player.getUniqueId());
}
public enum PlayerType {
NONE,
PROP,
SEEKER,
SPECTATOR
}
}

View File

@@ -0,0 +1,17 @@
package hdvtdev.blockAndSeek.objects;
import org.bukkit.Bukkit;
import org.bukkit.World;
public record BlockAndSeekMap(String world, Cords spawn, Cords lobby,
int minPlayers, int maxPlayers, int duration, int seekerSpawnDelay, int delayBeforeEnd) {
public static void prepareWorld(World world) {
if (Integer.parseInt(Bukkit.getMinecraftVersion().replaceAll("[^0-9]", "")) >= 1215) {
String cmd = "execute in " + world.getKey() + " run gamerule locatorBar true";
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
}
}
}

View File

@@ -0,0 +1,4 @@
package hdvtdev.blockandseek.objects;
public interface GamePhase {
}

View File

@@ -0,0 +1,9 @@
package hdvtdev.blockAndSeek.objects;
import org.bukkit.inventory.ItemStack;
public record PropBlock(ItemStack block, int chance) {
public PropBlock(ItemStack block, Rarity rarity) {
this(block, rarity.toChance());
}
}

View File

@@ -0,0 +1,23 @@
package hdvtdev.blockAndSeek.objects;
public enum Rarity {
COMMON,// 38%
UNCOMMON,// 27%
RARE,// 19%
EPIC,// 10%
MYTHIC,// 4%
LEGENDARY; // 2%
public int toChance() {
return switch (this.ordinal()) {
case 1 -> 27;
case 2 -> 19;
case 3 -> 10;
case 4 -> 4;
case 5 -> 2;
default -> 38;
};
}
}

View File

@@ -1,8 +1,5 @@
package hdvtdev.blockAndSeek.roulette;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import hdvtdev.blockAndSeek.Localization;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
@@ -18,7 +15,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/*
public final class RouletteCreator implements InventoryHolder {
@@ -167,3 +164,6 @@ public final class RouletteCreator implements InventoryHolder {
}
*/

View File

@@ -1,12 +1,11 @@
package hdvtdev.blockAndSeek.roulette;
import com.lewdev.probabilitylib.ProbabilityCollection;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
/*
public class RouletteGenerator {
private final ProbabilityCollection<ItemStack> probabilityCollection = new ProbabilityCollection<>();
@@ -25,3 +24,5 @@ public class RouletteGenerator {
}
*/

View File

@@ -1,5 +1,7 @@
package hdvtdev.blockAndSeek.roulette;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
@@ -7,7 +9,7 @@ public class RouletteList<T> {
private final List<T> items;
private int currentIndex;
public RouletteList(List<T> items) {
public RouletteList(@NotNull List<T> items) {
this.items = Objects.requireNonNull(items);
this.currentIndex = 0;
if (items.isEmpty()) {

View File

@@ -1,19 +0,0 @@
config:
==: hdvtdev.blockAndSeek.Config # <-- DO NOT CHANGE THIS FIELD!!!
# A place to teleport players to after the game is over
# Example:
# default-spawn:
# - world: "your world"
# location:
# - 0 #x
# - 60 #y
# - 0 #z
default-spawn: { }
# If force-control set to true plugin will control typical aspects such as
# disabling breaking blocks, disabling damage in lobbies, etc.
# WARN: DO NOT USE THIS WITH OTHER PLUGINS THAT PROVIDE SIMILAR FUNCTIONALITY
force-control: false
# planned
# auto-update: false

View File

View File

@@ -1,40 +0,0 @@
en-US:
#Maps
maps-available: "<gold>Available maps: <white>"
maps-available-element: "- {color-status}{map}<white>"
map-lobby-sidebar: "<bold><gradient:#FFFF00:#FFD700:#FFA500>{map}"
not-enough-permissions: "<red><bold>You do not have permission to run this command."
not-enough-arguments: "<red><bold>Too few arguments to run command {command}. Arguments example: {help}"
successful-reload: "<green>Successfully reloaded <yellow><u>{config}<green>."
failed-reload: "<red>Failed to reload <yellow><u>{config}<red>. Error: {e}"
seekers-won: "<bold><yellow>Seekers <red>won!"
hiders-won: "<bold><yellow>Hiders <green>won!"
hiders-solo-win: "<bold><yellow>{hider} <green>won this game!"
hider-was-found: "<yellow><bold>{hider}<reset><gold> was found by <red><bold>{seeker}"
hider-died: "<yellow><bold>{hider}<reset><gold> somehow died xd"
game-time-left: "<gold>Time left: <yellow>{time}<gold>s"
game-players-count: "<yellow>{players} <gold>of <yellow>{max-players}"
player-join: "<yellow><bold>{player} <reset><gold>joined. <yellow><bold>{players}"
player-leave: "<yellow><bold>{player} <reset><gold>leaved. <yellow><bold>{players}"
game-title: "<bold><gold>{title}"
wait-time-left: "<gold>Game starts in: <yellow><bold>{time}s"
#items
freeze-item: "<gradient:#084CFB:#ADF3FD><bold>Freeze"
seeker-armor: "<gradient:#8B0000:#B22222:#DC143C><bold>Seeker armor"
menu-item: "<gradient:#FFD700:#FFF200:#FFFF00><bold>BlockAndSeek Menu"
games-page-item: "<gradient:#006400:#228B22:#00FF7F><bold>Games"
create-game-item: "<green><bold>Create new game"
game-name: "<green>{name}"
game-player-count: "<yellow>{players}<gold> of <yellow>{max-players}<gold> players"
leave-item: "<red>Leave game"
roulette-title: "<bold><gold>Props Roulette"

View File

@@ -1 +0,0 @@
# DO NOT edit this file manually! Use plugin commands to edit maps instead.