1.15.2 Compare currentTimeMillis() after runTaskLater has different values

Discussion in 'Spigot Plugin Development' started by i998979, Jun 23, 2020.

  1. So this problem confused me for a long time
    Lets say I have these code

    plugin.getConfigManager().getEnemyDuration() = 40 tick
    Code (Java):
    Bukkit.getServer().getScheduler().runTaskLater(plugin, () -> {
        // If the calculation below is true
        if (bar.attemptRemove())
            // Config value, assumed true
            if (plugin.getConfigManager().isSelfEnabled())
                // Add player to BossBar viewer
                bar.getSelfBar().addPlayer(player);
       
    }, plugin.getConfigManager().getEnemyDuration());
    e_lastUpdate is an System.currentTimeMillis(), it updates whenever the player damage an entity
    Code (Java):
    public boolean attemptRemove() {
        long elapsedTime = System.currentTimeMillis() - e_lastUpdate;
        long confVal = plugin.getConfigManager().getEnemyDuration() / 20 * 1000L;
        if (elapsedTime - confVal >= 0) {
            removeEnemy();
            return true;
        }
        return false;
    }
    Code (Text):
    public void onDamage(EntityDamageEvent event) {
        Entity victim = event.getEntity();
        Bukkit.getScheduler().runTask(plugin, () -> {

            // Update e_lastUpdate

            // Update other player's boss bar
            for (Map.Entry<Player, HealthBar> entry : HealthBar.bars.entrySet()) {
                Player player = entry.getKey();
                HealthBar bar = entry.getValue();
               
                if (bar.getTarget() != null && bar.getTarget().equals(victim)) {
                   
                    bar.updateEnemy(player, (LivingEntity) victim, event.getDamage() * -1);
                   
                    Bukkit.getServer().getScheduler().runTaskLater(plugin, () -> {
                        if (bar.attemptRemove())
                            if (plugin.getConfigManager().isSelfEnabled())
                                bar.getSelfBar().addPlayer(player);
                       
                    }, plugin.getConfigManager().getEnemyDuration());
                }
            }
        }
    When the player damage an entity -> set e_lastUpdate to System.currentTimeMillis() -> Scheduler start delay(runTaskLater, 40 tick) runs -> 40 ticks later -> attemptRemove() -> If the elapsed time >= 40 tick -> remove boss bar

    The problem here is, the System.currentTimeMillis() inside attemptRemove() (inside the runTaskLater) should be > 40 tick (or 2000 ms)
    (Difference between elapsed time and config value should be larger or equals to 0, since it should be checked after a 40 tick runTaskLater scheduler)

    But as you can see in the picture, it gives give -3, 1, -12 6, which is not in my expectation. The scheduler ended earlier / System.currentTimeMillis() didn't give the updated value when I call it where the runTaskLater ends


    What's happening? and what I have to do in order to fix this issue? (Currently I'm accepting -20 instead of 0, ik this is a dumb idea but I dunno how)
    2020-06-24_00.46.24.png 2020-06-24_00.46.30.png 2020-06-24_00.46.45.png 2020-06-24_00.46.48.png
     
    #1 i998979, Jun 23, 2020
    Last edited: Jun 24, 2020
  2. drives_a_ford

    Moderator

    Just add debug messages to see which values you're subtracting exactly. I.e print out the value of confVal and elapsedTime.
     
    #2 drives_a_ford, Jun 23, 2020
    Last edited: Jun 23, 2020
  3. Yep I did it, the result is at the bottom, it gives me different value everytime
     
  4. drives_a_ford

    Moderator

    I'm not sure what your issue is exactly. All the screenshots indicate that the calculation is working exactly as you describe it. There isn't any "random small numbers" that I can see.

    But then again, you're clearly not showing the code that you're actually using, either.

    This could easily be an integer overflow issue if you're casting you long to an integer somewhere.
     
  5. Ohhhhh I think that's why the number is inaccurate. maybe I casted double or int to long somewhere. Will look into that

    The problem is a bit hard to explain as I'm running out of brain cells rn, will explain after I fixed the unexpected int cast and failed (hope not)
     
  6. The original post is updated, please check
     
  7. drives_a_ford

    Moderator

    You've still not managed to show the actual code you're using.

    With that said, the EntityDamageEvent gets called whenever any entity gets damaged by any other entity. This happens quite a lot and most of the time you (the player) have nothing to do with it (i.e bats flying into lava, mobs falling more than 3 blocks and so on).
    While you are keeping track of a "victim" by your "bar" object, you are updating e_lastUpdate regardless of the mob that's actually getting damaged.

    So between the 40 ms at which you scheduled the task and when the task executes, you've updated the value of e_lastUpdate because of some some other (unrelated) entities being damaged.
     
  8. drives_a_ford

    Moderator

  9. Thats a great tutorial, exactly what i need for now!
    Do u hv any other tutorials talking about when and how to use Builders, Managers, Factories? I wanna learn them too

    I'll created a new thread if i still getting issues after rewriting my code,
     
  10. drives_a_ford

    Moderator

    Googling "Java design patterns" leads me here.
     
    • Like Like x 1