[Resource] Tornado! Spawn a tornado with zero client mods. v3.2

Discussion in 'Resources' started by LucasEmanuel, Nov 19, 2013.

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

    ArthurHoeke

    LucasEmanuel DevRosemberg Ok :p
    Now i got this but nothing is working... I get a error on spawnTornado...
    Code:
        if(commandLabel.equalsIgnoreCase("tornado")){
            Player s = (Player)sender;
            Vector vec = new Vector(2, 2, 2);
            Ores.spawnTornado(this, s.getLocation(), null, null, 200, 30);
     
  2. Offline

    DevRosemberg

    LucasEmanuel Can you provide a code to actually spawn the tornado correctly on V3? What i used appeared as an error in my IDE.
     
  3. Offline

    ArthurHoeke

    How to fix this?
    Code:
    package me.Arthurhoeke.Tutorial;
     
    import java.util.ArrayDeque;
    import java.util.HashMap;
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    import java.util.List;
     
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Color;
    import org.bukkit.Effect;
    import org.bukkit.FireworkEffect;
    import org.bukkit.FireworkEffect.Type;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Arrow;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.FallingBlock;
    import org.bukkit.entity.Fireball;
    import org.bukkit.entity.Firework;
    import org.bukkit.entity.LivingEntity;
    import org.bukkit.entity.Player;
    import org.bukkit.entity.Snowball;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.entity.EntityDamageByEntityEvent;
    import org.bukkit.event.entity.ProjectileHitEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.meta.FireworkMeta;
    import org.bukkit.metadata.FixedMetadataValue;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitRunnable;
    import org.bukkit.util.BlockIterator;
    import org.bukkit.util.Vector;
     
    public class Ores extends JavaPlugin implements Listener {
        /**
        * Spawns a tornado at the given location l.
        *
        * @param plugin
        *            - Plugin instance that spawns the tornado.
        * @param location
        *            - Location to spawn the tornado.
        * @param material
        *            - The base material for the tornado.
        * @param data
        *            - Data for the block.
        * @param direction
        *            - The direction the tornado should move in.
        * @param speed
        *            - How fast it moves in the given direction. Warning! A number greater than 0.3 makes it look weird.
        * @param amount_of_blocks
        *            - The max amount of blocks that can exist in the tornado.
        * @param time
        *            - The amount of ticks the tornado should be alive.
        * @param spew
        *            - Defines if the tornado should remove or throw out any block it picks up.
        */
        public static void spawnTornado(
                final JavaPlugin plugin,
                final Location  location,
                final Material  material,
                final byte      data,
                final Vector    direction,
                final double    speed,
                final int        amount_of_blocks,
                final long      time,
                final boolean    spew
        ) {
            // Modify the direction vector using the speed argument.
            if (direction != null) {
                direction.normalize().multiply(speed);
            }
       
            class VortexBlock {
       
                Entity entity;
             
                private boolean removable = true;
       
                private float ticker_vertical = 0.0f;
                private float ticker_horisontal = (float) (Math.random() * 2 * Math.PI);
       
                @SuppressWarnings("deprecation")
                public VortexBlock(Location l, Material m, byte d) {
       
                    if (l.getBlock().getType() != Material.AIR) {
       
                        Block b = l.getBlock();
                        entity = l.getWorld().spawnFallingBlock(l, b.getType(), b.getData());
       
                        if (b.getType() != Material.WATER)
                            b.setType(Material.AIR);
                     
                        removable = false;
                    }
                    else
                        entity = l.getWorld().spawnFallingBlock(l, m, d);
                 
                    addMetadata();
                    tick();
                }
             
                public VortexBlock(Entity e) {
                    entity    = e;
                    removable = false;
                    addMetadata();
                    tick();
                }
             
                private void addMetadata() {
                    entity.setMetadata("vortex", new FixedMetadataValue(plugin, "protected"));
                }
             
                public void remove() {
                    if(removable || (!spew && (entity instanceof FallingBlock))) {
                        entity.remove();
                    }
                    entity.removeMetadata("vortex", plugin);
                }
       
                @SuppressWarnings("deprecation")
                public VortexBlock tick() {
                 
                    double radius    = Math.sin(verticalTicker()) * 2;
                    float  horisontal = horisontalTicker();
                 
                    Vector v = new Vector(radius * Math.cos(horisontal), 0.5D, radius * Math.sin(horisontal));
                 
                    setVelocity(v);
                 
                    // Pick up blocks
                    Block b = entity.getLocation().add(v).getBlock();
                    if(b.getType() != Material.AIR) {
                        return new VortexBlock(b.getLocation(), b.getType(), b.getData());
                    }
                 
                    // Pick up other entities
                    List<Entity> entities = entity.getNearbyEntities(1.0D, 1.0D, 1.0D);
                    for(Entity e : entities) {
                        if(!e.hasMetadata("vortex")) {
                            return new VortexBlock(e);
                        }
                    }
                 
                    return null;
                }
       
                private void setVelocity(Vector v) {
                    entity.setVelocity(v);
                }
       
                private float verticalTicker() {
                    if (ticker_vertical < 1.0f) {
                        ticker_vertical += 0.05f;
                    }
                    return ticker_vertical;
                }
       
                private float horisontalTicker() {
    //                    ticker_horisontal = (float) ((ticker_horisontal + 0.8f) % 2*Math.PI);
                    return (ticker_horisontal += 0.8f);
                }
            }
       
            final int id = new BukkitRunnable() {
       
                private ArrayDeque<VortexBlock> blocks = new ArrayDeque<VortexBlock>();
       
                public void run() {
       
                    // Spawns 10 blocks at the time, with a maximum of 200 blocks at
                    // the same time.
                    for (int i = 0; i < 10; i++) {
                        if (direction != null) {
                            location.add(direction);
                        }
                     
                        checkListSize();
                        blocks.add(new VortexBlock(location, material, data));
                    }
                 
                 
                    // Make all blocks in the list spin, and pick up any blocks that get in the way.
                    ArrayDeque<VortexBlock> que = new ArrayDeque<VortexBlock>();
       
                    for (VortexBlock vb : blocks) {
                        VortexBlock temp = vb.tick();
                        if(temp != null) {
                            que.add(temp);
                        }
                    }
                 
                    for(VortexBlock vb : que) {
                        checkListSize();
                        blocks.add(vb);
                    }
                }
             
                // Removes the oldest block if the list goes over the limit.
                private void checkListSize() {
                    if (blocks.size() >= amount_of_blocks) {
                        VortexBlock vb = blocks.getFirst();
                        vb.remove();
                        blocks.remove(vb);
                    }
                }
             
            }.runTaskTimer(plugin, 5L, 5L).getTaskId();
       
            // Stop the "tornado" after the given time.
            new BukkitRunnable() {
                public void run() {
                    plugin.getServer().getScheduler().cancelTask(id);
                }
            }.runTaskLater(plugin, time);
        }
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){       
           
        if(commandLabel.equalsIgnoreCase("tornado")){
            Player s = (Player)sender;
            Vector vec = new Vector(2, 2, 2);
            Ores.spawnTornado(this, s.getLocation(), null, null, 200, 30);
        }
        return false;
        }
    }
     
  4. Offline

    darkness1999

    DevRosemberg ArthurHoeke

    Code:
            Tornado.spawnTornado(plugin, p.getLocation(), Material.WEB, (byte) 0, new Vector(2, 0, 2), 0.1, 100, (long) 30*20, true);
    This is working for me.

    LucasEmanuel

    Have you read my new ideas on the first comments page (posted some more...)?
     
  5. Offline

    DevRosemberg

    darkness1999 Well that works, thanks, i had forgoten to cast the Long and Byte.
     
  6. Offline

    DSH105

    I just started working on something that included this a little over a month ago ;o

    Nice job! :)
     
  7. Offline

    chasechocolate

    LucasEmanuel nicely done, my friend :D Sooooo going to use this in a minigame plugin.
     
    LucasEmanuel likes this.
  8. Offline

    chasechocolate

    LucasEmanuel I've been playing around with the particle effects, and got that to work and move in a single direction. How could I make it move randomly, or at least in different directions? Would I just need to change the direction to toLoc.toVector().subtract(fromLoc().toVector()).normalize()?
     
  9. Offline

    jusjus112

    LucasEmanuel
    How do it so, that the tornado pick up players?
     
  10. Offline

    Blah1

    This is amazing!
     
  11. Offline

    GermanCoding

    Really useful! Use it in a new gamemode plugin.
    Note: If you spawn the tornado with Material.AIR the client crashes :p.
     
    LucasEmanuel likes this.
  12. Offline

    LucasEmanuel

    You could probable make it randomly create a new direction vector every now and then. :)

    Hi guys, thanks so much for the appreciation! It means a lot to me. :)

    I need your help, the tornado isn't working as it should. As some have pointed out, the tornado doesn't pick up all of the blocks, it lifts them up then they immediately fall down again, the same goes for most entities.

    It is almost as if the entity-objects change every now and then for some entities making the tornado applying to calculated velocity to something else instead of the entities it has captured. If you can spot what I'm doing wrong or if there is something else in play here, I would love your help. :)

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

    DSH105

    You can take a look at mine if you want. I'm not sure that you'll find much to improve from it though :)
     
    LucasEmanuel likes this.
  14. Offline

    Ape101

    Quick few questions.
    What are the arguments for the direction the tornado moves?
    and is it possible to have the tornado made out of the clouds or smoke particles? making it look more like a tornado
     
  15. Offline

    LucasEmanuel

    Thanks, I fixed the problem earlier, forgot to post about it here. Thanks anyway :)

    The vector-argument is the one you are looking for. :) For the particles you should ask chasechocolate he is working on something like that. :)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
    DSH105 likes this.
  16. Offline

    Ape101

    chasechocolate would you be able to share your secrets with us? for mine and others sake
     
  17. Offline

    chasechocolate

    Ape101 yeah, I'll post some code here once I finish it.
     
  18. Offline

    darkness1999

    LucasEmanuel

    I can't find a use for this currently, although I'd like to use this.

    These ideas should make it possible to use this on servers that dont allow to break and place any blocks.
    • In general: A tornado should not pickup any fluids (water/lava) because too many water/lava causes massive lag on my server (on explosion)
    • boolean whether or not FallingBlocks should be placed. Why? Because a lot of people probably dont want placed tornado blocks on their servers (me too)
    • boolean whether or not entities (such as players, etc) should be picked up by the tornado. Why? This option allows more configuration.
    • boolean whether or not blocks should be picked up. Why? Because a lot of people probably dont want removed blocks in their cities (me too)
    • boolean whether or not the blocks, which were picked up should be removed from landscape
    Hope you like my ideas. Please tell me what you think of them!
    darkness1999
     
  19. Offline

    LucasEmanuel

    • A tornado should not pickup any fluids
      In my opinion it should, a tornado in real life can pick up fluids.
    • Boolean whether or not FallingBlocks should be placedI can not change this, that would require it to listen to events, which it can't.
    • Boolean whether or not entities (such as players, etc) should be picked up by the tornadoThis might be implemented in a future version. But for now, you will have to modify the code yourself if it bothers you.
    • Boolean whether or not blocks should be picked upThis will cause the tornado to look and behave very glitchy. If it doesn't pick up any blocks that is in its way, all of those FallingBlock-objects that are flying around will smash into those blocks and drop as ItemStacks (I can not stop this, it would require events to be cancelled). Basically, as soon as the tornado would collide with a structure or similar, the tornado would disappear until it has passed through the structure and then spawn again on the other side.
    • Boolean whether or not the blocks, which were picked up should be removed from landscapeI can not change this, requires eventlisteners.
     
  20. Offline

    BungeeTheCookie

    How about we just create a tornado library or API and post it on github, with all of those events registered into the plugin you are using. I would like to see some people contribute to this (even myself :D)
     
  21. Offline

    darkness1999

    LucasEmanuel

    • In my opinion it should, a tornado in real life can pick up fluids.
    Yes, this is more realistic, but it causes massive lag. Maybe a boolean to enable or disable this feature?

    Hmm, why you don't create some custom event listeners?

    darkness19
     
  22. Offline

    DSH105

    LucasEmanuel I think this would be a better option for this kind of resource. IMO a tornado shouldn't be something that is simplified into one method.
     
    Garris0n likes this.
  23. Offline

    BungeeTheCookie

    How about we all go and contribute into making a library or API for tornadoes :D
     
  24. Offline

    hkminegod

    Can I protect a specific area from the destruction of the tornado?
     
  25. Offline

    LucasEmanuel

    Not with only my code, no. :)

    darkness1999
    The original idea of this resource was to create a small and neat method that people could call to spawn a basic tornado. If I start to register event listeners and etc it would no longer be a small and neat method, it would be an entire plugin inside a single method, and I'm starting to think the code has gotten advanced enough.

    BungeeTheCookie DSH105
    Well, I can create a repo on my GitHub page, but I don't know when I will have the time to actually start working on a project like that. You could go ahead and start if you want to. :)

    EDIT:
    Repo created, pm me with your github username and I will add you as contrib. :)
    https://github.com/Chilinot/Tornado

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

    BungeeTheCookie

    LucasEmanuel
    I don't have a github yet xD. I'll create one today and start adding some code! When I have one made it will tag and private message you!

    LucasEmanuel
    My GitHub username is BungeeTheCookie

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

    Ultimate_n00b

    fallingBlock.setDropItem(false);
     
  28. Offline

    BungeeTheCookie

    I will add this to the GitHub respitory as soon as possible! Thank you!
     
  29. Offline

    darkness1999

  30. Offline

    LucasEmanuel

    Yes I know about this method. Maybe I wasn't clear enough on what I was talking about. The problem isn't really that they dropped ItemStack's, but that they get destroyed when they smash into the blocks. :)
     
Thread Status:
Not open for further replies.

Share This Page