Помогите Мини-игра должна запускаться когда в опр. координатах будут игроки

Genius_Lyrics

Активный участник
Пользователь
Баллы
76
Как сделать чтобы мини-игра запускалась только тогда, когда в радиусе определенных координат было n игроков?
 
Возможный выход из ситуации:
1. Спавнишь Entity на нужных координатах
2. Проверяешь с помощью BukkitRunnable каждую 1 секунду (или больше) сколько существ находится рядом с этой Entity (это делается с помощю метода getNearbyEntities). Также должно выполняться условие entity instanceof Player
3. Если количество игроков - столько, сколько тебе нужно - можно запустить мини-игру.
 
Второй возможный вариант.
1. Заводишь 2 точки (Location), min и max.
2. Раз в 1 секунду (или больше) чекаешь всех игроков онлайн, кто в этом мире и все три координаты (x,y,z) между min и max. Считаешь их или заполняешь в список.
3. Если достаточно, начинаешь игру.
 
Создаёшь локацию в центре, получаешь энтити рядом, через getNearbyEntites и чекешь сколько игроков в радиусе например 20 блоков, если столько, сколько тебе надо - запускаешь игру
 
Возможный выход из ситуации:
1. Спавнишь Entity на нужных координатах
2. Проверяешь с помощью BukkitRunnable каждую 1 секунду (или больше) сколько существ находится рядом с этой Entity (это делается с помощю метода getNearbyEntities). Также должно выполняться условие entity instanceof Player
3. Если количество игроков - столько, сколько тебе нужно - можно запустить мини-игру.
Это самый костыль из костылей. Когда можно получить локацию и по ней проверять гетНеарбиPlayers, а не Ентитиес.
 
Как сделать чтобы мини-игра запускалась только тогда, когда в радиусе определенных координат было n игроков?
BukkitTask bukkitTask;

onEnable(){
Location center = new Location(Bukki.getWorlds().get(0), x, y, z);
bukkitTask = Bukkit.getScheduler().runTaskTimerAsynchronously(Prison.plugin, () -> {
if(center.getNearbyPlayers(radius).size() >= n) {
//start game...
bukkitTask.cancel(); //Выключаем наш бакитТаск, чтобы не работал по кд.
bukkitTask = null; //И присваиваем его null
}
}, 5L, 5L);
}
 
Последнее редактирование:
Второй возможный вариант.
1. Заводишь 2 точки (Location), min и max.
2. Раз в 1 секунду (или больше) чекаешь всех игроков онлайн, кто в этом мире и все три координаты (x,y,z) между min и max. Считаешь их или заполняешь в список.
3. Если достаточно, начинаешь игру.
Это самый не оптимизированный способ.
 
Мдэ, магазин костылей открыли
Код:
public Boolean isNearLocation(Player player, Location location){
        List<Player> list = new ArrayList<Player>()
        location.getNearbyEntities(100, 100, 100).forEach(entity -> {
            if (entity instanceof Player) {
                list.add(((Player) entity).getPlayer());
            }
        });
        if(list.contains(player)){
            return true;
        }
        else{
            return false;
        }
    }
 
Не так вопрос прочитал. Вот нужный
Код:
public Boolean getPlayerAmountNearLocation(int amount, Location location){
        List<Player> list = new ArrayList<Player>();
        location.getNearbyEntities(100, 100, 100).forEach(entity -> {
            if (entity instanceof Player) {
                list.add(((Player) entity).getPlayer());
            }
        });
        if(list.size() >= amount){
            return true;
        }
        else{
            return false;
        }
    }
Потом создаёшь повторяющийся поток и проверяешь, сколько там игроков
 
Присоединяюсь к обсуждению

PHP:
public class GameScheduler extends BukkitRunnable {

    private final Test plugin;
    private final Location location;
    private final int sourceTime;
    private int time;

    public GameScheduler(Test plugin, Location location, int sourceTime) {
        this.plugin = plugin;
        this.location = location;
        this.sourceTime = sourceTime;
        this.time = sourceTime;
    }

    @Override
    public void run() {
        boolean start = startGame(location, 10, 10, 10, 1);
        if (!start && time < sourceTime) {
            time = sourceTime;
            return;
        }
        if (start) {
            if (time == 0) {
                Bukkit.broadcastMessage("Game is started!");
                cancel();
                plugin.setGameScheduler(null);
                return;
            }
            time--;
            Bukkit.broadcastMessage(time + " seconds left before the start!");
        }
    }

    private boolean startGame(Location location, double radius, int count) {
        return startGame(location, radius, radius, radius, count);
    }

    private boolean startGame(Location location, double radiusX, double radiusY, double radiusZ, int count) {
        return location.getWorld().getNearbyEntities(location, radiusX, radiusY, radiusZ, e -> e instanceof Player).size() >= count;
    }

}
PHP:
    private GameScheduler gameScheduler;

    @Override
    public void onEnable() {
        startGameScheduler();
    }

    public void startGameScheduler() {
        gameScheduler = new GameScheduler(this, new Location(Bukkit.getWorld("world"), 0, 60, 0), 10);
        gameScheduler.runTaskTimer(this, 0L, 20L);
    }

    public void setGameScheduler(GameScheduler scheduler) {
        gameScheduler = scheduler;
    }
 
Последнее редактирование:
Это самый не оптимизированный способ.
Спасибо. Посмотрел исходники, у меня не Paper, а простой Spigot, поэтому вышло так:
Код:
BoundingBox bb = BoundingBox.of(minLocation, maxLocation);
List<Entity> = minLocation.getWorld()
   .getNearbyEntities(bb, e -> e instanceof Player);
 
Спасибо. Посмотрел исходники, у меня не Paper, а простой Spigot, поэтому вышло так:
Код:
BoundingBox bb = BoundingBox.of(minLocation, maxLocation);
List<Entity> = minLocation.getWorld()
   .getNearbyEntities(bb, e -> e instanceof Player);
А вот и плохо, лучше Paper юзай. На нём и есть удобные хандлеры и он сам по себе как ядро сильно оптимизированней
 
В курсе, но это прям уровень местных плагинов - тупо темы с ресурсами. По ссылке, которую оставил, готовится полноценный репозиторий.
А так все уже давно используют Paper, а не Spigot
Да, но на spigotmc.org запрещены плагины, которые не работают, собстна, на spigot'е.
 
По факту getNearbyEntities для игроков в большом радиусе - это большая жопа. Ибо во первых итерирует оно по списку энтитей каждого чанка в радиусе, проверяя при этом дальность, что уже получается медленней, дык ещё и энтитей в этих списках может быть вагон и маленькая тележка, и при этом для всех них будет выполняться проверка дальности.
Потому в 99.9999% случаев лучше проитерировать по world#getPlayers и проверить расстоние руками. А если боретесь за каждую копейку перформанса, тогда придётся варить карту дистанций с какой-то дискретностью самому.
 
Назад
Верх