Redefine what pistons push?

Discussion in 'Plugin Development' started by ZachBora, Feb 12, 2013.

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

    ZachBora

    Is it possible to redefine what a piston pushes? I know I can listen to the push event, but what I am interested is modifying what sends that event. Is that possible in a plugin or must it be done in a custom cb build?
     
  2. Offline

    caseif

    My guess would be that you would need to get the event's information and modify it, cancel the original event, then fire a new event with the modified information.
     
  3. Offline

    ZachBora

    So I create a MyPistonPushEvent extends BlockPushedByPistonEvent

    and in the listener

    if(not instanceof MyPistonPushEvent)
    {
    cancel event
    raise new MyPistonPushEvent with modified blocks
    if the new isnt canceled, move the blocks
    }
     
  4. Offline

    caseif

    Don't take my word for it, as I have no experience in this area, but I would think that you would just need to create a new BlockPushedByPistonEvent, or possibly a new PistonExtendEvent instead. But again, I have no clue what I'm talking about, so you may very well be right.
     
  5. Offline

    ZachBora

    Well I need to check if it is My event or it will go in infinite loop.

    But of course, if someone else does this in their plugin it will go in infinite loop... I'll give it a try tonight.
     
  6. Offline

    caseif

    Best of luck to you! :D
     
  7. Offline

    evilmidget38

    I'd honestly just do some NMS hacking for this.
     
  8. Offline

    ZachBora

    Like what? I don't usually play around with NMS. I've heard about reflection but I've no idea how that works.
     
  9. Offline

    evilmidget38

    ZachBora You can replace NMS's block objects with your own, if you so desire. Instead of the server using https://github.com/Bukkit/CraftBukk...in/java/net/minecraft/server/BlockPiston.java , you can unregister the block from https://github.com/Bukkit/CraftBukkit/blob/master/src/main/java/net/minecraft/server/Block.java#L21 or any other applicable Block arrays, and then use reflection to replace the static reference to the block. However, I'm not sure if block moving is handled within https://github.com/Bukkit/CraftBukk...va/net/minecraft/server/TileEntityPiston.java instead, in which case things become more difficult. If it's a tileentity, then you might find benefit in looking at bergerkiller's traincarts plugin, where he has to deal with custom entities(that persist between saves).

    Complicated stuff, perhaps un-needed, but I've found that if you work with NMS properly you often end up with less hacky results than if you use bukkit events. The more i think about this, though, the more it makes sense to try using the piston event first, despite the difficulties with that(although this is heavily influenced by me not knowing where the calculations are done in NMS, and how hacky the implementation looks).
     
  10. Offline

    ZachBora

    evilmidget38 I so started by finding where the event is thrown.
    https://github.com/Bukkit/CraftBukk...ava/net/minecraft/server/BlockPiston.java#L73
    So then I'm like... where the heck does it do the piston move? The only thing after checking if the event is cancelled is world.playNote. So I checked in pluginmanager.callEvent and there was nothing there.

    I checked the piston class to see where it moves stuff, that's in j(). Going up from there I find b() which is what world.playNote calls :|. Yep, let's put the sound AND movements inside the playNote...
    https://github.com/Bukkit/CraftBukk...va/net/minecraft/server/BlockPiston.java#L104


    So now that I have this BlockPiston.b(world,int,int,int,int,int) and BlockPiston.j(world,int,int,int,int), how do I replace them? I'm guessing I have to copy the whole class or to extend it and replace those 2 functions. But from there I have no idea...
     
  11. Offline

    evilmidget38

    ZachBora You're going to want to extend it. You can't override j as it's private, so you'll have to copy+paste or rewrite the method to suit your needs. b is public and non-static, and is the only method that calls j, so really the only method you'd minimally need to override.

    Once you have your replacement class, you'll want to first clear the id value from Block.byId, then you can create your new class. After that you can use reflection to replace the static reference to BlockPiston(reflection needed because it's final(Google how to do this, I know for a fact it's possible(I've done it). It requires reflection on reflection)).
     
  12. Offline

    Ne0nx3r0

    I'm really curious to see if you guys manage to sort this out. I've been trying to find this functionality for a while with no luck.
     
  13. Offline

    ZachBora

    What I eventually want to do is a way to push air blocks and maybe retract sticky pistons that will also retract the block they are next to. But mostly push air blocks.

    Of course, if every air block was pushed we'd have a problem. There will be limits to it. For instance, if there is
    <pushing piston><block><air><block><air><piston>
    It will not push the 2nd air block and piston.

    @evilmidget38 Ok we'll see how it goes. I might try it both ways (cancel event and raise new event, and replacing that block) to see if one is faster or less glitchy.

    Alright, it's sort of working. I was forced to use some NMS code unfortunatly, maybe you guys would have an idea to not use NMS. At worse, I'll use classloader to support multiple versions. It's the TileEntities that I've no idea if they exist in the Bukkit API...

    At the moment the code acts like a normal piston Except it also pushes Air and after 12 blocks it stops pushing.
    https://github.com/ZachBora/PistonMe/blob/master/src/com/worldcretornica/pistonme/PistonMe.java

    Edit: Did a commit that removes NMS references, but some blocks don't behave properly, like Redstone and any breakable blocks. It's probably something stupid.

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

    APlusMalware

    ZachBora
    You can look at the source of my PushablePumpkins plugin. It essentially replaces (with reflection) the material class of the Pumpkin block with a material that is able to be pushed. This won't work in all cases due to nonsensical NMS code, but it should usually work. Alternatively, you could replace the piston block with a modified version that replaces the methods that check the blocks mobility:
    https://github.com/Bukkit/CraftBukk...va/net/minecraft/server/BlockPiston.java#L246
    and
    https://github.com/Bukkit/CraftBukk...va/net/minecraft/server/BlockPiston.java#L271
     
  15. Offline

    ZachBora

    APlusMalware It's a good idea, but if I make every air pushable it'll always go over the max of 12 blocks. I need to make some air blocks not pushed.
     
  16. Offline

    APlusMalware

    ZachBora
    Oh, sorry, I seem to have skipped some posts. So couldn't you just modify the loops in j() and i() to suit your needs? Or am I missing something?
     
  17. Offline

    ZachBora

    It is what I did. And it worked mostly. I just have to check my code for errors.
     
Thread Status:
Not open for further replies.

Share This Page