Vehicle collision detection not working?

Discussion in 'Plugin Development' started by skipperguy12, May 4, 2013.

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

    skipperguy12

    I am trying to stop spectators from damaging vehicles, so far i've been able to make them: Stop breaking it, and stop entering it. Now, when I use this code to detect collision, it doesn't work:
    Code:
        @EventHandler
        public void onVehicleEntityCollision(VehicleEntityCollisionEvent event) {
     
            if ((event.getEntity() instanceof Player)) {
                Player player = (Player) event.getEntity();
     
                if (plugin.spectator.contains(player.getName())) {
     
                    event.setCollisionCancelled(true);
                }
            }
        }
    plugin.spectator does work, it worked for all the other vehicle events!
     
  2. Offline

    ZeusAllMighty11

    What are you trying to achieve here?
     
  3. Offline

    jorisk322

    Making it so they don't push carts around when they push them I guess.
     
  4. Offline

    evilmidget38

    EDIT: skipperguy12

    Unfortunately that can't be achieved using only the Bukkit API. I had to add this feature into a plugin I was working on, so I ended up asking bergerkiller how he did it in TrainCarts. It's been awhile since I did this, but from what I remember, it comes down to:
    • Create a class that extends the minecart you want to override(1.5 added in new Minecart entities).
    • Override the method(s) that handle collision, iterate through the colliding bounding boxes, and iterate over the nearby entities. If you find an entity you don't want to collide with, you remove them from the list of colliding bounding boxes.
    • Replace minecarts with your own minecart objects as necessary. If you want them to be preserved when the world is loaded you'll have to jump through a lot of hoops. I was lucky, and didn't have to, but I believe bergerkiller had to.
    As I don't remember a lot of the specific methods or code(and I can't access my code from here[And it wasn't updated to 1.5 by me]), you'll have to do a lot of digging around. Perhaps bergerkiller will drop by and help you out.

    EDIT: Replied to the wrong post, sorry jorisk.
     
    1 person likes this.
  5. Offline

    bergerkiller

    I ended up putting all the code that does this in BKCommonLib, and it works for all entities, not just minecarts. Essentially what I do is filter the 'collision boxes' list prior to actual collision is handled in the NMS.Entity.move() method. To do so I had to rewrite the entire move method and insert two calls where I filter it.

    https://github.com/bergerkiller/BKC...ntroller/EntityControllerCollisionHelper.java

    You can do the hard way and include 6 minecart class extensions, replace all minecarts and etc, or simply use BKCommonLib Entity Controllers to manage that for you. Also avoids having to update each new CB version.

    Code:
    CommonEntity<?> entity = CommonEntity.get(myBukkitEntity);
    entity.setController(new EntityController<CommonEntity<?>>() {
        public boolean onEntityCollision(Entity entity) {
            return false; // True to allow, False to deny
        }
     
        public boolean onBlockCollision(Block block, BlockFace hitFace) {
            return false; //True to allow, False to deny
        }
    });
    On another note: many Entity fields/methods used in the move() methods are protected, and can therefore not be used externally. This makes it impossible to move the move() method outside the Entity class, so you end up:
    • Using reflection
    • Including methods in the Entity class that make them public
    So I recommend you just take the easy way out and avoid all this trouble.
     
    microgeek likes this.
Thread Status:
Not open for further replies.

Share This Page