majority of bug fixes

This commit is contained in:
hdvt
2025-07-02 17:49:15 +03:00
parent 118f503011
commit 611ac6c213
18 changed files with 810 additions and 369 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,3 @@
/.gradle/
/build/
/gradle/
/bin/

View File

@@ -1,11 +1,14 @@
package hdvtdev.blockAndSeek;
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;
@@ -34,10 +37,6 @@ public class BlockAndSeek extends JavaPlugin {
return javaPlugin.getResource(resource);
}
public static void saveResource(File file) {
saveResource(file.getAbsolutePath());
}
public static void saveResource(String file) {
javaPlugin.saveResource(file, false);
}
@@ -46,17 +45,13 @@ public class BlockAndSeek extends JavaPlugin {
return javaPlugin.getLogger();
}
public static PluginCommand getCmd(String name) {
return javaPlugin.getCommand(name);
}
@Override
public void onEnable() {
javaPlugin = this;
ConfigurationSerialization.registerClass(BlockAndSeekMap.class, "BlockAndSeekMap");
ConfigurationSerialization.registerClass(Config.class, "BlockAndSeekConfig");
LibsDisguises libsDisguises = (LibsDisguises) Bukkit.getPluginManager().getPlugin("LibsDisguises");
@@ -71,20 +66,15 @@ public class BlockAndSeek extends JavaPlugin {
getLogger().severe("Failed to save some .yml configs!");
}
getLogger().warning(ConfigManager.getConfig().toString());
PluginCommand command = Objects.requireNonNull(getCommand("blockandseek"));
command.setExecutor(new CommandListener());
/* TODO
if (CommodoreProvider.isSupported()) {
CommandListener.registerCompletions(CommodoreProvider.getCommodore(this), command);
}
*/
getServer().getPluginManager().registerEvents(new EventListener(), this);
PluginManager manager = getServer().getPluginManager();
if (ConfigManager.getConfig().forceControl()) manager.registerEvents(new ForceControlEventListener(), this);
manager.registerEvents(new EventListener(), this);
}

View File

@@ -1,14 +1,23 @@
package hdvtdev.blockAndSeek;
import hdvtdev.blockAndSeek.managers.ConfigManager;
import hdvtdev.blockAndSeek.managers.FreezeManager;
import hdvtdev.blockAndSeek.managers.GamesManager;
import hdvtdev.blockAndSeek.managers.ItemManager;
import hdvtdev.blockAndSeek.roulette.RouletteCreator;
import me.libraryaddict.disguise.DisguiseAPI;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -17,117 +26,255 @@ public class BlockAndSeekGame {
private final ConcurrentHashMap<Player, PlayerType> players = new ConcurrentHashMap<>();
private final AtomicBoolean started = new AtomicBoolean(false);
private final String name;
private final int maxPlayers;
private final BlockAndSeekMap map;
private final Location lobby;
private final Location spawn;
private final String name;
public BlockAndSeekGame(String name, int maxPlayers, List<Integer> lobby) {
public BlockAndSeekGame(String name, BlockAndSeekMap map) {
this.map = map;
World world = Bukkit.getWorld(name);
world.setTime(1000);
world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
world.setStorm(false);
world.setGameRule(GameRule.DO_WEATHER_CYCLE, false);
this.name = name;
this.maxPlayers = maxPlayers;
this.lobby = new Location(Bukkit.getWorld(name), lobby.getFirst(), lobby.get(1), lobby.get(2));
}
public List<Player> getHiders() {
return players.entrySet().stream().filter(e -> Objects.equals(e.getValue(), PlayerType.HIDER)).map(Map.Entry::getKey).toList();
}
public void preEnd() {
for (Player hider : getHiders()) {
FreezeManager.unfreezeIfFrozen(hider);
FreezeManager.removePlayerDisguise(hider);
DisguiseAPI.undisguiseToAll(hider);
hider.getInventory().clear();
hider.setGlowing(true);
}
for (Player player : getPlayers()) {
player.setInvulnerable(true);
player.setVisibleByDefault(true);
}
}
public void end() {
for (Player hider : getHiders()) {
FreezeManager.removePlayerDisguise(hider);
DisguiseAPI.undisguiseToAll(hider);
}
for (Player player : players.keySet()) {
player.teleport(lobby);
player.getPersistentDataContainer().remove(Keys.PLAYER);
player.setGameMode(GameMode.SURVIVAL);
player.setInvulnerable(false);
player.setGlowing(false);
}
}
public boolean addPlayer(Player player) {
if (started.get() || playerCount() + 1 > maxPlayers) {
return false;
}
player.getPersistentDataContainer().set(Keys.PLAYER, PersistentDataType.STRING, name);
player.teleport(lobby);
players.put(player, PlayerType.HIDER);
return true;
}
public void removePlayer(Player player) {
players.remove(player);
}
public void setSpectator(Player player) {
players.put(player, PlayerType.SPECTATOR);
player.setGameMode(GameMode.SPECTATOR);
}
public Set<Player> getPlayers() {
return players.keySet();
}
public Player getLastHider() {
for (Map.Entry<Player, PlayerType> entry : players.entrySet()) {
if (entry.getValue() == PlayerType.HIDER) return entry.getKey();
}
return null;
}
public int seekersCount() {
return (int) players.values().stream().filter(f -> f.equals(PlayerType.SEEKER)).count();
}
public int hidersCount() {
return (int) players.values().stream().filter(f -> f.equals(PlayerType.HIDER)).count();
this.lobby = map.getLobbyLocation(world);
this.spawn = map.getSpawnLocation(world);
this.startBukkitTask();
}
public int playerCount() {
return players.size();
}
public void start() {
public int maxPlayers() {
return map.getMaxPlayers();
}
public boolean addPlayer(Player player) {
if (!started.get()) {
players.put(player, PlayerType.HIDER);
player.getPersistentDataContainer().set(Keys.GAME, PersistentDataType.STRING, name);
player.teleport(lobby);
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.setItem(8, Localization.translateItem(player, ItemManager.getLeaveItem()));
player.setGameMode(GameMode.SURVIVAL);
player.setInvulnerable(true);
player.setHealth(20.0);
player.setFoodLevel(20);
Localization.sendMessage(
players.keySet(),
true,
"player-join",
"{player}", player.getName(),
"{players}", players.size() + "/" + map.getMaxPlayers()
);
return true;
} else return false;
}
public void removePlayer(Player player) {
players.remove(player);
DisguiseAPI.undisguiseToAll(player);
player.getInventory().clear();
player.setGameMode(GameMode.SURVIVAL);
player.getPersistentDataContainer().remove(Keys.GAME);
Config config = ConfigManager.getConfig();
if (config.forceControl()) ItemManager.defaultInventory(player);
player.teleport(config.defaultSpawn());
Localization.sendMessage(
players.keySet(),
true,
"player-leave",
"{player}", player.getName(),
"{players}", started.get() ? "" : players.size() + "/" + map.getMaxPlayers()
);
}
public void setSpectator(Player hider, @Nullable Player seeker) {
hider.spigot().respawn();
hider.teleport(hider.getLastDeathLocation());
players.put(hider, PlayerType.SPECTATOR);
hider.setGameMode(GameMode.SPECTATOR);
Localization.sendMessage(
players.keySet(),
true,
seeker == null ? "hider-died" : "hider-was-found",
"{hider}", hider.getName(),
"{seeker}", seeker == null ? "" : seeker.getName()
);
}
private long getHidersCount() {
return players.values().stream().filter(type -> type == PlayerType.HIDER).count();
}
private List<Player> getSeekers() {
return players.entrySet().stream().filter(entry -> entry.getValue() == PlayerType.SEEKER).map(Map.Entry::getKey).toList();
}
private List<Player> getHiders() {
return players.entrySet().stream().filter(entry -> entry.getValue() == PlayerType.HIDER).map(Map.Entry::getKey).toList();
}
private Player getLastHider() {
return players.keySet().iterator().next();
}
private void start() {
started.set(true);
selectRandomSeekers((int) Math.round(players.size() * 0.25));
List<Player> hiders = getHiders();
for (Player hider : hiders) {
hider.getPersistentDataContainer().set(Keys.HIDER, PersistentDataType.BOOLEAN, true);
hider.teleport(spawn);
hider.setInvulnerable(false);
PlayerInventory inventory = hider.getInventory();
inventory.clear();
inventory.addItem(Localization.translateItem(hider, ItemManager.getFreezeItem()));
RouletteCreator.createRoulette(hider, null, true, map.getBlocks());
}
}
public boolean isStarted() {
return started.get();
private void end(boolean force) {
GamesManager.remove(name);
if (!force) {
Location serverLobby = ConfigManager.getConfig().defaultSpawn();
boolean defaultInventory = ConfigManager.getConfig().forceControl();
for (Player player : players.keySet()) {
PersistentDataContainer container = player.getPersistentDataContainer();
container.remove(Keys.HIDER);
container.remove(Keys.SEEKER);
container.remove(Keys.GAME);
DisguiseAPI.undisguiseToAll(player);
if (defaultInventory) ItemManager.defaultInventory(player);
player.setGlowing(false);
player.setInvulnerable(false);
player.setVisibleByDefault(true);
player.setGameMode(GameMode.SURVIVAL);
player.teleport(serverLobby);
}
}
}
public Player selectRandomSeeker() {
return selectRandomSeekers(1).getFirst();
private void preEnd() {
for (Player hider : getHiders()) {
hider.getInventory().clear();
FreezeManager.unfreezeIfFrozen(hider);
hider.setGlowing(true);
hider.setInvulnerable(true);
}
}
public List<Player> selectRandomSeekers(int count) {
public void selectRandomSeekers(int count) {
ArrayList<Player> playerList = new ArrayList<>(players.keySet());
Collections.shuffle(playerList);
List<Player> seekers = playerList.subList(0, Math.min(count, playerList.size()));
for (Player seeker : seekers) players.put(seeker, PlayerType.SEEKER);
return seekers;
for (Player seeker : seekers) {
players.put(seeker, PlayerType.SEEKER);
ItemManager.setSeekerSet(seeker);
seeker.setInvulnerable(false);
seeker.getPersistentDataContainer().set(Keys.SEEKER, PersistentDataType.BOOLEAN, true);
}
}
private void startBukkitTask() {
new BukkitRunnable() {
int waitTime = 30;
final int defaultWaitTime = waitTime;
int duration = map.getDuration();
final int seekerDeploy = duration - 15;
@Override
public void run() {
if (waitTime != 0) {
int playerSize = players.size();
if (playerSize >= map.getMinPlayers()) {
if (waitTime % 5 == 0 || waitTime <= 5) {
Localization.sendMessage(
players.keySet(),
true,
"wait-time-left",
"{time}", String.valueOf(waitTime)
);
}
waitTime--;
} else if (playerSize == 0) {
end(true);
this.cancel();
} else if (waitTime != defaultWaitTime) {
waitTime = defaultWaitTime;
}
} else {
if (!started.get()) {
start();
} else {
if (players.isEmpty()) end(false);
if (duration > 0 && getHidersCount() == 0) {
Localization.sendTitle(
players.keySet(),
false,
"seekers-won"
);
duration = -1;
}
if (duration == seekerDeploy) {
for (Player seeker : getSeekers()) {
seeker.teleport(spawn);
}
}
if (duration == 0) {
preEnd();
if (getHidersCount() == 1) {
Localization.sendTitle(
players.keySet(),
false,
"hiders-solo-win",
"{hider}", getLastHider().getName()
);
} else {
Localization.sendTitle(
players.keySet(),
false,
"hiders-won"
);
}
duration--; // уменьшаем только один раз
} else if (duration > 0) {
Localization.sendActionBar(
players.keySet(),
false,
"game-time-left",
"{time}", String.valueOf(duration)
);
duration--;
} else if (duration == -10) {
this.cancel();
end(false);
} else {
duration--;
}
}
}
}
}.runTaskTimer(BlockAndSeek.getInstance(), 0L, 20L);
}
private enum PlayerType {
SEEKER,
HIDER,

View File

@@ -1,10 +1,13 @@
package hdvtdev.blockAndSeek;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -35,6 +38,10 @@ public class BlockAndSeekMap implements ConfigurationSerializable {
return spawn;
}
public Location getSpawnLocation(@Nullable World world) {
return new Location(world, spawn.getFirst(), spawn.get(1), spawn.get(2));
}
public void setSpawn(List<Integer> spawn) {
this.spawn = spawn;
}
@@ -43,6 +50,10 @@ public class BlockAndSeekMap implements ConfigurationSerializable {
return lobby;
}
public Location getLobbyLocation(@Nullable World world) {
return new Location(world, lobby.getFirst(), lobby.get(1), lobby.get(2));
}
public void setLobby(List<Integer> lobby) {
this.lobby = lobby;
}

View File

@@ -5,12 +5,15 @@ package hdvtdev.blockAndSeek;
//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;
@@ -73,9 +76,21 @@ public class CommandListener implements TabExecutor {
DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, new ItemStack(material)));
}
}
case "armor" -> {
case "new" -> {
if (sender instanceof Player player) {
player.getInventory().setArmorContents(ItemManager.getSeekerArmor());
RouletteCreator.newCreateRoulette(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" -> {
@@ -88,6 +103,25 @@ public class CommandListener implements TabExecutor {
player.getInventory().addItem(foo);
}
}
case "container" -> {
if (sender instanceof Player player) {
player.sendMessage(String.valueOf(player.getPersistentDataContainer().has(Keys.GAME)));
}
}
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);
DisguiseAPI.undisguiseToAll(player);
}
}
case "map" -> {
if (sender.hasPermission("blockandseek.manage")) {
if (argsLen > 1) {

View File

@@ -0,0 +1,41 @@
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

@@ -10,11 +10,15 @@ public class Keys {
public static final NamespacedKey SOUND_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekSoundItem");
public static final NamespacedKey FREEZE_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekFreezeItem");
public static final NamespacedKey MENU_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekMenuItem");
public static final NamespacedKey LEAVE_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekLeaveItem");
public static final NamespacedKey GAME_PAGE = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekGamePage");
public static final NamespacedKey FROZEN_PLAYER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekFrozenPlayer");
public static final NamespacedKey PLAYER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekPlayer");
public static final NamespacedKey GAME = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekGame");
public static final NamespacedKey HIDER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekHider");
public static final NamespacedKey SEEKER = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekSeeker");
public static final Team NO_COLLIDE_TEAM;
static {
@@ -23,5 +27,7 @@ public class Keys {
if (team == null) team = scoreboard.registerNewTeam("BlockAndSeekNoCollide");
team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
NO_COLLIDE_TEAM = team;
}
}

View File

@@ -3,53 +3,107 @@ 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 org.jetbrains.annotations.Nullable;
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 String get(@NotNull String key, String... replacements) {
return getLang(null, key, replacements);
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 String getLang(@Nullable String lang, @NotNull String key, String... replacements) {
lang = lang == null || !localization.containsKey(lang) ? "en-US" : lang;
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;
}
String s = localization.get(lang).get(key);
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;
}
public static Component getComponent(String key, String... replacements) {
return getLangComponent(null, key, replacements);
}
public static Component getLangComponent(String lang, String key, String... replacements) {
return miniMessage.deserialize(getLang(lang, key, replacements));
}
public static Component getLangComponentWithPrefix(String lang, String key, String... replacements) {
return prefix.append(getLangComponent(lang, key, replacements));
}
public static Component getComponentWithPrefix(String key, String... replacements) {
return prefix.append(getLangComponent(null, key, replacements));
}
}

View File

@@ -1,6 +1,8 @@
package hdvtdev.blockAndSeek;
package hdvtdev.blockAndSeek.eventListeners;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.Keys;
import hdvtdev.blockAndSeek.managers.FreezeManager;
import hdvtdev.blockAndSeek.managers.GamesManager;
import hdvtdev.blockAndSeek.managers.GuiManager;
@@ -17,24 +19,24 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDismountEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerDropItemEvent;
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 org.bukkit.util.Vector;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -49,9 +51,6 @@ public class EventListener implements Listener {
private static final ConcurrentHashMap<Player, BukkitTask> tasks = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<Player, Long> soundCoolDown = new ConcurrentHashMap<>();
private static final Vector ZERO_VELOCITY = new Vector(0, 0, 0);
private static final ItemStack freezeItem = ItemManager.getFreezeItem();
private static final ItemStack menuItem = ItemManager.getMenuItem();
public static void createTask(Player player, BukkitTask bukkitTask) {
@@ -63,28 +62,38 @@ public class EventListener implements Listener {
task.cancel();
}
private static boolean playerInGame(Player player) {
return player.getPersistentDataContainer().has(Keys.GAME);
}
private static boolean isInOneTeam(Player p1, Player p2) {
var c1 = p1.getPersistentDataContainer();
var c2 = p2.getPersistentDataContainer();
return (c1.has(Keys.HIDER) && c2.has(Keys.HIDER)) || (c1.has(Keys.SEEKER) && c2.has(Keys.SEEKER));
}
@EventHandler
public void onDrop(PlayerDropItemEvent event) {
event.setCancelled(true);
if (event.getPlayer().getPersistentDataContainer().has(Keys.GAME)) event.setCancelled(true);
}
@EventHandler
public void onBlockDamage(BlockDamageEvent event) {
if (event.getPlayer().getPersistentDataContainer().has(Keys.SEEKER)) {
if (FreezeManager.unfreeze(event.getBlock().getBlockData())) event.setCancelled(true);
}
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (player.getVehicle() instanceof ArmorStand armorStand) {
armorStand.getPersistentDataContainer().remove(Keys.FROZEN_PLAYER);
PersistentDataContainer armorStandContainer = armorStand.getPersistentDataContainer();
if (armorStandContainer.has(Keys.FROZEN_PLAYER)) {
armorStandContainer.remove(Keys.FROZEN_PLAYER);
armorStand.remove();
}
Inventory inventory = player.getInventory();
if (!inventory.contains(ItemManager.getMenuItem())) inventory.addItem(ItemManager.getMenuItem());
}
}
@EventHandler
@@ -92,9 +101,8 @@ public class EventListener implements Listener {
Player player = event.getPlayer();
PersistentDataContainer container = player.getPersistentDataContainer();
String arena = container.get(Keys.PLAYER, PersistentDataType.STRING);
String arena = container.get(Keys.GAME, PersistentDataType.STRING);
if (arena != null) {
container.remove(Keys.PLAYER);
GamesManager.get(arena).removePlayer(player);
FreezeManager.removePlayerDisguise(player);
}
@@ -102,7 +110,15 @@ public class EventListener implements Listener {
@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
@@ -113,6 +129,14 @@ public class EventListener implements Listener {
}
}
@EventHandler
public void onFoodLevelChange(FoodLevelChangeEvent event) {
if (event.getEntity() instanceof Player player && playerInGame(player)) {
event.setCancelled(true);
event.getEntity().setFoodLevel(20);
}
}
@EventHandler
public void onRightClick(PlayerInteractEvent event) {
@@ -123,61 +147,84 @@ public class EventListener implements Listener {
ItemStack itemInHand = player.getInventory().getItemInMainHand();
ItemMeta meta = itemInHand.getItemMeta();
if (itemInHand.equals(freezeItem)) {
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);
FreezeManager.freeze(player);
event.setCancelled(true);
} else if (itemInHand.equals(menuItem)) {
} 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);
}
}
}
}
@EventHandler
public void onBlockPlacement(BlockPlaceEvent event) {
event.setCancelled(true);
if (event.getPlayer().getPersistentDataContainer().has(Keys.GAME)) event.setCancelled(true);
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
event.setCancelled(true);
if (event.getPlayer().getPersistentDataContainer().has(Keys.GAME)) 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);
}
}
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
Inventory inventory = event.getClickedInventory();
if (inventory != null) {
InventoryHolder holder = inventory.getHolder();
switch (holder) {
case GuiManager.Menu ignored -> {
switch (event.getSlot()) {
case 13 -> {
ItemStack item = inventory.getItem(event.getSlot());
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);
}
default -> {
}
}
event.setCancelled(true);
}
case GuiManager.Menu.Games ignored -> {
ItemStack game = event.getCurrentItem();
} else if (itemData.has(Keys.GAME)) {
String game = itemData.get(Keys.GAME, PersistentDataType.STRING);
if (game != null) {
String gameName = game.getItemMeta().getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING);
if (gameName != null) GamesManager.get(gameName).addPlayer(player);
}
GamesManager.get(game).addPlayer(player);
event.setCancelled(true);
}
case null, default -> {
}
}
}
}
if (player.getPersistentDataContainer().has(Keys.GAME)) {
event.setCancelled(true);
}
if (player.hasMetadata("RollingMenu")) {
event.setCancelled(true);
int slot = event.getSlot();
@@ -190,8 +237,6 @@ public class EventListener implements Listener {
player.closeInventory(InventoryCloseEvent.Reason.UNKNOWN);
}
}
} else if (event.getSlotType().equals(InventoryType.SlotType.ARMOR)) {
event.setCancelled(true);
}

View File

@@ -0,0 +1,75 @@
package hdvtdev.blockAndSeek.eventListeners;
import hdvtdev.blockAndSeek.Keys;
import hdvtdev.blockAndSeek.managers.ItemManager;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.weather.WeatherChangeEvent;
import org.bukkit.event.world.TimeSkipEvent;
import org.bukkit.persistence.PersistentDataContainer;
public class ForceControlEventListener implements Listener {
private 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));
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
ItemManager.defaultInventory(player);
}
@EventHandler
public void onWeatherChange(WeatherChangeEvent event) {
if (event.getCause() != WeatherChangeEvent.Cause.COMMAND) event.setCancelled(true);
}
@EventHandler
public void onTimeSkip(TimeSkipEvent event) {
if (event.getSkipReason() != TimeSkipEvent.SkipReason.COMMAND) event.setCancelled(true);
}
@EventHandler
public void onBlockPlacement(BlockPlaceEvent event) {
event.setCancelled(true);
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
event.setCancelled(true);
}
@EventHandler
public void onFoodLevelChange(FoodLevelChangeEvent event) {
if (event.getEntity() instanceof Player player) {
event.setCancelled(true);
player.setFoodLevel(20);
}
}
@EventHandler
public void onDrop(PlayerDropItemEvent event) {
event.setCancelled(true);
}
@EventHandler
public void onPlayerDamage(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) {
if (!hasPermsToDamage(damager, victim)) {
event.setCancelled(true);
}
}
}
}

View File

@@ -2,6 +2,7 @@ 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;
@@ -17,15 +18,16 @@ import java.util.concurrent.ConcurrentHashMap;
public class ConfigManager {
private static volatile Map<String, Map<String, String>> localization;
private static volatile Map<String, String> config;
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 BlockAndSeekMap getMap(String name) {
return maps.get(name);
public static Config getConfig() {
return config;
}
public static Set<String> getAllMaps() {
return YamlConfiguration.loadConfiguration(mapsFile).getKeys(false);
}
@@ -47,14 +49,9 @@ public class ConfigManager {
BlockAndSeek.saveResource(file);
/*
switch (file) {
case "config.yml" -> {
Map<String, String> confMap = new HashMap<>();
for (String key : defaultConfiguration.getKeys(false)) {
confMap.put(key, defaultConfiguration.getString(key, "NULL"));
}
config = confMap;
}
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<>();
@@ -67,36 +64,26 @@ public class ConfigManager {
}
}
*/
}
} else {
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) throws IOException {
ConcurrentHashMap<String, String> confMap = new ConcurrentHashMap<>();
private static void loadConfig(File configurationFile, YamlConfiguration defaultConfiguration) {
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configurationFile);
configuration.setDefaults(defaultConfiguration);
for (String key : defaultConfiguration.getKeys(false)) {
if (configuration.isSet(key)) {
confMap.put(key, configuration.getString(key, defaultConfiguration.getString(key, "NULL")));
} else {
String value = defaultConfiguration.getString(key, "NULL");
configuration.set(key, value);
confMap.put(key, value);
}
}
configuration.save(configurationFile);
config = confMap;
config = configuration.getSerializable("config", Config.class);
}
private static void loadLocalization(File configurationFile, YamlConfiguration defaultConfiguration) throws IOException {
@@ -135,6 +122,7 @@ public class ConfigManager {
configuration.save(configurationFile);
localization = confMap;
Localization.update();
}

View File

@@ -4,22 +4,14 @@ import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekGame;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import hdvtdev.blockAndSeek.Localization;
import hdvtdev.blockAndSeek.roulette.RouletteCreator;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.WorldCreator;
import org.bukkit.entity.Player;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Criteria;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import java.io.File;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -45,111 +37,16 @@ public class GamesManager {
}
BlockAndSeekMap map = MapsManager.getMap(name);
System.out.println(map);
BlockAndSeekGame game = new BlockAndSeekGame(name, map.getMaxPlayers(), map.getLobby());
List<Integer> spawnCords = map.getSpawn();
List<Integer> lobbyCords = map.getLobby();
BlockAndSeekGame game = new BlockAndSeekGame(name, map);
games.put(name, game);
new BukkitRunnable() {
int duration = map.getDuration() + 10;
final int seekerSpawn = duration - 15;
int gameEnd = duration - 10;
int waitTime = 30;
final Location spawn = new Location(Bukkit.getWorld(name), spawnCords.getFirst(), spawnCords.get(1), spawnCords.get(2));
Player seeker;
@Override
public void run() {
if (!game.isStarted()) {
int playerCount = game.playerCount();
for (Player player : game.getPlayers()) {
player.sendActionBar(Component.text("Игроков " + playerCount + "/12")); //TODO!
}
if (playerCount >= map.getMinPlayers()) {
if (waitTime == 0 || playerCount == map.getMaxPlayers()) {
game.start();
seeker = game.selectRandomSeeker();
for (Player player : game.getHiders()) {
player.teleport(spawn);
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.addItem(ItemManager.getFreezeItem());
RouletteCreator.createRoulette(player, null, true, map.getBlocks());
}
} else {
if (waitTime < 5 || waitTime % 5 == 0) {
for (Player player : game.getPlayers()) {
player.sendMessage(Localization.getLangComponentWithPrefix(player.locale().toLanguageTag(), "wait-time-left", "{time}", String.valueOf(waitTime)));
}
}
waitTime--;
}
} else waitTime = 10;
} else {
if (seekerSpawn == gameEnd) {
seeker.teleport(spawn);
PlayerInventory seekerInventory = seeker.getInventory();
seekerInventory.setArmorContents(ItemManager.getSeekerArmor());
}
if (game.hidersCount() == 0) {
for (Player player : game.getPlayers()) {
player.showTitle(Title.title(Localization.getComponent("seekers-won"), Component.text("")));
}
game.preEnd();
games.remove(name);
}
for (Player player : game.getPlayers()) {
player.sendActionBar(Localization.getComponent("game-time-left", "{time}", String.valueOf(gameEnd)));
}
if (gameEnd == 0) {
if (game.hidersCount() == 1) {
for (Player player : game.getPlayers()) {
player.showTitle(Title.title(Localization.getComponent("hiders-solo-win", "{player}", game.getLastHider().getName()), Component.text("")));
}
} else {
for (Player player : game.getPlayers()) {
player.showTitle(Title.title(Localization.getComponent("hiders-won"), Component.text("")));
}
}
game.preEnd();
games.remove(name);
} else gameEnd--;
if (duration == 0) {
this.cancel();
}
}
}
}.runTaskTimer(BlockAndSeek.getInstance(), 0L, 20L);
return 0;
}
public static void remove(String name) {
games.remove(name);
}
public static BlockAndSeekGame get(String name) {
return games.get(name);
}

View File

@@ -1,7 +1,9 @@
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;
@@ -12,6 +14,8 @@ 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);
@@ -40,24 +44,22 @@ public class GuiManager {
public static final Menu instance = new Menu();
private static final Inventory mainMenu = Bukkit.createInventory(instance, 27, Localization.getComponent("menu-item"));
static {
fill(mainMenu);
mainMenu.setItem(13, ItemManager.getGamesPageItem());
}
private Menu() {
}
public static void open(Player player) {
player.openInventory(mainMenu);
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 mainMenu;
return Bukkit.createInventory(instance, 27, Component.text("raw"));
}
public static class Games implements InventoryHolder {
@@ -69,14 +71,21 @@ public class GuiManager {
public static void open(Player player) {
Inventory gamesMenu = Bukkit.createInventory(new Games(), 45, Localization.getComponent("menu-item"));
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(Localization.getComponent("game-name", "{name}", 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(gameItem);
gamesMenu.addItem(Localization.translateItem(player, gameItem, "{name}", game));
}

View File

@@ -2,6 +2,7 @@ package hdvtdev.blockAndSeek.managers;
import hdvtdev.blockAndSeek.Keys;
import hdvtdev.blockAndSeek.Localization;
import net.kyori.adventure.text.Component;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
@@ -17,53 +18,83 @@ public class ItemManager {
private static final ItemStack freezeItem = new ItemStack(Material.HEART_OF_THE_SEA);
private static final ItemStack seekerSword = new ItemStack(Material.WOODEN_SWORD);
private static final ItemStack seekerHelmet = new ItemStack(Material.LEATHER_HELMET);
private static final ItemStack seekerChestplate = new ItemStack(Material.LEATHER_CHESTPLATE);
private static final ItemStack seekerLeggings = new ItemStack(Material.LEATHER_LEGGINGS);
private static final ItemStack seekerBoots = new ItemStack(Material.LEATHER_BOOTS);
private static final ItemStack menuItem = new ItemStack(Material.COMPASS);
private static final ItemStack games = new ItemStack(Material.BOOKSHELF);
private static final ItemStack createGameButton = new ItemStack(Material.SLIME_BALL);
private static final ItemStack leaveItem = new ItemStack(Material.RED_DYE);
private static final ItemStack[] seekerSet;
static {
ItemMeta freezeMeta = freezeItem.getItemMeta();
freezeMeta.displayName(Localization.getComponent("freeze-item"));
freezeMeta.displayName(Component.text("freeze-item"));
freezeMeta.getPersistentDataContainer().set(Keys.FREEZE_ITEM, PersistentDataType.BOOLEAN, true);
freezeItem.setItemMeta(freezeMeta);
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(Localization.getComponent("menu-item"));
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(Localization.getComponent("games-page-item"));
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(Localization.getComponent("create-game-item"));
createGameButtonMeta.displayName(Component.text("create-game-item"));
createGameButton.setItemMeta(createGameButtonMeta);
ItemStack seekerHelmet = new ItemStack(Material.LEATHER_HELMET);
ItemStack seekerChestplate = new ItemStack(Material.LEATHER_CHESTPLATE);
ItemStack seekerLeggings = new ItemStack(Material.LEATHER_LEGGINGS);
ItemStack seekerBoots = new ItemStack(Material.LEATHER_BOOTS);
seekerHelmet.setItemMeta(color(seekerHelmet));
seekerBoots.setItemMeta(color(seekerBoots));
seekerChestplate.setItemMeta(color(seekerChestplate));
seekerLeggings.setItemMeta(color(seekerLeggings));
seekerSet = new ItemStack[]{seekerBoots, seekerLeggings, seekerChestplate, seekerHelmet};
}
public static void setSeekerSet(Player seeker) {
PlayerInventory inventory = seeker.getInventory();
inventory.clear();
inventory.addItem(Localization.translateItem(seeker, seekerSword));
ItemStack[] armor = new ItemStack[]{
Localization.translateItem(seeker, seekerBoots),
Localization.translateItem(seeker, seekerLeggings),
Localization.translateItem(seeker, seekerChestplate),
Localization.translateItem(seeker, seekerHelmet)
};
inventory.setArmorContents(armor);
}
private static ItemMeta color(ItemStack item) {
LeatherArmorMeta meta = (LeatherArmorMeta) item.getItemMeta();
meta.setColor(Color.RED);
meta.setUnbreakable(true);
meta.addEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 10, true);
meta.displayName(Localization.getComponent("seeker-armor"));
meta.displayName(Component.text("seeker-armor"));
return meta;
}
@@ -71,7 +102,11 @@ public class ItemManager {
public static void defaultInventory(Player player) {
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.addItem(menuItem);
inventory.addItem(Localization.translateItem(player, menuItem));
}
public static ItemStack getLeaveItem() {
return leaveItem;
}
public static ItemStack getCreateGameButton() {
@@ -86,10 +121,6 @@ public class ItemManager {
return menuItem;
}
public static ItemStack[] getSeekerArmor() {
return seekerSet;
}
public static ItemStack getFreezeItem() {
return freezeItem;
}

View File

@@ -21,13 +21,6 @@ public class MapsManager {
return allMaps.keySet();
}
public static void test() {
System.out.println("all maps");
allMaps.forEach((k, v) -> System.out.println(k + ": " + v));
System.out.println("ready maps");
readyMaps.forEach((k, v) -> System.out.println(k + ": " + v));
}
public static BlockAndSeekMap getMap(String name) {
return allMaps.get(name);
}

View File

@@ -2,7 +2,7 @@ package hdvtdev.blockAndSeek.roulette;
import hdvtdev.blockAndSeek.BlockAndSeek;
import hdvtdev.blockAndSeek.BlockAndSeekMap;
import hdvtdev.blockAndSeek.EventListener;
import hdvtdev.blockAndSeek.eventListeners.EventListener;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
@@ -25,6 +25,102 @@ import java.util.List;
public class RouletteCreator implements InventoryHolder {
public static void newCreateRoulette(Player player, List<BlockAndSeekMap.Block> blocks) {
final Inventory gui = Bukkit.createInventory(null, 45);
new BukkitRunnable() {
int i = 0;
final RouletteGenerator rouletteGenerator = new RouletteGenerator(blocks);
final List<RouletteList<ItemStack>> rows = List.of(
new RouletteList<>(rouletteGenerator.getRandomRow(15)),
new RouletteList<>(rouletteGenerator.getRandomRow(15)),
new RouletteList<>(rouletteGenerator.getRandomRow(15))
);
final List<ItemStack[]> items = List.of(
new ItemStack[]{
rows.getFirst().next(),
rows.getFirst().next(),
rows.getFirst().next(),
rows.getFirst().next(),
rows.getFirst().next()
},
new ItemStack[]{
rows.get(1).next(),
rows.get(1).next(),
rows.get(1).next(),
rows.get(1).next(),
rows.get(1).next()
},
new ItemStack[]{
rows.get(2).next(),
rows.get(2).next(),
rows.get(2).next(),
rows.get(2).next(),
rows.get(2).next()
}
);
private volatile boolean finished = false;
private long startTime = System.currentTimeMillis();
private long lastActionTime = startTime;
private long nextDelay = 0;
private final long baseDelay = 30;
private final long maxDelay = 450;
private final double k = 0.2;
@Override
public void run() {
if (finished) this.cancel();
long now = System.currentTimeMillis();
long elapsedSeconds = (now - startTime) / 1000;
if (elapsedSeconds >= 10) {
finished = true;
return;
}
nextDelay = (long) (baseDelay + (maxDelay - baseDelay) * (1 - Math.exp(-k * elapsedSeconds)));
if (now - lastActionTime >= nextDelay) {
i++;
for (int j = 0; j < 5; j++) {
gui.setItem(3 + j * 9, items.getFirst()[j]);
gui.setItem(5 + j * 9, items.get(1)[j]);
gui.setItem(7 + j * 9, items.get(2)[j]);
}
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 0.5f, 2f);
for (int j = 4; j >= 1; j--) {
items.getFirst()[j] = items.getFirst()[j - 1];
items.get(1)[j] = items.get(1)[j - 1];
items.get(2)[j] = items.get(2)[j - 1];
}
items.getFirst()[0] = rows.getFirst().next();
items.get(1)[0] = rows.get(1).next();
items.get(2)[0] = rows.get(2).next();
lastActionTime = now;
}
i++;
}
}.runTaskTimer(BlockAndSeek.getInstance(), 0, 4);
player.openInventory(gui);
}
@Deprecated
public static void createRoulette(Player player, Inventory inventory, boolean openInventory, List<BlockAndSeekMap.Block> blocks) {
Inventory gui = inventory == null ? new RouletteCreator().getInventory() : inventory;

View File

@@ -1,3 +1,19 @@
# Selected language in localization.yml (en_US is used by default)
language: en_US
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

@@ -11,14 +11,18 @@ en-US:
failed-reload: "<red>Failed to reload <yellow><u>{config}<red>. Error: {e}"
seekers-won: "<bold><yellow>Seekers <red>won!"
hiders-won: "<bold><yellow>Seekers <green>won!"
hiders-solo-win: "<bold><yellow>{player} <green>won this game!"
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}<reset><gold>s"
wait-time-left: "<gold>Game starts in: <yellow><bold>{time}s"
#items
freeze-item: "<gradient:#084CFB:#ADF3FD><bold>Freeze"
@@ -26,5 +30,9 @@ en-US:
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"