Way to allow placement which are normal not possible! (e.g. torch -> glass)

Discussion in 'Plugin Development' started by xGhOsTkiLLeRx, Jan 3, 2012.

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

    xGhOsTkiLLeRx

    Hey there!

    Any idea how I can place items (or allow it via an event) on blocks which won't be possible (normal)

    e.g. torch on glass!

    I already tried the onBlockPlace event, but it isn't fired because it's not possible to place it normally
    (https://gist.github.com/1536743 )

    Hope someone knows a way to do this ;)
     
  2. Offline

    wwsean08

    I'm not sure it will work, but a playerInteractEvent that way if they right click a glass block with a torch in their hand you can place it? I'm not sure it will work, but it's a thought.
     
  3. Offline

    bergerkiller

    Use onBlockCanPlace event in the Block Listener, optionally disable the physics event if that is needed for the block to stay alive.
     
    xGhOsTkiLLeRx likes this.
  4. Offline

    xGhOsTkiLLeRx

    @bergerkiller my hero <3

    EDIT:

    My debug message tells me, that the onBlockPhysics event is cancelled, but the items still drop off!

    Code:java
    1.  
    2. public void onBlockPhysics (BlockPhysicsEvent e) {
    3. if (e.isCancelled()) return;
    4. if (e.getBlock().getType() == Material.GLASS) {
    5. bogPlugin.log.info("PHYSICS: "+e.getChangedType().toString());
    6. bogPlugin.log.info("PHYSICS: IT'S GLASS!");
    7. e.setCancelled(true);
    8. bogPlugin.log.info("PHYSICS: CANCELLED!");
    9. }
    10. }
    11.  

    @bergerkiller
     
  5. Offline

    bergerkiller

    @xGhOsTkiLLeRx you need to cancel torch physics events instead. Torch breaking off is torch physics, not glass physics.

    The same could apply to the onBlockCanPlace though...you may have to allow placement of all blocks on glass.

    If you need help on how to obtain the block a torch is attached to, feel free to ask. Hint: it uses the directional material data type.
     
  6. Offline

    desht

    Not certain about this, but I believe what you need to do in your onBlockPhysics() is check if the item in the event's block is attached to a glass block, and then cancel the event. What you're cancelling is a physics event for the glass block itself, which won't help any items attached to it.

    E.g.
    Code:java
    1.  
    2. public void onBlockPhysics(BlockPhysicsEvent e) {
    3. MaterialData m = e.getBlock().getState().getData();
    4. if (m instanceof Attachable) {
    5. ma = (Attachable)m;
    6. if (e.getBlock().getRelative(ma.getAttachedFace()).getType() == Material.GLASS) {
    7. e.setCancelled(true);
    8. }
    9. }
    10. }
    11.  

    Off the top of my head, totally untested...
     
  7. Offline

    xGhOsTkiLLeRx

    Problem is that I get with the variable m the glass block and not the torch.

    And even the canceling of the whole event doesn't solve my issue....
     
  8. Offline

    bergerkiller

    So you don't get any torch physics event firing once the torch breaks? Seems unlikely...
     
  9. I'm pretty sure the event fires when the torch breaks...I remember using it
     
  10. Offline

    desht

    Weird. I had to go and test my code afterwards and (other than a couple of typos), it did what I expected. I get physics events fired for torches and other attachables.

    Update: no, you're right - I wasn't testing carefully enough. The physics event does not seem to fire for torches when they pop off a glass block. I instead see 2 physics event fired for the same block - the glass block.

    (I also noticed that the BlockCanBuildEvent getBlock() method always seems to return a block of type AIR, regardless of what I try to build on... bug?)
     
  11. Offline

    xGhOsTkiLLeRx

    Yeah. I ran into exactly the same problems. Only air as a block and only firing for the torch.

    Any idea how I could solve this?

    @tips48

    Nope. We both couldn't fire the event for torches.
     
  12. BLOCK_PHYSICS is called for every 6 adjacent blocks (which are not air) when a block somewhere changes. What I believe is happening (event fired twice for glass block but not for torch) is the following:

    - torch placed
    - BLOCK_PHYSICS fired for the adjacent blocks -> 1st event for glass block
    - torch notices it shouldn't be here -> drops off -> block changes to air
    - once again BLOCK_PHYSICS fired for the adjacent blocks because of the change from torch to air -> 2nd event for glass block

    There is no event fired for the changing block itself, don't ask me why.

    I acted on the assumption that allowing the block to be built in BlockCanBuildEvent would prevent the physics from updating or at least prevents the block itself from checking wether it can be there.
    The only other way that would come to my mind would be using PlayerInteractEvent, cancelling it, manually calling a BlockPlaceEvent and then explicitly set the block to a torch using setTypeIdAndData (I believe it was a method like that ...), which allows suppressing a block update IIRC.
     
  13. Weird.
    What bone said to do might work, or you could maybe listen to BLOCK_PLACE (or BLOCK_PHYSICS?) and then setTypeIdAndData() with the priority Monitor?
     
  14. Offline

    xGhOsTkiLLeRx

    okay guys. I hate physics when I wanna manipulate them!

    Second, code snippets? :D
    The method setTypeIdAndData is the following (int type, byte data, boolean applyPhysics)

    What do I need to put in at the byte argument?
     
  15. Agreed, manipulating physics is a hassle.
    The second argument needs the blocks data (guess what, that's why it's called setTypeIdAndData :p)
    For torches, that is: http://www.minecraftwiki.net/wiki/Data_values#Torches_and_Redstone_Torches
    You somehow need to get the direction it is being placed. Dunno if you can get the clicked BlockFace in PlayerInteractEvent. If you can't, you have a problem ...

    Code snippet:
    Code:
    byte data = ...;
    block.setTypeIdAndData(Material.TORCH.getId(), data, false);
    Amazingly helpful, isn't it? ;)

    Oh, I just recalled, there was a plugin called Tables that would allow you to place pressure plates on top of fences 'n stuff (also glass). That was prior to the update that allowed that by default.
    The plugin did it just the intended way, by using BlockCanBuildEvent and BlockPhysicsEvent.
    Source file:
    https://github.com/DemmyDemon/Table...onsept/bukkit/tables/TablesBlockListener.java
    Maybe it's a new bug in bukkit? You could try with BlockCanBuild once more.
     
  16. Offline

    mooman219

    Pressure plates are an exception as they fire their event in a special way when triggered.

    Aside from them, you need to edit the NMS (net.minecraft.server if you didn't know) if you want FULL control over the physics. It sucks. I tried to do it within bukkit, but there are just to many limitations. It is impossible unless in the nms.

    Check out my plugin LivingBuilding, it allows for well expanded control over block placement, far beyond tables and blocks on glass. I spent hours researching the nms from different sources and I earned myself a decent understanding of how it works, block wise. Right now I am doing a config rewrite because apparently people are confused with the current one.
     
Thread Status:
Not open for further replies.

Share This Page