[SPIGOT-5510] VehicleBlockCollisionEvent returns the wrong block Created: 12/Jan/20  Updated: 21/Jan/20  Resolved: 15/Jan/20

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Eccentric Devotion Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None
Environment:

macOS 10.15.2
Java 1.8.0_221


Attachments: PNG File 2020-01-12_23.33.37.png    
Version: git-Spigot-492a779-d208733
Guidelines Read: Yes

 Description   

The VehicleBlockCollisionEvent returns the block in the opposite direction to the collided block
Code used to test:

    List<BlockFace> faces = Arrays.asList(BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH, BlockFace.EAST);
    @EventHandler(ignoreCancelled = true)
    public void onVehicleBlockCollision(VehicleBlockCollisionEvent event) {
        if (event.getVehicle() instanceof Minecart) {
            Block block = event.getBlock(); // block in opposite direction of collision
            Bukkit.getLogger().info("event block: " + block.getType().toString());
            Block minecartBlock = event.getVehicle().getLocation().getBlock();
            for (BlockFace face : faces) {
                Block bb = minecartBlock.getRelative(face);
                Bukkit.getLogger().info(face.toString() + ": " + bb.getType().toString());
            }
        }
    }

Typical output of the above is:

[23:26:28 INFO]: event block: RAIL
[23:26:28 INFO]: NORTH: AIR
[23:26:28 INFO]: WEST: IRON_DOOR
[23:26:28 INFO]: SOUTH: AIR
[23:26:28 INFO]: EAST: RAIL


 Comments   
Comment by TheCreeperCow [ 21/Jan/20 ]

The fix in place currently does not fix the fact the event is not triggered if someone is riding the boat and collides into a block

Comment by Eccentric Devotion [ 13/Jan/20 ]

This fixed it for my use case:

if (vec3d1.x > vec3d.x) {
    bl = bl.getRelative(BlockFace.WEST);
} else if (vec3d1.x < vec3d.x) {
    bl = bl.getRelative(BlockFace.EAST);
} else if (vec3d1.z > vec3d.z) {
    bl = bl.getRelative(BlockFace.NORTH);
} else if (vec3d1.z < vec3d.z) {
    bl = bl.getRelative(BlockFace.SOUTH);
}
Comment by Eccentric Devotion [ 13/Jan/20 ]

It would seem this code section is wrong for starters:

} else if (vec3d.x < vec3d.x) {  // comparing the same vector
		bl = bl.getRelative(BlockFace.WEST);

Surely it should be:

} else if (vec3d1.x < vec3d.x) {  // comparing different vectors :)
		bl = bl.getRelative(BlockFace.WEST);
Comment by TheCreeperCow [ 13/Jan/20 ]

I have reviewed the code and attempted fixes however i cant get the event to fire properly and i cant get it to return the correct block im putting in a recommendation to deprecate this event im sorry if you wanted to use this.

Comment by Eccentric Devotion [ 13/Jan/20 ]

Relevant code from net.minecraft.server.Entity.java

// CraftBukkit start
if (positionChanged && getBukkitEntity() instanceof Vehicle) {
	Vehicle vehicle = (Vehicle) this.getBukkitEntity();
	org.bukkit.block.Block bl = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));

	if (vec3d1.x > vec3d.x) {
		bl = bl.getRelative(BlockFace.EAST);
	} else if (vec3d.x < vec3d.x) {
		bl = bl.getRelative(BlockFace.WEST);
	} else if (vec3d1.z > vec3d.z) {
		bl = bl.getRelative(BlockFace.SOUTH);
	} else if (vec3d1.z < vec3d.z) {
		bl = bl.getRelative(BlockFace.NORTH);
	}

	if (bl.getType() != org.bukkit.Material.AIR) {
		VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
		world.getServer().getPluginManager().callEvent(event);
	}
}
// CraftBukkit end
Comment by TheCreeperCow [ 13/Jan/20 ]

Im checking this out and it seems to be related and perhaps the source of https://hub.spigotmc.org/jira/browse/SPIGOT-5463

Generated at Tue Apr 15 11:10:09 UTC 2025 using Jira 10.3.3#10030003-sha1:d220e3fefc8dfc6d47f522d3b9a20c1455e12b7b.