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

Помогите Фейерверки в 1.8

CraftCoder

Старожил
Пользователь
Баллы
108
Имя в Minecraft
CraftCoderr
Как взорвать фейерверк в координатах в minecraft 1.8?
В версиях ниже я делаю так:
Код:
private Method world_getHandle = null;
    private Method nms_world_broadcastEntityEffect = null;
    private Method firework_getHandle = null;
   
    public void playFirework(World world, Location loc, FireworkEffect fe) throws Exception {
        Firework fw = (Firework) world.spawn(loc, Firework.class);
        Object nms_world = null;
        Object nms_firework = null;
        if(world_getHandle == null) {
            world_getHandle = getMethod(world.getClass(), "getHandle");
            firework_getHandle = getMethod(fw.getClass(), "getHandle");
        }
        nms_world = world_getHandle.invoke(world, (Object[]) null);
        nms_firework = firework_getHandle.invoke(fw, (Object[]) null);
        if(nms_world_broadcastEntityEffect == null) {
            nms_world_broadcastEntityEffect = getMethod(nms_world.getClass(), "broadcastEntityEffect");
        }
        FireworkMeta data = (FireworkMeta) fw.getFireworkMeta();
        data.clearEffects();
        data.setPower(1);
        data.addEffect(fe);
        fw.setFireworkMeta(data);
        nms_world_broadcastEntityEffect.invoke(nms_world, new Object[] {nms_firework, (byte) 17});
        fw.remove();
    }
   
    private static Method getMethod(Class<?> cl, String method) {
        for(Method m : cl.getMethods()) {
            if(m.getName().equals(method)) {
                return m;
            }
        }
        return null;
    }
 
В баккит 1.7.10 точно есть. detonate()

В любом случае я способов взорвать фейерверк находился несколько штук. Под 1.8 ещё не пробовал, но можно попробовать что-то вроде: https://github.com/fromgate/PlayEff...effect/customeffects/PacketNMS.java#L174-L211

Один из них у меня работал в 1.6.х, другой - 1.7.х (второй по сути является аналогом detonate(), я сам этот метод не стал использовать просто чтобы сохранить совместимость со всеми версиями 1.7.х)
Нашёл шикарный способ: http://bukkit.org/threads/lib-insta...sible-rocket-just-the-firework-effect.269919/

Вот вариант, переделанный под 1.8. Будет в следующей версии PlayEffect :)

Код:
package me.fromgate.playeffect.customeffects;

import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Player;
import org.*********ventory.meta.FireworkMeta;
import net.minecraft.server.v1_8_R1.EntityFireworks;
import net.minecraft.server.v1_8_R1.PacketPlayOutEntityStatus;
import net.minecraft.server.v1_8_R1.World;

public class InstantFireworks extends EntityFireworks {
    Player[] players = null;

    public InstantFireworks(World world, Player... p) {
        super(world);
        players = p;
        this.a(0.25F, 0.25F);
    }

    boolean gone = false;

    @Override
    public void s_() {
        if (gone) {
            return;
        }

        if (!this.world.isStatic) {
            gone = true;

            if (players != null)
                if (players.length > 0)
                    for (Player player : players)
                        (((CraftPlayer) player).getHandle()).playerConnection.sendPacket(new PacketPlayOutEntityStatus(this, (byte) 17));
            else world.broadcastEntityEffect(this, (byte) 17);
            this.die();
        }
    }

    public static void spawn(Location location, FireworkEffect effect, Player... players) {
        try {
            InstantFireworks firework = new InstantFireworks(((CraftWorld) location.getWorld()).getHandle(), players);
           
            FireworkMeta meta = ((Firework) firework.getBukkitEntity()).getFireworkMeta();
            meta.addEffect(effect);
            ((Firework) firework.getBukkitEntity()).setFireworkMeta(meta);
           
            firework.setPosition(location.getX(), location.getY(), location.getZ());

            if ((((CraftWorld) location.getWorld()).getHandle()).addEntity(firework)) {
                firework.setInvisible(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Да и кстати, detonate() и все его вариации не работают :(
Я вчера вариантов десять перепробовал...
 
В баккит 1.7.10 точно есть. detonate()

В любом случае я способов взорвать фейерверк находился несколько штук. Под 1.8 ещё не пробовал, но можно попробовать что-то вроде: https://github.com/fromgate/PlayEff...effect/customeffects/PacketNMS.java#L174-L211

Один из них у меня работал в 1.6.х, другой - 1.7.х (второй по сути является аналогом detonate(), я сам этот метод не стал использовать просто чтобы сохранить совместимость со всеми версиями 1.7.х)
Нашёл шикарный способ: http://bukkit.org/threads/lib-insta...sible-rocket-just-the-firework-effect.269919/

Вот вариант, переделанный под 1.8. Будет в следующей версии PlayEffect :)

Код:
package me.fromgate.playeffect.customeffects;

import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Player;
import org.*********ventory.meta.FireworkMeta;
import net.minecraft.server.v1_8_R1.EntityFireworks;
import net.minecraft.server.v1_8_R1.PacketPlayOutEntityStatus;
import net.minecraft.server.v1_8_R1.World;

public class InstantFireworks extends EntityFireworks {
    Player[] players = null;

    public InstantFireworks(World world, Player... p) {
        super(world);
        players = p;
        this.a(0.25F, 0.25F);
    }

    boolean gone = false;

    @Override
    public void s_() {
        if (gone) {
            return;
        }

        if (!this.world.isStatic) {
            gone = true;

            if (players != null)
                if (players.length > 0)
                    for (Player player : players)
                        (((CraftPlayer) player).getHandle()).playerConnection.sendPacket(new PacketPlayOutEntityStatus(this, (byte) 17));
            else world.broadcastEntityEffect(this, (byte) 17);
            this.die();
        }
    }

    public static void spawn(Location location, FireworkEffect effect, Player... players) {
        try {
            InstantFireworks firework = new InstantFireworks(((CraftWorld) location.getWorld()).getHandle(), players);
          
            FireworkMeta meta = ((Firework) firework.getBukkitEntity()).getFireworkMeta();
            meta.addEffect(effect);
            ((Firework) firework.getBukkitEntity()).setFireworkMeta(meta);
          
            firework.setPosition(location.getX(), location.getY(), location.getZ());

            if ((((CraftWorld) location.getWorld()).getHandle()).addEntity(firework)) {
                firework.setInvisible(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Да и кстати, detonate() и все его вариации не работают :(
Я вчера вариантов десять перепробовал...
Спасибо :good:
 
В баккит 1.7.10 точно есть. detonate()

В любом случае я способов взорвать фейерверк находился несколько штук. Под 1.8 ещё не пробовал, но можно попробовать что-то вроде: https://github.com/fromgate/PlayEff...effect/customeffects/PacketNMS.java#L174-L211

Один из них у меня работал в 1.6.х, другой - 1.7.х (второй по сути является аналогом detonate(), я сам этот метод не стал использовать просто чтобы сохранить совместимость со всеми версиями 1.7.х)
Нашёл шикарный способ: http://bukkit.org/threads/lib-insta...sible-rocket-just-the-firework-effect.269919/

Вот вариант, переделанный под 1.8. Будет в следующей версии PlayEffect :)

Код:
package me.fromgate.playeffect.customeffects;

import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Player;
import org.*********ventory.meta.FireworkMeta;
import net.minecraft.server.v1_8_R1.EntityFireworks;
import net.minecraft.server.v1_8_R1.PacketPlayOutEntityStatus;
import net.minecraft.server.v1_8_R1.World;

public class InstantFireworks extends EntityFireworks {
    Player[] players = null;

    public InstantFireworks(World world, Player... p) {
        super(world);
        players = p;
        this.a(0.25F, 0.25F);
    }

    boolean gone = false;

    @Override
    public void s_() {
        if (gone) {
            return;
        }

        if (!this.world.isStatic) {
            gone = true;

            if (players != null)
                if (players.length > 0)
                    for (Player player : players)
                        (((CraftPlayer) player).getHandle()).playerConnection.sendPacket(new PacketPlayOutEntityStatus(this, (byte) 17));
            else world.broadcastEntityEffect(this, (byte) 17);
            this.die();
        }
    }

    public static void spawn(Location location, FireworkEffect effect, Player... players) {
        try {
            InstantFireworks firework = new InstantFireworks(((CraftWorld) location.getWorld()).getHandle(), players);
          
            FireworkMeta meta = ((Firework) firework.getBukkitEntity()).getFireworkMeta();
            meta.addEffect(effect);
            ((Firework) firework.getBukkitEntity()).setFireworkMeta(meta);
          
            firework.setPosition(location.getX(), location.getY(), location.getZ());

            if ((((CraftWorld) location.getWorld()).getHandle()).addEntity(firework)) {
                firework.setInvisible(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Да и кстати, detonate() и все его вариации не работают :(
Я вчера вариантов десять перепробовал...
Сначала я перешёл на 1.8, протестил кучу своего барахла, а потом обнаружил что нет фейерверков. Я подумал что это я что-то не так делаю и поискал на форуме сигопта, там нашёл занимательную тему, на которую никто не ответил. Потом я поискал на форуме баккита, там об этом не написано. Потом попробовал сделать как раньше -- отправлять пакеты, но и это не сработало. И прежде чем расковыривать сервер повторно и искать решения, я вошёл сюда. Как это чудесно, что мне не придётся в очередной раз разделывать ядро. Спасибо за заготовку под фейерверки.
П.С. Может быть кто-то из здесь находящихся знает как отобразить FallingBlock воды или лавы в 1.8 и какие ещё есть сюрпризы в этой версии?
 
@Ission
До этого я ещё не добирался. Потребности не было.
Меня что интересует - как можно получить предмет по синтаксису внесенному в 1.8 (minecraft:stone) и т.п. Народ уже привык к этому, думаю надо потихоньку плагины прикручивать. Всё руки не доходят вытащить этот "механизм" наружу.
 
@fromgate
Плохая идея переходить на этот механизм. Это ещё одна вещь, за которые я не люблю 1.8. Для некоторых технических блоков, среди которых например лава, вода, не существует связанного названия или его придётся долго искать, а потом объяснять(я по крайней мере его не нашёл).
 
@Ission согласен - полностью на него переходить нельзя. Но я рассматриваю его как дополнительный вариант.
Сейчас их два — название материала в bukkit и id. Это был бы третий.
 
@Ission
До этого я ещё не добирался. Потребности не было.
Меня что интересует - как можно получить предмет по синтаксису внесенному в 1.8 (minecraft:stone) и т.п. Народ уже привык к этому, думаю надо потихоньку плагины прикручивать. Всё руки не доходят вытащить этот "механизм" наружу.
Bukkit.getUnsafe().getMaterialFromInternalName(String name)
Там кстати ещё пару интересных методов есть, например возможность модифицировать итемстак с помощью json.
 

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

Назад
Верх