[Help!] Explosion Effect (without damage or sound)

Discussion in 'Plugin Development' started by Btomhat, Aug 29, 2013.

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

    Btomhat

    i want to know how to make the explosion visual effect without the sound or damage. i can get it without damage but the sound it annoying after a while. please help me.
     
  2. Btomhat
    You can use ProtocolLib to remove sounds if certain conditions are true.

    I hate to bug you all the time, Comphenix , but you're the best man to explain this.
     
  3. Offline

    Btomhat

    thank you i'll send him a message and see what we can do. i appreciate it.
     
  4. Offline

    Comphenix

    Well, you could disable the explosion damage with a Bukkit event, and the sound with ProtocolLib (download):
    Code:java
    1. public class ExampleMod extends JavaPlugin implements Listener {
    2. private boolean suppressDamage;
    3.  
    4. @Override
    5. public void onEnable() {
    6. getServer().getPluginManager().registerEvents(this, this);
    7.  
    8. ProtocolLibrary.getProtocolManager().addPacketListener(
    9. new PacketAdapter(this, ConnectionSide.SERVER_SIDE, Packets.Server.NAMED_SOUND_EFFECT) {
    10. @Override
    11. public void onPacketSending(PacketEvent event) {
    12. String soundName = event.getPacket().getStrings().read(0);
    13.  
    14. if ("random.explode".equals(soundName) && suppressDamage) {
    15. event.setCancelled(true);
    16. }
    17. }
    18. });
    19. }
    20.  
    21. @EventHandler
    22. public void onEntityDamage(EntityDamageByBlockEvent event) {
    23. if(event.getCause().equals(DamageCause.BLOCK_EXPLOSION)) {
    24. if (suppressDamage) {
    25. event.setCancelled(true);
    26. }
    27. }
    28. }
    29.  
    30. @Override
    31. public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    32. if (sender instanceof Player) {
    33. Player player = (Player) sender;
    34.  
    35. createSoundlessExplosion(player.getLocation());
    36. }
    37.  
    38. return true;
    39. }
    40.  
    41. /**
    42.   * Create a soundless explosion at a given location.
    43.   * <p>
    44.   * Does not do any damage.
    45.   * @param loc - the location.
    46.   */
    47. private void createSoundlessExplosion(Location loc) {
    48. suppressDamage = true;
    49. loc.getWorld().createExplosion(loc, 10);
    50. suppressDamage = false;
    51. }
    52. }
     
  5. Offline

    Btomhat

    ok thnx
     
  6. Offline

    Drkmaster83

    Sorry to pop in like this, as this thread may be over and done with, but I'd just like to propose another way without ProtocolLib as a dependency.

    I, for whatever reason, have always been a person who is against using dependencies and always like to use methods that are domesticated within the plugin's .class files. So, you could remove ProtocolLib as a dependency and use Packet63WorldParticles (which is NMS code, requiring craftbukkit.jar).

    Here's a method to help you with setting the packet's data:
    Code:
    public void spawnExplosionParticles(Player player, Player receivingPacket)
        {
            // Make an instance of the packet!
            Packet63WorldParticles packet = new Packet63WorldParticles();
            for (Field field : packet.getClass().getDeclaredFields())
            {
                try
                {
                    field.setAccessible(true);
                    String fieldName = field.getName();
                    switch (fieldName)
                    {
                        case "a":
                            field.set(packet, "hugeexplosion"); //Particle name
                            break;
                        case "b":
                            field.setFloat(packet, player.getLocation().getBlockX()); //Block X
                            break;
                        case "c":
                            field.setFloat(packet, player.getLocation().getBlockY()); //Block Y
                            break;
                        case "d":
                            field.setFloat(packet, player.getLocation().getBlockZ()); //Block Z
                            break;
                        case "e":
                            field.setFloat(packet, 1); //Random X Offset
                            break;
                        case "f":
                            field.setFloat(packet, 1); //Random Y Offset
                            break;
                        case "g":
                            field.setFloat(packet, 1); //Random Z Offset
                            break;
                        case "h":
                            field.setFloat(packet, 0); //Speed/data of particles
                            break;
                        case "i":
                            field.setInt(packet, 15); //Amount of particles
                            break;
                    }
                } 
                catch (Exception e)
                {
                    System.out.println(e.getMessage());
                    return;
                }
            }
            ((CraftPlayer)player).getHandle().playerConnection.sendPacket(packet);
            ((CraftPlayer)receivingPacket).getHandle().playerConnection.sendPacket(packet);
        }
    If you wish for the player that the particles are being spawned on to have the particles client-side, then remove the receivingPacket player object from the method entirely. "player" is the player that the explosions will be spawned on. "receivingPacket" will be able to see the explosions being spawned on "player."

    You can find a detailed list of particle names here.

    Don't think that I'm dissing your beautiful work of art, Comphenix, I'm just not the kind of guy that wants to use dependencies.
     
  7. Offline

    Comphenix

    Oh, I wouldn't exactly call it a work of art either. ProtocolLib is merely a pragmatic solution to any lack of features in the Bukkit API, as a kind of last resort.

    Triggering an explosion particle is a fine solution, and is even native on Spigot (the PR is still pending for CraftBukkit), but it will invoke a bit more work if you also want to destroy blocks in the explosion.

    Incidentally, you can send these particle effects with ProtocolLib as well - that way, you'll be version-independent unlike your NMS solution:
    Code:java
    1. ProtocolManager manager = ProtocolLibrary.getProtocolManager();
    2.  
    3. if (sender instanceof Player) {
    4. Player player = (Player) sender;
    5. Packet3FParticle particle = new Packet3FParticle(ParticleEffect.HUGE_EXPLOSION, 1, player.getLocation(), new Vector());
    6.  
    7. // Send this effect to every player for sake of simplicity
    8. try {
    9. for (Player other : player.getWorld().getPlayers()) {
    10. manager.sendServerPacket(other, particle.getHandle());
    11. }
    12. e.printStackTrace();
    13. }
    14. }

    Just remember to add AbstractPacket and Packet3FParticle to your plugin.
     
    Assist likes this.
Thread Status:
Not open for further replies.

Share This Page