1

I am creating some magic spells, and obviously I want a delay between each usage.

Now According to google, there are 1000000000 nanoseconds in a second.

However, the magic spell is recharging after less than two seconds.

@EventHandler
public void onInteract(PlayerInteractEvent e){
    Player p = e.getPlayer();
    if (p.getItemInHand().getType().equals(Material.BLAZE_ROD)){
        {
            {
                if (!kam.containsKey(p.getName())) kam.put(p.getName(), (long) 0);
                if (kam.get(p.getName()) < System.nanoTime()){
                    kam.remove(p.getName());
                    kam.put(p.getName(), System.nanoTime() + (1000000000 * 30));
                    //Do magic spell attack here.
                    }
                }
            }else{
                p.sendMessage(ChatColor.AQUA + "Skill recharging!");
            }
}

Obviously my code is trying to add the System.nanoTime() plus 30 seconds, and then checking if the current system nanoTime is greater than the one I put into the hashmap, and if it is, do the spell.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
Joehot200
  • 1,070
  • 15
  • 44
  • 2
    `1000000000 * 30` is certainly causing an integer overflow. Try with `1000000000L * 30` – Alexis C. Nov 29 '14 at 11:19
  • 1
    There seems little point in using `nanoTime` for calculations of this magnitude. If you don't really need to measure to the nearest thousand-millionth of a second then just use `currentTimeMillis` – Ian Roberts Nov 29 '14 at 11:27

2 Answers2

5

I suggest you print out the value 1000000000 * 30 and check it. You'll find it's wrapping around because it's too big to fit into an integer.

In other words, the following program:

public class Test
{
    public static void main(String args[])
    {
        System.out.println(1000000000 * 30);
        System.out.println(1000000000L * 30);
    }
}

prints out:

-64771072
30000000000

So, if you use the long variant, it will work fine.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Hang on, I have been programming since I was 11 and I didn't know that L at the end of a number turned it into a long? Wow. Many thanks for the help. – Joehot200 Nov 29 '14 at 11:23
5

bare numeric literals in Java are treated as ints, and thus your calculation overflows. One way to fix this is to perform the calculation with long literals, by adding L after the literal:

kam.put(p.getName(), System.nanoTime() + (1000000000L * 30L));
Mureinik
  • 297,002
  • 52
  • 306
  • 350