Random Item spawn

Discussion in 'Spigot Plugin Development' started by danichef, Apr 28, 2017.

  1. Hello, I am trying to make gold ingots spawn randomly in a radius of X blocks around this loction:
    Code (Text):
        World w = Bukkit.getServer().getWorld(settings.getData().getString("center.world"));
        double x = settings.getData().getDouble("center.x");
        double y = settings.getData().getDouble("center.y");
        double z = settings.getData().getDouble("center.z");
        p.teleport(new Location(w, x, y, z));
    How can I make this?
    Thanks for your time!
     
  2. yhl

    yhl

    Wait, so you want ingots to randomly spawn around the map?
     
  3. Just add some random values to the x / y / z values. Similar to this:

    Code (Text):

    Random random = new Random();

    int xNew = x + random.nextInt(radius.nextBoolean() ? radius : (-radius));
    int yNew = y + random.nextInt(radius.nextBoolean() ? radius : (-radius));
    int zNew = z + random.nextInt(radius.nextBoolean() ? radius : (-radius));
     
     
  4. You'll want to create a for loop that repeats the number of ingots you wish to drop

    Then a new ItemStack(Material.GOLD_INGOT,1);

    Assign that to a variable

    Then take your center location and add or subtract x/z values to it.

    Then get the world where the drop should occur

    wld.dropItemNaturally(item,newLoc);



    Sent from my iPhone using Tapatalk
     
  5. yhl

    yhl

    Code (Text):
        Random r = new Random();
        int x = r.nextInt(1000) + 1;
        int y = 80;
        int z = r.nextInt(1000)+1;
       
        Location loc = new Location(p.getWorld(), x,y,z)
       
        w.dropitemnaturally(loc, itemstack);
    That should work but its untested
     
  6. @Phloxz Where did you import/ get radius from?
    @yhl the 1000 you placed is radius?
    Also I supose I should add .getHighestBlockYAt for y shouldnt I?
     
  7. Don't use new Random() use
    Int z = ThreadLocalRandom.current.NextInt(minOffset,maxOffset);

    Will give you a random number between min and max


    Sent from my iPhone using Tapatalk
     
  8. @dNiym Whats the prob with new Random()?
     
  9. ThreadLocal keeps reusing the same random number generator while new random creates a new instance every time you call it. If you have this event happening often those new instances can pile up


    Sent from my iPhone using Tapatalk
     
  10. @dNiym So can I use it inside an scheduler so it has a cooldown?
     
  11. yhl

    yhl

    Oh I forgot about the radius
     
    • Funny Funny x 1
  12. Creating a new random instance once is not the reason why people should use the local thread random it also has been called once. Its basically a good and better display for some classes
     
  13. the radius is just a number like 50 blocks would be ( int radius = 50; )
     
  14. @Phloxz It gives me error "Cannot invoke nextBoolean() on the primitive type int" in .nextBoolean()
     
  15. Yes you'll want to get a block that is not underground obviously. You may also want it to be +\- 10 y because if they're in a cave and this happens and you use getHighest it could spawn them on the ground above them. Just do a check for block.getType() == Material.AIR before allowing the spawn.

    Your radius could really be anything I would suggest a minimum/max so it's less likely to pick a block right on top of the player.

    And yes you could run this on a task so that it has a cooldown before it'll happen again.

    If there are going to be multiple players with this perk/ability or whatever I would suggest making a timer class that handles all the spawns rather than a new runnable per player.




    Sent from my iPhone using Tapatalk
     
  16. Whoops used radius instead of random :confused:

    here's the fixed code:

    Code (Text):

    int xNew = x + random.nextInt(random.nextBoolean() ? radius : (-radius));
    int yNew = y + random.nextInt(random.nextBoolean() ? radius : (-radius));
    int zNew = z + random.nextInt(random.nextBoolean() ? radius : (-radius));
     
     
  17. He's creating one new instance of random per execution of this method, if this method gets called often it will create more overhead than threadlocalrandom which does not create a new instance. it re uses the one created for that memory thread. If you create a lot of new randoms often times if you display them you'll have synchronized results meaning randomA randomB and randomC are all the same "random number" even though you wasted the memory creating a new Random()


    Sent from my iPhone using Tapatalk
     
  18. Basically, he only used a random at the code to display why the "random" is there ..
    Just creating a static Random class would fix that
     
  19. Or you could use threadlocalrandom which prevents you from having to create that static random class and is its exact purpose.


    https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadLocalRandom.html

    Or the tldr version.
    When applicable, use of ThreadLocalRandom rather than shared Random objects in concurrent programs will typically encounter much less overhead and contention.

    Sent from my iPhone using Tapatalk
     
  20. the threadlocalrandom has been also created at some time so its not really a reason why people should use that.
    But ok, you still can use that or just a static random at the end its still a random class. This thread situation could go on with discussions about that but would end with the same reason over and over so i stop with that now.