Percentages being weird?

Discussion in 'Spigot Plugin Development' started by MangoCodes, Jun 29, 2016.

  1. Code (Text):

    Set<UUID> set = new HashSet<>();

    Random random = new Random();
    int chance = random.nextInt(100) + 1;

    @EventHandler
    public void Chill(EntityShootBowEvent e) {
        if (!(e.getEntity() instanceof Player)) return;
        Player p = (Player) e.getEntity();
        if (p.getInventory().getItemInHand() == null) return;
        if (p.getInventory().getItemInHand().getItemMeta() == null) return;
        if (p.getInventory().getItemInHand().getItemMeta().getLore() == null) return;
        if (p.getInventory().getItemInHand().getType() == null) return;


        if (p.getInventory().getItemInHand().getItemMeta().getLore().contains(ChatColor.GOLD + "Chill I")) {
            if (chance <= 65) {
                Entity proj = e.getProjectile();
                set.add(proj.getUniqueId());
            }
        }
    }

      @EventHandler
      public void onEntityDamage(EntityDamageByEntityEvent e) {
          if (!(e.getEntity() instanceof Player)) return;
          if (!(e.getDamager() instanceof Arrow)) return;
          if (!(set.contains(e.getDamager().getUniqueId()))) return;

          Projectile arrow = (Arrow) e.getDamager();
          Player p = (Player) arrow.getShooter();
          Player damaged = (Player) e.getEntity();

          if (p.getInventory().getItemInHand().getItemMeta().getLore().contains(ChatColor.GOLD + "Chill I")) {
              damaged.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 80, 10));
              set.remove(e.getDamager().getUniqueId());
          }
      }
     
    For some reason it only works if the percentage is 50 or 70+
     
  2. Umm anything..?
     
  3. Note that you should only bump every 24 hours.
    Code (Text):
    Random random = new Random();
    int chance = random.nextInt(100) + 1;
    You did good on making the Random a field instead of making a new one every time you needed it, but you only have 1 random number that you set as field. You need to remove that field, and when you check if the value is smaller than or equal to 65, use random.nextInt()
     
    • Informative Informative x 1
  4. Just a suggestion, when dealing with percentages I find it much easier just to use Math.random(). if you want something that happens 65% of the time, you just do this:

    Code (Text):
    if(Math.random() <= 0.65) {
        // your code
    }
    I find it's usually just quicker and easier.
     
    • Informative Informative x 1
  5. So after I check if it's <= 65 add random.nextInt();?
     
  6. Don't use Math.random(), bad for performance, also when you put the field locally and not inside the method it will always be one value and won't change very time you shoot, instead I suggest a method, like this untested but it should work:
    Code (Java):
    Random rand = new Random();

    public boolean onChance(int percent) {
        double val = rand.nextDouble() * 100;
        return percent >= val
    }
    Again, not sure if it's 100% right or if it works but it's on the right path for what you should be doing instead of your current system
     
    • Informative Informative x 1
  7. @ExoticCode correct me if I'm wrong, but I believe Math.random() just uses nextDouble() on a Random saved in the Math class. So this won't change anything about performance.
     
  8. http://stackoverflow.com/questions/738629/math-random-versus-random-nextintint
    This explains why using Random#nextDouble is better on performance, it's very minuscule but it adds up so using Random#nextDouble is better to use (in my experience) I've used nextDouble since I honestly like it better. The Math class uses it internally, twice (I think) and it's not terribly bad or wrong just a little performance boost :p
     
  9. @ExoticCode the discussion on that page is Math.random() vs. Random#nextInt(n), not Math.random() vs. Random#nextDouble(). In the answer they even say that Math.random() just uses Random#nextDouble() and that thát is the one that it worse than nextInt.
     
  10. oh okay, I guess I didn't read it thoroughly enough but yeah using random.nextInt is less random then double since double has more options to choose from and can be a range of options for example 25.5% chance would be the same as 26% with nextInt so I guess either use Math.random() or Random.nextDouble() whatever is your preference.
     
  11. ThreadLocalRandom.current().nextInt(100)/1000;
    No problem.
     
  12. @ExoticCode actually, using a double might give you more precise numbers, since the range stays the same (1-100) it won't actually generate more 'random' numbers.

    @stoneminer02 might want to cast there as you will always get 0 now ;p
     
  13. Make it a double :3
     
  14. Math#random simply points to a Random#nextDouble invoked on a lazily initialized Random object.
     
  15. @Korengenv1 that's almost what I said, but it's indirectly lazy as the Random is held inside an inner class of Math which holds it and is initialized when the class is referenced.