Poisonous Mycelium

Discussion in 'Archived: Plugin Requests' started by TelephoneKiosk, Jul 8, 2014.

  1. Offline


    Plugin category: Misc

    Suggested name: Deadly Mycelium

    What I want: Whenever a player is standing on Mycelium, they take a configurable amount of damage every X seconds

    Messages: When a player first takes damage from Mycelium, a configurable message will display


    Ideas for permissions: Players with mycelium.ignore will not take damage from Mycelium

    When I'd like it by: I'd like it by today please​

  2. Offline


    I'll make it.
  3. Offline


    Here is the download:

    mycelium.ignore : Makes the player not take damage on mycelium

    There is a config file for it and it runs on CraftBukkit 1.7.9

    If you want a different version, an update, or anything in the future/now just message me on Bukkitdev and I'll help you. If you want the source you can also message me for that.

    The actual plugin page I made is here, for everyone to use.
  4. Offline


  5. Offline

    timtower Administrator Administrator Moderator

    marwzoor Quote from the rules.
  6. Offline


    Okaaaaay? Haha wtf.


    I hope you didn't make a runnable that runs every second since that would drain the server power and is very inefficient ;)

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


    Beeperdp That plugin is horrible inefficient as marwzoor said use events not a unnecessary runnable that fires every single second not to mention you looping through every online player every second
  8. Offline


    I'm just trying to help, marwzoor is better at coding then me, but you don't have to be mean about it.
    timtower likes this.
  9. Offline


    Onlineids Beeperdp marwzoor

    Well, in 99,99% of all cases Onlineids and marwzoor are right, but this is a special one I think.

    On a small server, on which only a few players are playing it'd of course the best way to check for a player move event.

    But imagine the server is larger, it is very likely that the PlayerMoveEvent is fired very very often for a large amount of players, since moving is the thing players normally do.

    So running a runnable that runs every single second can be performanter than listening for the player move event which will be fired even if a player just spins around.

    The best solution I imagine would be checking in how often the the plugin's player move evnt get's fired (check this on a seperaate thread if possible) and then (if necessary) unregistered from the event and run the runnable instead.
    After a certain amount of time (or amount of online players) stop the runnable and register the move event instead, going to point 1.
    So you can check the best solution at runtime.

    That's my solution, feel free to reply your suggestions. I opened a thread about exactly this topic a few weeks ago, feel free to report there, since this is the request section and we're a little ot.
    €dit: Thread: https://forums.bukkit.org/threads/playermoveevent-vs-scheduler.278806/
  10. Offline


  11. Offline


    Zupsub The runnable is fired every second for every player on the server, on a large server this can mean hundreds of tasks running at once, so no this is not a special case.... This is unefficient as I stated before. Use PlayerMoveEvent
  12. Offline


    Onlineids If i were to revise that runnable though, then it might become a plausible result.
  13. Offline


    Beeperdp Why? PlayerMoveEvent does what you do more efficiently more effectively and more easily there is 0 reason to use a runnable for this...
  14. Offline


    Well a server with hundreds of players, its very likely most of them are moving / spinning => so the PlayerMoveEvent will be fired for (almost) every player probably more often than once (or even twice) per second.

    I'll run some checks, verifying / denying my opinion on my testserver tomorrow.
  15. Offline


    Zupsub Yea but he unlike the runnable the move event can be quickly returned after verifying that they are not on mycelium, there is no circumstance where your way would be better for this plugin.
  16. Offline


    Let us consider this, we have a 100 player server and everyone is online and moving around.

    Scenario 1:
    Every 2 seconds we loop 100 times and check if the player is on a block. That is an average of 50 'checks' per second.

    Scenario 2:
    All 100 players are constantly moving and the event is fired every tick. That is 2000 'checks' per second there. Not only are you checking which block the player is standing on you are also checking if it is the right time to apply damage.
  17. Offline


    In scenario 2 you return if the block they are standing on is not mycelium, that isn't a check that is virtually nothing.
    While in scenario 1 he is looping through everyone instead of the one person listed above and has entire code surrounded in if statement making it very inefficient
  18. Offline


    I am considering a 'check' to be the checking of whether or not they are standing on mycelium here, which is required in both scenarios. Also that check may be almost nothing, and in scenario 2 it is only per person, however the event will be fired every tick for every player which is much more than looping through online players.
  19. Offline


    The PlayerMoveEvent has to be called for every (moving) player, so there's no difference than looping threw (prep?) every player.
    Technically it's BETTER using a loop, since reflection for searching a method containing a PlayerMoveEvent parameter and a EventHandler annotation coast more "time" than a simple loop.
  20. Offline


    Zupsub electro4fun Im guessing neither of you actually looked at the code which is what I was referring to.... He has his runnable surrounded with a if statement which is inefficient by itself then he runs that code for every person every second...
  21. Offline


    Ignoring reflection and all of that, the loop still has less checks per second than the event.

    Consider this then:
    1. public void run() {
    2. for(Player p : Bukkit.getOnlinePlayers()){
    3. if(p.getLocation().add(0, -1, 0).getBlock().getType().equals(Material.MYCELIUM)){
    4. if(p.hasPermission("mycel.poison")){
    5. //give damage
    6. }
    7. }
    8. }
    9. }

    Where this is run every X seconds.

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


    instead of adding -1 to the y axis couldn't you subtract?
    Not that it matters, though.
  23. Offline


    Beeperdp and izarooni like this.
  24. Offline


  25. Offline

    timtower Administrator Administrator Moderator

    Why not check a smaller amount of players each time instead of checking them all at once? Then you spread the load a bit. Not sure how it performs against the move event, but hey, stand still on mycelium and you are safe.
    izarooni likes this.
  26. Offline


    Beeperdp I didn't want you to think you were a bad coder. I was just a bit mad because I said that I would make the plugin and then you just made it? This wasted my time a lot. I thought you reserved the post if you said you would do it, correct me if I'm wrong.

    And to add into the discussion about playermove and scheduler;
    TelephoneKiosk specifically said that he wanted the damage period to be configurable, if you have a runnable then it would take more power if you decrease the period. The one I coded with the PlayerMoveEvent will only apply a scheduler when someone stands on mycelium. And also, how do you know when they "first" enter mycelium, so you can give the message if you use a scheduler?
  27. Offline


    Sorry - I hadn't refreshed the page when I posted my plugin to see that you had claimed that you would make it. I did edit to say that I beat you too it because of that, but I realize I shouldn't have done that. You coded yours better anyways :)
  28. Offline


    Onlineids Beeperdp marwzoor electro4fun timtower (?)

    First of all to your code:
    1. If comparing enums, please use == instead of .equals() so Block#getType() == Material.YYY
    2. Instead of coding it yourself and wasting time, use ChatColor.translateAlternativeColorCodes(...)
    3. :eek::confused:
    Instead of
    1. for (World w : Bukkit.getWorlds()) {
    2. if (p.getWorld() == w)
    3. w.playSound(p.getLocation(), org.bukkit.Sound.SUCCESSFUL_HIT, 10.0F, 1.0F);
    4. }

    just do


    Okay, then to the Scheduler or Event discussion:
    I made a test plugin (download here). The result if you are moving the whole time:
    The PlayerMoveEvent is called EVERY TICK (97 of 100 ticks). So with a scheduler running every second tick you use only 50% of time compared to the MoveEvent.

    But: If you run the scheduler every third tick and the player runs/jumps the whole time, you might not be able to detect every block the player moves above. So sometimes the player is at f.e. 0|0|0 and after three ticks at 0|2|0 so you miss one up to two blocks.
    I tested it with running every second tick and it didn't missed any block.


    Then I tested it, when I not walk continuously: The result is still clear! Since the event is fired if i move only my head too, it's more often called then the runnable. Of course there might be a time, when the event isn't fired (in my case "only" 454 out of 600 ticks), but that is still too much (300 ot of 600 ticks from the scheduler).

    So last but not least, you can heavily increase performance by running a scheduler instead of the PlayerMoveEvent! If you don't believe me, test yourself.
  29. Offline


    Thank you sir, hope this solves some people's confusion.
  30. Offline


    Using == and .equals() doesn't really matter, the result is the same.

    So I guess that playermoveevent is much more precise but the scheduler takes less power.
    electro4fun likes this.

Share This Page