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

Помогите визуальные эффекты

@energy455
Не всё так страшно. Пусть у Вас будет 30 человек. Допустим, один раз в тик (хотя это слишком часто, по факту надо будет реже) вы будете на каждом отображать один эффект. Если отправлять информацию всем игрокам это будет 30х30=900 эффектов. Но если Вы просчитаете, сколько игроков должно видеть эти эффекты.
Допустим, измерите расстояние от игрока А до игрока Б и увидите, что игрок Б - вообще находится в другом мире или за сотню блоков и ему отсылать пакет с эффектом от игрока А не нужно. Проверите всех игроков и увидите, что количество пакетов значительно сократится.
Кстати, могу ошибаться, но по моему в NMS даже метод был отправки пакетов игрокам в определенном радиусе. Поищите, методы связанные с пакетами - но если Вы вручную будете определять кому слать пакеты, то это будет замечательно работать.
спасибо)
 
Вызываю процедуру sendToLocation() из следующего класса:
Java:
import java.lang.reflect.Method;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;

public enum particleeffects {

    HUGE_EXPLODE("hugeexplosion", 0), LARGE_EXPLODE("largeexplode", 1), FIREWORK_SPARK("fireworksSpark", 2), AIR_BUBBLE(
            "bubble", 3), SUSPEND("suspend", 4), DEPTH_SUSPEND("depthSuspend", 5), TOWN_AURA("townaura", 6), CRITICAL_HIT(
            "crit", 7), MAGIC_CRITICAL_HIT("magicCrit", 8), MOB_SPELL("mobSpell", 9), MOB_SPELL_AMBIENT(
            "mobSpellAmbient", 10), SPELL("spell", 11), INSTANT_SPELL("instantSpell", 12), BLUE_SPARKLE("witchMagic",
            13), NOTE_BLOCK("note", 14), ENDER("portal", 15), ENCHANTMENT_TABLE("enchantmenttable", 16), EXPLODE(
            "explode", 17), FIRE("flame", 18), LAVA_SPARK("lava", 19), FOOTSTEP("footstep", 20), SPLASH("splash", 21), LARGE_SMOKE(
            "largesmoke", 22), CLOUD("cloud", 23), REDSTONE_DUST("reddust", 24), SNOWBALL_HIT("snowballpoof", 25), DRIP_WATER(
            "dripWater", 26), DRIP_LAVA("dripLava", 27), SNOW_DIG("snowshovel", 28), SLIME("slime", 29), HEART("heart",
            30), ANGRY_VILLAGER("angryVillager", 31), GREEN_SPARKLE("happyVillager", 32), ICONCRACK("iconcrack", 33), TILECRACK(
            "tilecrack", 34);

    private String name;
    private int id;

    particleeffects(String name, int id) {
        this.name = name;
        this.id = id;
    }

    String getName() {
        return name;
    }

    int getId() {
        return id;
    }

    public static void sendToPlayer(particleeffects effect, Player player, Location location, float offsetX, float offsetY,
            float offsetZ, float speed, int count) {
        try {
            Object packet = createPacket(effect, location, offsetX, offsetY, offsetZ, speed, count);
            sendPacket(player, packet);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void sendToLocation(particleeffects effect, Location location, float offsetX, float offsetY, float offsetZ, float speed, int count) {
        try {
            Object packet = createPacket(effect, location, offsetX, offsetY, offsetZ, speed, count);
            for (Player player : Bukkit.getOnlinePlayers()) {
                if(S(location, player.getLocation()) < 30){sendPacket(player, packet);}
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Object createPacket(particleeffects effect, Location location, float offsetX, float offsetY,
            float offsetZ, float speed, int count) throws Exception {
        if (count <= 0) {count = 1;}
        Object packet = net.minecraft.server.v1_7_R4.PacketPlayOutWorldParticles.class.getConstructor(String.class, float.class, float.class,
                float.class, float.class, float.class, float.class, float.class, int.class).newInstance(effect.name, (float) location.getX(),
                        (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, count);
        return packet;
    }

    private static void sendPacket(Player p, Object packet) throws Exception {
        Object eplayer = getHandle(p);
        java.lang.reflect.Field playerConnectionField = eplayer.getClass().getField("playerConnection");
        Object playerConnection = playerConnectionField.get(eplayer);
        for (Method m : playerConnection.getClass().getMethods()) {
            if (m.getName().equalsIgnoreCase("sendPacket")) {
                m.invoke(playerConnection, packet);
                return;
            }
        }
    }

    private static Object getHandle(Entity entity) {
        try {
            Method entity_getHandle = entity.getClass().getMethod("getHandle");
            Object nms_entity = entity_getHandle.invoke(entity);
            return nms_entity;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
   
    public static Integer S(Location loc, Location target){
        double x1 = loc.getX(), y1 = loc.getY(), z1 = loc.getZ(), x2 = target.getX(), y2 = target.getY(), z2 = target.getZ();
        int S = (int)Math.sqrt( Math.pow ((x1 - x2), 2) + Math.pow ((y1 - y2), 2) + Math.pow ((z1 - z2), 2));
        return S;
    }

}
получаю в ответ это:
kuloOh9kI1.png

Почему так? И как исправить?
 
Вызываю процедуру sendToLocation() из следующего класса:
Java:
import java.lang.reflect.Method;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;

public enum particleeffects {

    HUGE_EXPLODE("hugeexplosion", 0), LARGE_EXPLODE("largeexplode", 1), FIREWORK_SPARK("fireworksSpark", 2), AIR_BUBBLE(
            "bubble", 3), SUSPEND("suspend", 4), DEPTH_SUSPEND("depthSuspend", 5), TOWN_AURA("townaura", 6), CRITICAL_HIT(
            "crit", 7), MAGIC_CRITICAL_HIT("magicCrit", 8), MOB_SPELL("mobSpell", 9), MOB_SPELL_AMBIENT(
            "mobSpellAmbient", 10), SPELL("spell", 11), INSTANT_SPELL("instantSpell", 12), BLUE_SPARKLE("witchMagic",
            13), NOTE_BLOCK("note", 14), ENDER("portal", 15), ENCHANTMENT_TABLE("enchantmenttable", 16), EXPLODE(
            "explode", 17), FIRE("flame", 18), LAVA_SPARK("lava", 19), FOOTSTEP("footstep", 20), SPLASH("splash", 21), LARGE_SMOKE(
            "largesmoke", 22), CLOUD("cloud", 23), REDSTONE_DUST("reddust", 24), SNOWBALL_HIT("snowballpoof", 25), DRIP_WATER(
            "dripWater", 26), DRIP_LAVA("dripLava", 27), SNOW_DIG("snowshovel", 28), SLIME("slime", 29), HEART("heart",
            30), ANGRY_VILLAGER("angryVillager", 31), GREEN_SPARKLE("happyVillager", 32), ICONCRACK("iconcrack", 33), TILECRACK(
            "tilecrack", 34);

    private String name;
    private int id;

    particleeffects(String name, int id) {
        this.name = name;
        this.id = id;
    }

    String getName() {
        return name;
    }

    int getId() {
        return id;
    }

    public static void sendToPlayer(particleeffects effect, Player player, Location location, float offsetX, float offsetY,
            float offsetZ, float speed, int count) {
        try {
            Object packet = createPacket(effect, location, offsetX, offsetY, offsetZ, speed, count);
            sendPacket(player, packet);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void sendToLocation(particleeffects effect, Location location, float offsetX, float offsetY, float offsetZ, float speed, int count) {
        try {
            Object packet = createPacket(effect, location, offsetX, offsetY, offsetZ, speed, count);
            for (Player player : Bukkit.getOnlinePlayers()) {
                if(S(location, player.getLocation()) < 30){sendPacket(player, packet);}
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Object createPacket(particleeffects effect, Location location, float offsetX, float offsetY,
            float offsetZ, float speed, int count) throws Exception {
        if (count <= 0) {count = 1;}
        Object packet = net.minecraft.server.v1_7_R4.PacketPlayOutWorldParticles.class.getConstructor(String.class, float.class, float.class,
                float.class, float.class, float.class, float.class, float.class, int.class).newInstance(effect.name, (float) location.getX(),
                        (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, count);
        return packet;
    }

    private static void sendPacket(Player p, Object packet) throws Exception {
        Object eplayer = getHandle(p);
        java.lang.reflect.Field playerConnectionField = eplayer.getClass().getField("playerConnection");
        Object playerConnection = playerConnectionField.get(eplayer);
        for (Method m : playerConnection.getClass().getMethods()) {
            if (m.getName().equalsIgnoreCase("sendPacket")) {
                m.invoke(playerConnection, packet);
                return;
            }
        }
    }

    private static Object getHandle(Entity entity) {
        try {
            Method entity_getHandle = entity.getClass().getMethod("getHandle");
            Object nms_entity = entity_getHandle.invoke(entity);
            return nms_entity;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
  
    public static Integer S(Location loc, Location target){
        double x1 = loc.getX(), y1 = loc.getY(), z1 = loc.getZ(), x2 = target.getX(), y2 = target.getY(), z2 = target.getZ();
        int S = (int)Math.sqrt( Math.pow ((x1 - x2), 2) + Math.pow ((y1 - y2), 2) + Math.pow ((z1 - z2), 2));
        return S;
    }

}
получаю в ответ это:
kuloOh9kI1.png

Почему так? И как исправить?
1 вопрос. Если юзаешь NMS, то зачем тогда подмешивать рефлексии?
 
Проблема в том, что мне нужно было в плагин свой добавить партиклы, я поискал в интернете и нашел этот API. Он мне понравился тем, что он маленький. Часть строк я вообще не понимаю, как работает, так как с пакетами никогда не работал. Но там, где я взял этот код, вроде автору "спасибо" говорили, из чего я решил, что он рабочий. Впрочем, там вроде говорилось об 1.7.2, а у меня Cauldron 1.7.10.
 
Проблема в том, что мне нужно было в плагин свой добавить партиклы, я поискал в интернете и нашел этот API. Он мне понравился тем, что он маленький. Часть строк я вообще не понимаю, как работает, так как с пакетами никогда не работал. Но там, где я взял этот код, вроде автору "спасибо" говорили, из чего я решил, что он рабочий. Впрочем, там вроде говорилось об 1.7.2, а у меня Cauldron 1.7.10.
Сразу бы сказал, что котел. Для него этот вариант не подходит. Используй Protocollib и погляди в сторону PlayEffect
 
Использовать NMS на котле нельзя
Понял, спасибо.
Короче, спёр я кусок кода у @fromgate и получил такое:

NN5CH3nvlq.png


Только не пойму, что подставить в String effectName. Где взять список валидных названий эффектов?
И почему тут PacketType.Play.Server? Разве не PacketType.Play.Client?
 
Понял, спасибо.
Короче, спёр я кусок кода у @fromgate и получил такое:

NN5CH3nvlq.png


Только не пойму, что подставить в String effectName. Где взять список валидных названий эффектов?
И почему тут PacketType.Play.Server? Разве не PacketType.Play.Client?
http://wiki.vg/Protocol#Particle, этот пакет отправляется со стороны сервера к клиенту, по другому никак.
 
Большое спасибо, это именно то, что было нужно, всё заработало. Отдельное спасибо @fromgate за готовый код.

Не за что ;)
Я правда, в более поздних версиях отказался от ProtocolLib - попал в момент, когда PL долго не обновлялся. Может стоит потом опять с ними подружиться обратно.
 

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

Назад
Верх