Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите [РЕШЕНО] Проиграть плагином звук из мода

LaoTheLizard

Старожил
Пользователь
Баллы
103
Единственный способ, которым я смог воспроизвести плагином звук из мода:
Java:
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "playsound mocreatures:appearmagic " + ((Player)e.getEntity()).getName());

Звук звучит. В консоли при этом выводятся такие строки каждый раз:
rtrV8gzxs8.png


Есть ли более элегантное решение задачи? Или хотя бы способ убрать вывод в консоль этих оповещений?
 
Я не сказал, что не пробовал этот метод. Просто я не смог вызвать звук из мода этим методом. По крайней мере так:
Java:
playSound((Player)e.getEntity(), "WITHER_SHOOT");

// plays sound
public static void playSound(Player p, String sound) {
    try {
        Sound snd = Sound.valueOf(sound);
        p.getWorld().playSound(p.getLocation(), snd, 1.2f, (float) 1.0);
    } catch (IllegalArgumentException e) {
        log.info("Invalid sound!");
        e.printStackTrace();
    }
}

Если написать точно, как я показал, будет звук выстрела ифрита. Я пытался подставить вместо "WITHER_SHOOT" разные значения. И везде выдавало ошибку, вроде Wrong source file или типа того (не помню точно).

Такие варианты пришли в голову.
mocreatures_appearmagic
mocreatures:appearmagic
MOCREATURES_APPEARMAGIC
MOCREATURES:APPEARMAGIC

Кто-нибудь знает, как нужно написать, чтоб звук, наконец, прозвучал?
 
Используйте метод со строковым параметром, а не Sound
Ты абсолютно прав!

Дальнейшее изучение вопроса показало, что звук можно воспроизвести только через метод игрока player.playSound(Location, String float, float); (у мира метода со строковым параметром нет). Метод этот deprecated, но это, конечно, не проблема. Действительно проблема в том, что проигрывание звука через этот метод не приведёт к тому, что стоящие рядом с игроком-целью игроки тоже услышат звук (да-да, все давно знали, а вот я только что узнал). Чтобы решить этот вопрос, я написал такой метод:

Java:
/**
    *Location location - место, откуда должен исходить звук, String sound - название звука,
    *float volume - громкость звука в центре, float pitch - тональность звука,
      */
    public boolean playModSound(Location location, String sound, float volume, float pitch){
        Collection <? extends Player> players = Bukkit.getServer().getOnlinePlayers();
        if(players.size() == 0){return true;} // на всякий случай
        int radius = 15;
        for(Player p:players){
            int S = Distance(location, p.getLocation()); // расстояние от источника звука до игрока, где Distance - процедура, которую я здесь не привожу
            float maxvolume = 1.2F;
            if(S > radius * volume){continue;} // здесь уже не слышно
            float v = maxvolume - ((S / radius) / volume); // ниже поговорим об этой формуле
            if(v <= 0){continue;} // на всякий случай      
            try {
            p.playSound(p.getLocation(), sound, v, pitch);
            } catch (Exception e) {return false;}
        }
        return true;

Формула рассчитывает громкость звука в точке, где находится очередной игрок. Каждые 1.0F от volume добавляют к радиусу звука 15 блоков дальности. То есть, при volume = 4.0F звук будет слышен на том же расстоянии, что и взрыв ТНТ (он слышен на 60 блоков максимум, проверено).

Собственно, хотелось бы конструктивной критики кода, так как я не уверен, что корректно решаю эту задачу.
 
Собственно, хотелось бы конструктивной критики кода, так как я не уверен, что корректно решаю эту задачу.
Если у тебя свой расчёт громкости, то сгодится, а если тебе нужно сделать звук как это было бы на самом деле, то в первый аргумент ставь не позицию игрока, а позицию источника звука.
 
Опять я изобрел велосипед, действительно, всё было куда проще.
Для тех, кому понадобится:
Java:
    @SuppressWarnings("deprecation")
    public boolean playModSoundNaturally(Location location, String sound, float volume, float pitch){
        Collection <? extends Player> players = Bukkit.getServer().getOnlinePlayers();
        if(players.size() == 0){return true;}
        for(Player p:players){
            try {
            p.playSound(location, sound, volume, pitch);
            } catch (Exception e){return false;}
        }
        return true;
    }

@Den_Abr , благодарю за помощь.
 
Согласен. Со скобками смотрится эстетичнее.
 

Поделиться этой страницей

Назад
Верх