Particles and flight

Discussion in 'Plugin Development' started by Techy4198, May 30, 2013.

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

    Techy4198

    hi im wondering is it possible to do these?
    1. make a circle of colored firework particles explode from the player, aligned around their line of sight, like a sonic boom effect?
    2. trail colored particles from the player (probably easiest one)
    3. make the player creative flying speed about 5x normal speed but still accelerate slowly
     
  2. 1. use sin and cos to generate the point you need at a circle, it is complex calculations to make it (I mean, really hard)
    2. use a block iterator and apply a affect every ... blocks
    3. you can try playing with player.setVelocity() but it wont be smooth
     
  3. Offline

    Techy4198

    1. i need examples, or a link to a tutorial. also another note, i want the particles to be emitted in high density clouds, and travel for a huge distance before despawning.
    2. that doesnt sound very smooth. i just want it like particles trail from firework rockets, but with low gravity (like firework explosion effect).
    3. i do want smooth. and i was thinking maybe an effect similar to Essensials's '/speed' command, but smoother starting and stopping.

    edit: if #1 is too hard, i will stick with a check if the player is facing sideways or vertical, and use their yaw and pitch and a few 90 degrees here and there to make it a basic but good effect.

    edit 2: for #3, im thinking maybe a high level speed potion effect that works on creative flying.

    if i must say, it is for an ambitious project of mine, only my second plugin, i want to make a sonic rainboom possible in minecraft. for all you non-bronies (probably most of you), here is what it looks like.
    [​IMG]
    but rather than asking someone to do it for me (which they probably wont), i want as much of the code to be mine as possible, which is why i split it into 3 generic features. also may need something for the rainbow colored trail, i can probably do the circular rainbow myself.

    got some code that checks if the player is looking along the x, y, or z axis. i will resort to this until i have the code i need.

    ok now i have a small HUGE problem. i cannot find how to launch firework particles anywhere. i know it is possible though, the MagicSpells plugin can do it.
    edit: turns out it resorts to launching a firework with a flight time of 0 ticks. dang. is this even possible? please tell me!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  4. Offline

    Techy4198

  5. Offline

    thebiologist13

    I would suggest using a PlayerMoveEvent listener. Every time the player moves when you have the plugin on, it spawns firework entities with your desired metadata. You also give them a slight downward velocity so they don't rise (but still keep the power low) like this:
    Code:java
    1. firework.setPower(1);
    2. firwork.setVelocity(new Vector(0,-1,0));

    Also, everytime the player moves foreward (acceleration), you get their velocity as a vector and multiply it. Then, when the vector magnitude exceeds a certain value (like 5.0), you stop multiplying the vector so they can decelerate. I will try to edit in an example here later. :)

    TL;DR: Use PlayerMoveEvents, Vector math, and the getTo(), getFrom(), setTo(), and setFrom() methods from a PlayerMoveEvent for smooth, but fast movement. Spawn fireworks with power 1 and a downward vector. Make a Sonic Rainboom when the vector magnitude > some amount.

    I hope I could help! :D
    ~thebiologist13 /)
     
  6. Offline

    Techy4198

    kind of helps. but i don't like the spherical bursts that fireworks create. i would prefer some info on how to spawn firework burst particles. i've heard it can be done server side. the velocity thing is simple, yet completely slipped my mind, so thanks. also with the particles, is it possible to set their velocity & life? since i want a flat circular boom that goes very far, like in the animation.
     
  7. Offline

    DarkBladee12

    Techy4198 It's not possible to create single firework particles.... You can see which particle effects are possible in this code:

    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;
                }
            }
        }
    }
    The particle effect "Fireworks Spark" are just those particles from a launching rocket!
     
  8. Offline

    thebiologist13

    Techy4198 You could try some NMS code. Looking at net.minecraft.server.EntityFireworks, there is a method (public void l_()) that looks like it broadcasts the explosion particles. It broadcasts it with "net.minecraft.server.World.broadcastEntityEffect(Entity entity, byte b)", where "entity" is the firework and "b" is the packet ID, I think (based on the packet protocol here: http://mc.kev009.com/Protocol#Entity_Status_.280x26.29). So, you may be able to try this:
    Code:java
    1. //WorldServer is a subclass of World
    2. net.minecraft.server.v1_5_R3.WorldServer nms;
    3.  
    4. //Assign nms with some casting from a Bukkit world...
    5. nms = ((CraftWorld) (Bukkit.getWorld("world")).getHandle();
    6.  
    7. //Pretend "myFirework" is the firework entity you spawned.
    8. EntityFireworks nmsFirework = ((CraftFirework) myFirework).getHandle();
    9.  
    10. //This will spawn the effect
    11. nms.broadcastEntityEffect(nmsFirework, (byte) 17);

    This might not be optimal if it is only your second plugin, because you will have to update this section of code each time Bukkit updates, but it should work.

    Hope I could help!
    ~thebiologist13
     
  9. Offline

    Techy4198

    so they're just the white things that come out the bottom of the rocket like the jet? i thought they could be colored... :(
    well i need those particles anyway for the trail leading up to the boom. how exactly would i go about spawning a single one?
     
  10. Offline

    DarkBladee12

    Techy4198 Yes that are just these white particles, maybe it's possible to make them colored, for example the effect "Mob Spell" spawns potion particles with different colors, but no one has figured out how to only display this effect with a specific color.
     
  11. Offline

    fromgate

    Hello,
    What will "produce" suspend and depthSuspend particles? I've tried both and did not see nothing...
     
Thread Status:
Not open for further replies.

Share This Page