Помогите Некорректно собирается FireworkMeta

LaoTheLizard

Старожил
Пользователь
Баллы
103
Накитаёзил такой код (Minecraft 1.7.10):

Java:
    public static ItemStack randomRocket(int amount, String name, int altitude, int maxmain, int maxfade, int maxstar) {

        if (altitude > 3) altitude = 3; // высота больше трех - слишком далеко (можно максимум 128)
        if (maxfade < 0) maxfade = 0; // количество вторичного красителя не может быть отрицательным числом
        if (maxmain == 0) maxmain = 1; // не может быть и одного первичного красителя
        if (maxstar == 0) maxstar = 1; // не может быть ни одной звездочки в фейерверке
       
        ItemStack rocket = new ItemStack(Material.FIREWORK, amount); // создаем стак фейерверков
        FireworkMeta meta = (FireworkMeta) rocket.getItemMeta(); // берем мету
        // добавляем нужное количество звездочек
        for (int i = 0; i < maxstar; i++){
            Builder firework = fireworkMeta(maxmain, maxfade);
            meta.addEffect(firework.build());   
        }
        meta.setPower(altitude); // высота полета
        if(!name.equalsIgnoreCase("none"))meta.setDisplayName(name); // название фейерверка
        rocket.setItemMeta(meta); // все полученное суём обратно в ракету
        return rocket;
    }
   
    private static Builder fireworkMeta(int maxmain, int maxfade){
        Builder meta = FireworkEffect.builder();       
        // main color
        for (int i = 0; i < maxmain; i++){
            int main = rnd.nextInt(170);
            if(main < 10) {meta.withColor(Color.AQUA);}
            if(main >= 10 && main < 20) {meta.withColor(Color.BLACK);}
            if(main >= 20 && main < 30) {meta.withColor(Color.BLUE);}
            if(main >= 30 && main < 40) {meta.withColor(Color.FUCHSIA);}
            if(main >= 40 && main < 50) {meta.withColor(Color.GRAY);}
            if(main >= 50 && main < 60) {meta.withColor(Color.GREEN);}
            if(main >= 60 && main < 70) {meta.withColor(Color.LIME);}
            if(main >= 70 && main < 80) {meta.withColor(Color.MAROON);}
            if(main >= 80 && main < 90) {meta.withColor(Color.NAVY);}
            if(main >= 90 && main < 100) {meta.withColor(Color.OLIVE); }
            if(main >= 100 && main < 110) {meta.withColor(Color.ORANGE);}
            if(main >= 110 && main < 120) {meta.withColor(Color.PURPLE);}
            if(main >= 120 && main < 130) {meta.withColor(Color.RED);}
            if(main >= 130 && main < 140) {meta.withColor(Color.SILVER);}
            if(main >= 140 && main < 150) {meta.withColor(Color.TEAL);}
            if(main >= 150 && main < 160) {meta.withColor(Color.WHITE);}
            if(main >= 160) {meta.withColor(Color.YELLOW);}
        }
       
        // fade to
        for (int i = 0; i < maxfade; i++){
            int fade = rnd.nextInt(170);
            if(fade < 10) {meta.withFade(Color.AQUA);}
            if(fade >= 10 && fade < 20) {meta.withFade(Color.BLACK);}
            if(fade >= 20 && fade < 30) {meta.withFade(Color.BLUE);}
            if(fade >= 30 && fade < 40) {meta.withFade(Color.FUCHSIA);}
            if(fade >= 40 && fade < 50) {meta.withFade(Color.GRAY);}
            if(fade >= 50 && fade < 60) {meta.withFade(Color.GREEN);}
            if(fade >= 60 && fade < 70) {meta.withFade(Color.LIME);}
            if(fade >= 70 && fade < 80) {meta.withFade(Color.MAROON);}
            if(fade >= 80 && fade < 90) {meta.withFade(Color.NAVY);}
            if(fade >= 90 && fade < 100) {meta.withFade(Color.OLIVE); }
            if(fade >= 100 && fade < 110) {meta.withFade(Color.ORANGE);}
            if(fade >= 110 && fade < 120) {meta.withFade(Color.PURPLE);}
            if(fade >= 120 && fade < 130) {meta.withFade(Color.RED);}
            if(fade >= 130 && fade < 140) {meta.withFade(Color.SILVER);}
            if(fade >= 140 && fade < 150) {meta.withFade(Color.TEAL);}
            if(fade >= 150 && fade < 160) {meta.withFade(Color.WHITE);}
            if(fade >= 160) {meta.withFade(Color.YELLOW);}
        }

        if(rnd.nextBoolean()){meta.flicker(true);} else {meta.flicker(false);}
        if(rnd.nextBoolean()){meta.trail(true);} else {meta.trail(false);}
       
        int type = rnd.nextInt(50);
        if(type < 10)meta.with(Type.BALL);
        if(type > 10 && type < 20)meta.with(Type.BALL_LARGE);
        if(type > 20 && type < 30)meta.with(Type.BURST);
        if(type > 30 && type < 40)meta.with(Type.CREEPER);
        if(type > 40 && type <= 50)meta.with(Type.STAR);
        return meta;
    }
В итоге получаю некоторое количество фейерверков с рандомными свойствами, всё работает, всё круто, но есть один нюанс.

Так выглядит "ванильная" ракета (созданная в верстаке):

VAN6mjx68E.png


А так выглядит моя (сгенерированная приведённым выше кодом):

9br6tG8RUZ.png


То есть, все цвета описываются словом "Пользовательский". И если цветов много, то получается вообще гадость, не влезающая в экран. Если включить английский язык - будет много слов "Custom".

Это "ванильный" фейерверк:
SDMn5X1z61.png


А это мой:
u77Zxa1kky.png


Я не вижу между ними разницы (цвет шрифта названия ракеты не считайте, он не влияет). Но она есть. Есть идеи, в чём именно?
 
Какой-то баг, не всё сообщение вышло.
В общем, ещё раз. Этим кодом создаётся рандомный фейерверк. Но на вид он выглядит не так, как тот, что создаётся в верстаке.

Вот разница. Нормальный:
s4mwCuYwiP.png


Мой:
t9m4Md3rvV.png


То есть, все цвета стали называться "Пользовательский".

ItemInfo для первого:
clicWV4DyO.png


Для моего:
RkibiTEAFh.png


Я разницы не вижу. А вы?
 
Пусть это будет тема, в которой отвечал только автор. 🙂
В общем, изучив меты, я заподоздрил, что цвета у меня делаются неправильные. И оказался прав. Код исправил, результат вот:
NSKEoHOuSM.png


Суть проблемы в том, что Color.RED (и вообще все имеющиеся цвета) не соответствуют по RGB-коду цвету красителей в фейерверках. Пришлось создать пару "оригинальных" ракет, снять с них ItemInfo и вручную забить. Итоговый код, если кому хочется порадовать своих игроков морем халявных фейерверков (в преддверии праздника), выглядит так:
Java:
    public static ItemStack randomRocket(int amount, String name, int altitude, int maxmain, int maxfade, int maxstar) {
        if (amount < 1) amount = 1; // стак не может быть размером менее 1
        if (amount > 64) amount = 64; // стак не должен быть размером более 64
        if (altitude > 5) altitude = 5; // высота больше трех - слишком далеко (0...128)
        if (maxfade < 0) maxfade = 0; // количество вторичного красителя не может быть отрицательным числом (0...) 
        if (maxmain == 0) maxmain = 1; // не может быть ни одного первичного красителя (1...)
        if (maxstar == 0) maxstar = 1; // не может быть ни одной звездочки в фейерверке (1...)
       
        ItemStack rocket = new ItemStack(Material.FIREWORK, amount); // создаем стак фейерверков
        FireworkMeta meta = (FireworkMeta) rocket.getItemMeta(); // берем мету
        // добавляем нужное количество звездочек
        for (int i = 0; i < maxstar; i++){
            Builder firework = fireworkMeta(maxmain, maxfade);
            meta.addEffect(firework.build());   
        }
        meta.setPower(altitude); // высота полета
        if(!name.equalsIgnoreCase("none"))meta.setDisplayName(name); // название фейерверка
        rocket.setItemMeta(meta); // все полученное суём обратно в ракету
        return rocket;
    }
   
    private static Builder fireworkMeta(int maxmain, int maxfade){
        Builder meta = FireworkEffect.builder();       
        // main color
        for (int i = 0; i < maxmain; i++){
            int main = rnd.nextInt(160);
            if(main < 10) {meta.withColor(Color.fromRGB(30, 27, 27));} // черный! BLACK
            if(main >= 10 && main < 20) {meta.withColor(Color.fromRGB(179, 49, 44));} // красный! RED
            if(main >= 20 && main < 30) {meta.withColor(Color.fromRGB(81, 48, 26));} // коричневый! OLIVE
            if(main >= 30 && main < 40) {meta.withColor(Color.fromRGB(37, 49, 146));} // синий! BLUE
            if(main >= 40 && main < 50) {meta.withColor(Color.fromRGB(123, 47, 190));} // фиолетовый! MAROON
            if(main >= 50 && main < 60) {meta.withColor(Color.fromRGB(40, 118, 151));} // бирюзовый! TEAL
            if(main >= 60 && main < 70) {meta.withColor(Color.fromRGB(171, 171, 171));} // светло-серый! SILVER
            if(main >= 70 && main < 80) {meta.withColor(Color.fromRGB(67, 67, 67));} // серый! GRAY
            if(main >= 80 && main < 90) {meta.withColor(Color.fromRGB(216, 129, 152));} // розовый! FUCHSIA
            if(main >= 90 && main < 100) {meta.withColor(Color.fromRGB(65, 205, 52));} // лаймовый! LIME
            if(main >= 100 && main < 110) {meta.withColor(Color.fromRGB(222, 207, 42));} // желтый! YELLOW
            if(main >= 110 && main < 120) {meta.withColor(Color.fromRGB(102, 137, 211));} // голубой??? AQUA or NAVY?
            if(main >= 120 && main < 130) {meta.withColor(Color.fromRGB(195, 84, 205));} // пурпурный! PURPLE
            if(main >= 130 && main < 140) {meta.withColor(Color.fromRGB(235, 136, 68));} // оранжевый! ORANGE
            if(main >= 140 && main < 150) {meta.withColor(Color.fromRGB(240, 240, 240));} // белый! WHITE
            if(main >= 150) {meta.withColor(Color.fromRGB(59, 81, 26));} // зеленый! GREEN
        }
       
        // fade to
        for (int i = 0; i < maxfade; i++){
            int fade = rnd.nextInt(170);
            if(fade < 10) {meta.withFade(Color.fromRGB(30, 27, 27));}
            if(fade >= 10 && fade < 20) {meta.withFade(Color.fromRGB(179, 49, 44));}
            if(fade >= 20 && fade < 30) {meta.withFade(Color.fromRGB(81, 48, 26));}
            if(fade >= 30 && fade < 40) {meta.withFade(Color.fromRGB(37, 49, 146));}
            if(fade >= 40 && fade < 50) {meta.withFade(Color.fromRGB(123, 47, 190));}
            if(fade >= 50 && fade < 60) {meta.withFade(Color.fromRGB(40, 118, 151));}
            if(fade >= 60 && fade < 70) {meta.withFade(Color.fromRGB(171, 171, 171));}
            if(fade >= 70 && fade < 80) {meta.withFade(Color.fromRGB(67, 67, 67));}
            if(fade >= 80 && fade < 90) {meta.withFade(Color.fromRGB(216, 129, 152));}
            if(fade >= 90 && fade < 100) {meta.withFade(Color.fromRGB(65, 205, 52));}
            if(fade >= 100 && fade < 110) {meta.withFade(Color.fromRGB(222, 207, 42));}
            if(fade >= 110 && fade < 120) {meta.withFade(Color.fromRGB(102, 137, 211));}
            if(fade >= 120 && fade < 130) {meta.withFade(Color.fromRGB(195, 84, 205));}
            if(fade >= 130 && fade < 140) {meta.withFade(Color.fromRGB(235, 136, 68));}
            if(fade >= 140 && fade < 150) {meta.withFade(Color.fromRGB(240, 240, 240));}
            if(fade >= 150 && fade < 160) {meta.withFade(Color.fromRGB(240, 240, 240));}
            if(fade >= 160) {meta.withFade(Color.fromRGB(59, 81, 26));}
        }

        if(rnd.nextBoolean()){meta.flicker(true);} else {meta.flicker(false);}
        if(rnd.nextBoolean()){meta.trail(true);} else {meta.trail(false);}
       
        int type = rnd.nextInt(50);
        if(type < 10)meta.with(Type.BALL);
        if(type > 10 && type < 20)meta.with(Type.BALL_LARGE);
        if(type > 20 && type < 30)meta.with(Type.BURST);
        if(type > 30 && type < 40)meta.with(Type.CREEPER);
        if(type >= 40)meta.with(Type.STAR);
        return meta;
    }

Стак случайных фейерверков я получаю вызовом:
Java:
       // кол-во, название, высота полета, кол-во основных цветов, кол-во вторичных цветов, кол-во звездочек
        p.setItemInHand(randomRocket(64, "none", rnd.nextInt(5), rnd.nextInt(8), rnd.nextInt(8), rnd.nextInt(8)));

Можно, если хочется, в одну звездочку впихнуть больше восьми цветов, а в ракету - больше восьми звездочек (несмотря на ограничение при крафте в игре), но тогда мета фейерверка может не влезть в экран, как у меня было в начале.
 
но тогда мета фейерверка может не влезть в экран, как у меня было в начале.
Мету можно скрыть (не знаю, только, с какой версии), и будет действительно случайный фейерверк.
Видел пример с генерацией случайных фейерверком используя FireworkEffect.Builder, там строк кода было поменьше, но и количества цветов и тд. только по одному.
 
Мету можно скрыть (не знаю, только, с какой версии), и будет действительно случайный фейерверк.
Видел пример с генерацией случайных фейерверком используя FireworkEffect.Builder, там строк кода было поменьше, но и количества цветов и тд. только по одному.
Да, было бы неплохо, если бы можно было её скрыть. Я бы тогда давал им название и номера (а количество цветов сделал бы больше - ракета с 10-15 цветами выглядит круче): допустим, делает игрок себе ракеты, а они называются "Имя_игрока 1", "Имя_игрока 2". И потом так: "Народ, вы видели мою ракету номер двести? Улёёёёёт!" Ну, конечно, сделать возможность размножать ракету.
Вообще у меня на сервере идея реализована так: есть продавец (житель), подходишь к нему, кликаешь по нему порохом и он забирает у тебя определенное количество денег (в праздники - дешевле, а в день рождения игрока - бесплатно), а порох заменяет на стак случайных фейерверков в соотношении "один фейерверк за один порох". Можно сделать так, что если кликаешь по нему уже готовым фейерверком, то за плату увеличивает количество фейерверков в руке.
 
Назад
Верх