Particle packet library

Discussion in 'Resources' started by microgeek, Mar 31, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Ultimate_n00b

    Tested two, Critical Hit and Note. And critical didn't work..
    Code:java
    1. ParticleEffects.CRIT.sendToPlayer(player, entity.getLocation(), 0, 1, 0,
    2. 1000, 5);

    Is there something I am doing wrong? And what is speed? Does it make it go faster or slower the higher the number?
     
  2. Offline

    DSH105 Retired Staff

    Ultimate_n00b
    It works, you just may not have been able to see them, especially with such a high speed. Try increasing the particle amount and decreasing the speed.
     
  3. Offline

    Ultimate_n00b

    Is there any way to make it appear for x seconds? Or just trial and error?
     
  4. Offline

    DSH105 Retired Staff

    Ultimate_n00b
    A low speed might show it for a little bit longer, but otherwise trial and error ;).
     
  5. Offline

    Ultimate_n00b

    What is GeneralUtil() ?
     
  6. Offline

    DSH105 Retired Staff

    DarkBladee12
    Try using this (small improvement to your sendToLocation method :)):

    Code:java
    1.  
    2. public static void sendPacketToLocation(Location l, Object packet)
    3. for (Entity e : getNearbyEntities(l, 20)) { // In this case I used a radius of 20
    4. if (e instanceof Player) {
    5. Player p = (Player) e;
    6. Object nmsPlayer = getMethod(p.getClass(), "getHandle").invoke(p);
    7. Object con = nmsPlayer.getClass().getField("playerConnection").get(nmsPlayer);
    8. getMethod(con.getClass(), "sendPacket").invoke(con, packet);
    9. }
    10. }
    11. }
    12.  
    13. public static List<Entity> getNearbyEntities(Location l, int range) {
    14. List<Entity> entities = new ArrayList<Entity>();
    15. for (Entity entity : l.getWorld().getEntities()) {
    16. if (isInBorder(l, entity.getLocation(), range)) {
    17. entities.add(entity);
    18. }
    19. }
    20. return entities.isEmpty() ? null : entities;
    21. }
    22.  
    23. public static boolean isInBorder(Location center, Location l, int range) {
    24. int x = center.getBlockX(), z = center.getBlockZ();
    25. int x1 = l.getBlockX(), z1 = l.getBlockZ();
    26. if (x1 >= (x + range) || z1 >= (z + range) || x1 <= (x - range) || z1 <= (z - range)) {
    27. return false;
    28. }
    29. return true;
    30. }
    31.  


    The radius is configurable.

    EDIT: And I never figured out the mobSpell and note colours. I don't think it's possible without extending some classes or something like that.

    EDIT2: stirante Where did you find func_98182_a(Packet63WorldParticles par1Packet63WorldParticles)?
     
  7. Offline

    DarkBladee12

    Ultimate_n00b It's just another class where are some methods for lists and stuff, I tried to edit my post and remove this but seems like bukkit won't save it :/

    _DSH105_ Maybe it's in the source of minecraft, because I can't find it in the source of nms^^

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 31, 2016
  8. Offline

    DSH105 Retired Staff

    DarkBladee12
    Yeah, I spent some time researching it this afternoon but I still haven't found it yet.
     
  9. Offline

    Ultimate_n00b

    You could make a new post, or PM it.
     
  10. Offline

    stirante

    It's client's code decompiled with mcp.
     
  11. Offline

    Ultimate_n00b

    So.. is there a update proof version usable?
     
  12. Offline

    DarkBladee12

    Ultimate_n00b Yeah you can use mine, which is version proof:

    Code:
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.entity.Player;
     
    public enum ParticleEffect {
     
        HUGE_EXPLOSION("hugeexplosion", 0), LARGE_EXPLODE("largeexplode", 1), FIREWORKS_SPARK("fireworksSpark", 2), BUBBLE("bubble", 3), SUSPEND("suspend", 4), DEPTH_SUSPEND("depthSuspend", 5), TOWN_AURA("townaura", 6), CRIT("crit", 7), MAGIC_CRIT("magicCrit", 8), MOB_SPELL("mobSpell", 9), MOB_SPELL_AMBIENT("mobSpellAmbient", 10), SPELL("spell", 11), INSTANT_SPELL("instantSpell", 12), WITCH_MAGIC("witchMagic", 13), NOTE("note", 14), PORTAL("portal", 15), ENCHANTMENT_TABLE("enchantmenttable", 16), EXPLODE("explode", 17), FLAME("flame", 18), LAVA("lava", 19), FOOTSTEP("footstep", 20), SPLASH("splash", 21), LARGE_SMOKE("largesmoke", 22), CLOUD("cloud", 23), RED_DUST("reddust", 24), SNOWBALL_POOF("snowballpoof", 25), DRIP_WATER("dripWater", 26), DRIP_LAVA("dripLava", 27), SNOW_SHOVEL("snowshovel", 28), SLIME("slime", 29), HEART("heart", 30), ANGRY_VILLAGER("angryVillager", 31), HAPPY_VILLAGER("happyVillager", 32), ICONCRACK("iconcrack", 33), TILECRACK("tilecrack", 34);
     
        private String name;
        private int id;
     
        ParticleEffect(String name, int id) {
            this.name = name;
            this.id = id;
        }
     
        public String getName() {
            return name;
        }
     
        public int getId() {
            return id;
        }
     
        private static final Map<String, ParticleEffect> NAME_MAP = new HashMap<String, ParticleEffect>();
        private static final Map<Integer, ParticleEffect> ID_MAP = new HashMap<Integer, ParticleEffect>();
        static {
            for (ParticleEffect effect : values()) {
                NAME_MAP.put(effect.name, effect);
                ID_MAP.put(effect.id, effect);
            }
        }
     
        public static ParticleEffect fromName(String name) {
            if (name == null) {
                return null;
            }
            for (Entry<String, ParticleEffect> e : NAME_MAP.entrySet()) {
                if (e.getKey().equalsIgnoreCase(name)) {
                    return e.getValue();
                }
            }
            return null;
        }
     
        public static ParticleEffect fromId(int id) {
            return ID_MAP.get(id);
        }
     
        public static void sendToPlayer(ParticleEffect effect, Player player, Location location, float offsetX, float offsetY, float offsetZ, float speed, int count) throws Exception {
            Object packet = createPacket(effect, location, offsetX, offsetY, offsetZ, speed, count);
            sendPacket(player, packet);
        }
     
        public static void sendToLocation(ParticleEffect effect, Location location, float offsetX, float offsetY, float offsetZ, float speed, int count) throws Exception {
            Object packet = createPacket(effect, location, offsetX, offsetY, offsetZ, speed, count);
            for (Player player : Bukkit.getOnlinePlayers()) {
                sendPacket(player, packet);
            }
        }
     
        public static void sendCrackToPlayer(boolean icon, int id, byte data, Player player, Location location, float offsetX, float offsetY, float offsetZ, int count) throws Exception {
            Object packet = createCrackPacket(icon, id, data, location, offsetX, offsetY, offsetZ, count);
            sendPacket(player, packet);
        }
     
        public static void sendCrackToLocation(boolean icon, int id, byte data, Location location, float offsetX, float offsetY, float offsetZ, int count) throws Exception {
            Object packet = createCrackPacket(icon, id, data, location, offsetX, offsetY, offsetZ, count);
            for (Player player : Bukkit.getOnlinePlayers()) {
                sendPacket(player, packet);
            }
        }
     
        public static Object createPacket(ParticleEffect effect, Location location, float offsetX, float offsetY, float offsetZ, float speed, int count) throws Exception {
            if (count <= 0)
                count = 1;
            Object packet = getPacket63WorldParticles();
            setValue(packet, "a", effect.name);
            setValue(packet, "b", (float) location.getX());
            setValue(packet, "c", (float) location.getY());
            setValue(packet, "d", (float) location.getZ());
            setValue(packet, "e", offsetX);
            setValue(packet, "f", offsetY);
            setValue(packet, "g", offsetZ);
            setValue(packet, "h", speed);
            setValue(packet, "i", count);
            return packet;
        }
     
        public static Object createCrackPacket(boolean icon, int id, byte data, Location location, float offsetX, float offsetY, float offsetZ, int count) throws Exception {
            if (count <= 0)
                count = 1;
            Object packet = getPacket63WorldParticles();
            String modifier = "iconcrack_" + id;
            if (!icon) {
                modifier = "tilecrack_" + id + "_" + data;
            }
            setValue(packet, "a", modifier);
            setValue(packet, "b", (float) location.getX());
            setValue(packet, "c", (float) location.getY());
            setValue(packet, "d", (float) location.getZ());
            setValue(packet, "e", offsetX);
            setValue(packet, "f", offsetY);
            setValue(packet, "g", offsetZ);
            setValue(packet, "h", 0.1F);
            setValue(packet, "i", count);
            return packet;
        }
     
        private static void setValue(Object instance, String fieldName, Object value) throws Exception {
            Field field = instance.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(instance, value);
        }
     
        private static Object getEntityPlayer(Player p) throws Exception {
            Method getHandle = p.getClass().getMethod("getHandle");
            return getHandle.invoke(p);
        }
     
        private static String getPackageName() {
            return "net.minecraft.server." + Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
        }
     
        private static Object getPacket63WorldParticles() throws Exception {
            Class<?> packet = Class.forName(getPackageName() + ".Packet63WorldParticles");
            return packet.getConstructors()[0].newInstance();
        }
     
        private static void sendPacket(Player p, Object packet) throws Exception {
            Object eplayer = getEntityPlayer(p);
            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;
                }
            }
        }
    }
    
     
    KingFaris11 and hawkfalcon like this.
  13. Offline

    Ultimate_n00b

    Thanks! =D
    Just curious, the below is supposed to work right?:
    Code:java
    1. ParticleEffect.sendToPlayer(ParticleEffect.LARGE_EXPLODE, event.getClicker(), event.getClicker().getLocation(), 1, 1, 1, 1, 100);
     
  14. Offline

    DarkBladee12

    Ultimate_n00b Yes, but it will not display all explosions cause the count is too high! You should also make the offset a random number in order to let it look like a real explosion ;)
     
  15. Offline

    CeramicTitan Retired Staff

    I have so many questions :p

    1) How do you know what to make the offset for each effect?
    2) How do you know what the to count? What even is the count?
    3) How do you know how fast to make each speed for each effect?
    4) How do I use this? Is it just as simple as "ParticleEffect.sendToPlayer(parameter, parameter, etc);"

    Regards,
    CeramicTitan
     
  16. Offline

    Taurhuzz

    Why is RED_DUST not red ._. It's more like rainbow. Is it possible to change it's color to only one?
     
  17. Offline

    DarkBladee12

    Taurhuzz Unfortunatley, no one has figured out how to set the color of this effect :/

    CeramicTitan
    1) I always use "new Random().nextFloat()" as the offset values, the offset is actually the where the particle would go!
    2) The count is how much of those particles should be displayed.
    3) You have to test which speed you want, it's actually how fast the particle effect is displayed but it doesn't affect all particle effects!
    4) Yes ;)
     
    CeramicTitan likes this.
  18. Offline

    CeramicTitan Retired Staff

    That is awesome! You should submit a PR to bukkit. :)
     
  19. Offline

    DarkBladee12

  20. Offline

    DSH105 Retired Staff

    DarkBladee12
    Your play(Location etc) still just sends it to all players. It's not the most efficient way of achieving it ;)
     
  21. Offline

    DarkBladee12

    _DSH105_ I'm aware of that, but by now it just sends it to all players in a world, I may also add a .play method with a range ;)
     
  22. Offline

    RingOfStorms

  23. Offline

    xTrollxDudex

    Bukkit doesn't implement packets nor plan on implementing it anytime soon
     
  24. Offline

    DSH105 Retired Staff

  25. Offline

    RingOfStorms

    iirc blockdust is the circular effect when you hit the ground from high altitudes. And I haven't tested the id_data, but since that is how it has always been, and the code splits "_" looking for 3 arguments, I'd assume so yes.
     
    DSH105 likes this.
  26. Offline

    DSH105 Retired Staff

  27. Offline

    DarkBladee12

    DSH105 I can't find the new particle packet, did they remove it or is it just not visible atm?
     
  28. Offline

    DSH105 Retired Staff

    It's called "PacketPlayOutWorldParticles"
     
  29. Offline

    DarkBladee12

  30. Offline

    DSH105 Retired Staff

Thread Status:
Not open for further replies.

Share This Page