Entity Move Event -or- How to Stop Mobs?

Discussion in 'Plugin Development' started by Steeveeo, Jul 27, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    Steeveeo

    Well, looking through the documentation, it seems that there is a definite lack of EntityMoveEvent within the Bukkit API.

    This question is for the development of my ElixirMod plugin, specifically the work-in-progress Elixir of Frost Touch. What this elixir buff is supposed to do is completely freeze a target in place for a couple seconds. This seems to work perfectly well on players, but the problem is that it's not meant strictly for PVP, and is more of a utility against mobs.

    The only way I can figure out a way to do this without some sort of event within Bukkit would be to configure a timer to run exactly on-tick (or close enough) that resets a "frozen" mob's position each run. The problem with this is that it's horribly contrived and would barely fit into the system I'm using.

    Tl;dr: want mob stun, no EntityMoveEvent to cancel.
    Is there something I missed? Does anyone have a better suggestion?
     
  2. Offline

    toi

    I was promised someone would make it a long time ago when i was talking on IRC (might have been cogito or what his name is). Have still not happened :( I dunno if no one just haven't done it or if it is not possible. Would be very nice to have this event and i can't come up with a workaround atm.
    (Wanted this for my old arrowturrets plugin)
     
  3. Offline

    Steeveeo

    Well, for lack of a better system, this is what I used:

    Constructor for the Frost Touch potion and data HashMaps:
    Code:java
    1.  
    2. //Constructor
    3. public Frosttouch()
    4. {
    5. //Init Freeze control loop timer
    6. Timer Timer = new Timer(true);
    7. Frosttouch_freezeController controller = new Frosttouch_freezeController();
    8. Timer.schedule(controller, (long) 0, (long) 50);
    9. }
    10.  
    11. private Map<Entity, Integer> FrozenTicks = new HashMap<Entity, Integer>();
    12. private Map<Entity, Location> FrozenPos = new HashMap<Entity, Location>();
    13.  


    Timer that keeps "frozen" entities in place:
    Code:java
    1.  
    2. private class Frosttouch_freezeController extends TimerTask
    3. {
    4. //Make sure all frozen mobs are stuck in place
    5. public void run()
    6. {
    7. Set<Entity> keys = FrozenTicks.keySet();
    8. for(Entity ent : keys)
    9. {
    10. //If this has an entry, freeze
    11. if(FrozenTicks.containsKey(ent) && FrozenTicks.get(ent) > 0)
    12. {
    13. //If moved, move back
    14. if(!FrozenPos.get(ent).equals(ent.getLocation()))
    15. {
    16. ent.teleport(FrozenPos.get(ent));
    17. }
    18. }
    19. }
    20. }
    21. }
    22.  


    While I have found a system that runs, I would not consider this a good way to do things, as a built-in event would work much better. However, I leave this here for anyone who wants to use this in lieu of a working EntityMoveEvent.
     
  4. Offline

    Shamebot

    I think you rather should use the bukkit scheduler.
    A EntityMoveEvent probably would be very spammy since there're a lot of entities, but something like Entity.freeze(true) would be nice.
     
  5. Offline

    Steeveeo

    I am pretty sure the Bukkit Scheduler is run-once, though I may be wrong. This timer sets the position per-tick (with some other stuff not pasted here for the length of the freeze), and if I am right about the scheduler, then setting new schedules every time seems about as spammy to me.

    I too would like an Entity.setFrozen(bool) or Entity.freeze()/unfreeze() function. Would also help for some admin plugins to freeze problem players.

    EDIT: ah, found in the documentation:
    scheduleSyncRepeatingTask(Plugin plugin, Runnable task, long delay, long period)

    What advantages are there to this over a Java timer?
     
  6. Offline

    Shamebot

    Code:java
    1. Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin,new Frosttouch_freezeController(),0,1);

    Just change "extends TimerTask" to "extends Runnable".
     
  7. Offline

    Steeveeo

    So what are the advantages of that, then?
     
  8. Offline

    Shamebot

    Thread safety.
     
  9. Not only. Another advantage that is often neglected is that you are working with ticks instead of real time. Everything the server does is calculated in ticks, so that's the most effecient and safe way to have it happen on every x ticks.
    When the server lags (and that's nearly always the case - in small scales), timing stuff with milliseconds becomes inaccurate.
     
  10. Offline

    boduzapho

    Well not if you use native timers in java, instead of the bukkit tick timer. Using java timers I can guarantee execution on a fixed and accurate time schedule. With bukkits tick timer, the more lag you get the slower the timer.

    Thats crap.. Java timers run in a separate thread. when they die they have ZERO effect on bukkits main thread.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 18, 2016
  11. Yes, they run in a separate thread, that's why it's called >thread< safety. It doesn't count if the second thread dies, it does matter when one thread is writing to a variable while another thread is writing, too or reading it.
    In the above example the probably worst call is
    ent.teleport(FrozenPos.get(ent));
    cause this will throw a EntityTeleportEvent - calling the event handlers in the other plugins. But not from within minecrafts man thread but within the new thread... Spreading the non existent thread savety into other plugins...
     
    Deathmarine likes this.
  12. "That's crap" (if I may express it in your words) in this very outdated situation. The goal here wasn't to perform something after/every xxx seconds, but to keep an entity freezed. Since the server calculates entity movement each tick, it is a lot more helpful if you have a method that is executed each tick instead of every 50 milliseconds (not to speak of thread safety).
    If you read my previous post again, that's what I was stating as an advantage of the BukkitScheduler.

    BTW, do you realize this topic is almost a year old?
     
  13. Offline

    Deathmarine

    lol... V10lator and Bone008 is right use the scheduler. Me and V10lator actually argued this before.

    They may have zero effect on bukkits main thread as in execution however the methods you fire may have changed between threads. Example: if a player logs out after your thread pulls online players but then your thread fires off on that player that left. ConcurrentModficationException (experienced this first hand). Its just better to not run seperate threads outside bukkit.

    Wait a sec. Whats up with this Necro?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 18, 2016
    V10lator likes this.
  14. Offline

    boduzapho

    My point is, Tick based bukkit timers WILL slow when the server lags, a Java TimerTask will not.

    This is why we use them appropriately. I consider executing code from a one thread to another is just bad programming. A good portion of Bukkit programmers, well they should never try to write code, as they simply do not have a clue.

    But the truth of the matter is Java timers are more effective and more reliable than bukkits thread system. As far as your "ConcurrentModficationException" error, well that happens when you just don't understand HOW to use maps or how to modify them. Again inexperienced "script kiddies" are the majority, and they dont have the formal training to do things like this.

    You may think using the bukkit scheduler is safe, but that is because you do not know what you are doing in Java. Sorry if this seems harsh but it is the truth, and pushing bad advice because you are unable to do it correctly is also a very bad idea.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 18, 2016
  15. Offline

    Deathmarine

    This guy has been nothing but hostile from the get go. Oh great java genius, thank the lord that you necro'd the hell out of this thread.....
    Alright genius here:


    Exactly. So your thread pulls a Object and saves it and the server lags and boots everyone from the server the mircosecond after the thread runs. When you change the object, what happens then?

    Code:
     
    2012-04-04 19:39:12 [SEVERE] java.util.ConcurrentModificationException
    2012-04-04 19:39:12 [SEVERE] at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
    2012-04-04 19:39:12 [SEVERE] at java.util.AbstractList$Itr.next(Unknown Source)
    2012-04-04 19:39:12 [SEVERE] at java.util.AbstractCollection.removeAll(Unknown Source)
    2012-04-04 19:39:12 [SEVERE] at net.minecraft.server.World.tickEntities(World.java:1120)
    2012-04-04 19:39:12 [SEVERE] at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:542)
    2012-04-04 19:39:12 [SEVERE] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:449)
    2012-04-04 19:39:12 [SEVERE] at net.minecraft.server.ThreadServerApplication.run(SourceFile:492)
    2012-04-04 19:39:12 [SEVERE] Unexpected exception
    java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
    at java.util.AbstractList$Itr.next(Unknown Source)
    at java.util.AbstractCollection.removeAll(Unknown Source)
    at net.minecraft.server.World.tickEntities(World.java:1120)
    at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:542)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:449)
    at net.minecraft.server.ThreadServerApplication.run(SourceFile:492)
     
    
    Crash the main thread!!
    (add items to a player after they log out the split second after my thread ran)

    and if its sync'd or "async" what happens?
    Nothing cause the pull didn't have the object.


    To pull an Object from the main thread when it Could no longer exist is better programming then staying synced to the main thread and getting the information correct? So the harsh truth seems that I'm giving bad advice to "SCHEDULE" threads and stay sync'd to the main thread? Please reread your statement in full and get back to me.

    Facts:
    Bad programming is not understanding the system your attempting to hook into.
    Inexperience doesn't make you a script kiddie. Laziness does.
    If you had formal training this will make sense. Otherwise.
    I have no formal training. I learned java by staring at it (this is true). :D
     
  16. No, that's multitasking. But that only works if all called methods/variables/... are thread save and it's only useful if the code is optimized for it. Both don't apply to minecraft (and as a result to CraftBukkit).
    More efficient? depends on what you want to do. In a multitasking environment you are right, but even there the impact of using a Async*Task isn't that high compared to calling new Thread directly. If we would recode minecraft to allow full multitasking we either had to rewrite from scratch (that's what Spout does, not sure how multitasked their server is, through) or slown down the code execution cause of syncing overheads between the threads.
    Minecraft/CraftBukkit uses Maps/Sets/Lists internal and they will give you a ConcurrentModficationException if you call bukkit API functions. So Mojang and the Bukkit team are just inexperienced script kiddies in your eyes?
    [EDIT]Also a plugin that don't use *Tasks or Threads at all can crash (with a CME) cause your code will bring bukkit to call events and that events will get executed from other plugins. I explained that in another post before...[/EDIT]
    I think Sync*Tasks at the scheduler are threadsafe, yes, because they run in the main thread... Async*Tasks are not cause they run in their own thread. That's all explained here, too: http://wiki.bukkit.org/Scheduler_Programming but yea, the wiki has been written by inexperienced script kiddies, hasn't it?

    //EDIT: A bit to read for you:
    http://en.wikipedia.org/wiki/Task_(computing)
    http://en.wikipedia.org/wiki/Thread_(computer_science)#Multithreading
    http://en.wikipedia.org/wiki/Thread_safety
     
    Deathmarine likes this.
  17. Offline

    boduzapho

    Sure okay, I'm not going to sit here and argue with a 24 yrold kid. 99% of the people trying to make plugins are kids, and MIGHT have some experience with html or (Shiver) PHP. Your trying to compensate you ego by posting links written in wiki's by other people and that's not cutting it for me. Not to mention you seem to be completely off the point, which is.. Bukkit's tick based tasks will SLOW when the server cannot complete a loop in time. Basing a time based task on that will cause your time based event to also slow down and not run as expected.

    So you can drop it now, you have proven you can Google with the best of them. BTW when you were sperm I was writing TASM/MASM code. The really sad thing is these days programmers rely on libraries written by other people or compiler based addons (like Json). You guys never learned what it takes to do everything by hand. It is harder for me these days to code then back in the day, having to constantly debug open source libraries is a pain in the butt. Ive wasted too much time on this already.
     
  18. Offline

    chenr1

    LOL, so your ragging on them for being in their 20's?? So how old are you playing minecraft?
     
  19. Offline

    CorrieKay

    he's 44 years old, and he should probably drop the age elitism, because i know 18 year olds who could probably outprogram him
     
  20. So what? Assembler was a common language in the past, but today the use case is small. You see some small inline Assembler codes in libraries like Mesa... That's completely off topic, I know, but your personal attacks are off topic, too.
    I'm proving my words by wiki entries written by other people. What are you doing to prove your words other than arguing "everybody except me is a kiddie, I'm a old school Assembler dev! You are just trying to compensate your ego and I am right, no discussion!"
    The point is that a server has to do a loop in time. What hardcore code are you writing that you worry it could slow down the server that much? Assuming one loop == one tick and building a task system into that is what the BukkitScheduler does, so yes you code will execute in the loop and as such the loops execution time will be higher. But by how much? A loop has 1/20 second to finish. If you execute your code in another thread instead you have to synchronize it with the main thread, this synchronization will block the main thread and as a result slow down the loop. This is simply cause minecraft isn't designed for multitasking.
    The really sad thing these days is old school programmers had to write everything for themself cause there were no good libraries. Todays (open) standards changed this but that guys don't see the good sides of libraries, just the bad one they know from the past. I know what it takes to do everything by hand and cause of that I use libraries. Who are you to tell what I know and what not?
    Now you say the point: It's harder for you. That doesn't mean the old way is the best way.
     
  21. Offline

    dxwarlock

    I fail to see how the logic of age plays into proficiency in a given subject.

    I've seen guys in their 30's out do men in their 50-60's for fine woodcrafting..
    I've seen guys in their 20's out do men in their 40's for car repair.
    I've seen guys of all ages, be more adept at various things that older men, that's spent decades more doing it, cant do.

    If your basis of quality and skill is based solely on age and years spent preforming the task, and not the quality of the work, do not open a business, as you will hire the wrong people.

    But its always refreshing to see that the old parable of "old men are wiser" is still tossed around as if its a given truth without question.

    yes yes we get it, back in your day, you coded, uphill, both ways, in the snow, with a loose leaf folder full of punchcards that you had to burn the used ones for warmth...kids these days don't know how much of a 'real programmer' it took back in those days...

    At my age, if Ive learned ONE thing in 40 years, its to follow this rule:
    You may know 99% of something, and someone else knows only 2% about it....listen to them anyway without belittle them..part of that 2%, may be some of the 1% you DON'T know.

    I've learned many things from many people, in areas in my younger years I thought I was "master of all" in..and someone doing it a 1/4 as long as me, shows me a trick I never knew before.

    if anything about guys my age annoys me, its their arrogance to assume that being around longer means you know more by default.
     
  22. Offline

    CorrieKay

    pfffhahaha, i freaking lost it at this bit! :D
     
    bitWolfy, bobacadodl and monstuhs like this.
  23. Offline

    soulofw0lf

    there is no reason for this post to reincarnate yearly... please let it die.. it's had a good life...
     
    TheMintyMate likes this.
Thread Status:
Not open for further replies.

Share This Page