--- a/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java
+++ b/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java
@@ -28,6 +28,11 @@
 import net.minecraft.world.phys.AxisAlignedBB;
 import net.minecraft.world.phys.Vec3D;
 
+// CraftBukkit start
+import org.bukkit.entity.Vehicle;
+import org.bukkit.event.vehicle.VehicleEntityCollisionEvent;
+// CraftBukkit end
+
 public class NewMinecartBehavior extends MinecartBehavior {
 
     public static final int POS_ROT_LERP_TICKS = 3;
@@ -516,6 +521,12 @@
 
     @Override
     public double getMaxSpeed(WorldServer worldserver) {
+        // CraftBukkit start
+        Double maxSpeed = this.minecart.maxSpeed;
+        if (maxSpeed != null) {
+            return (this.minecart.isInWater() ? maxSpeed / 2.0D : maxSpeed);
+        }
+        // CraftBukkit end
         return (double) worldserver.getGameRules().getInt(GameRules.RULE_MINECART_MAX_SPEED) * (this.minecart.isInWater() ? 0.5D : 1.0D) / 20.0D;
     }
 
@@ -544,7 +555,7 @@
 
     @Override
     public double getSlowdownFactor() {
-        return this.minecart.isVehicle() ? 0.997D : 0.975D;
+        return this.minecart.isVehicle() || !this.minecart.slowWhenEmpty ? 0.997D : 0.975D; // CraftBukkit - add !this.slowWhenEmpty
     }
 
     @Override
@@ -571,6 +582,14 @@
                     Entity entity = (Entity) iterator.next();
 
                     if (!(entity instanceof EntityHuman) && !(entity instanceof EntityIronGolem) && !(entity instanceof EntityMinecartAbstract) && !this.minecart.isVehicle() && !entity.isPassenger()) {
+                        // CraftBukkit start
+                        VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity());
+                        this.level().getCraftServer().getPluginManager().callEvent(collisionEvent);
+
+                        if (collisionEvent.isCancelled()) {
+                            continue;
+                        }
+                        // CraftBukkit end
                         boolean flag = entity.startRiding(this.minecart);
 
                         if (flag) {
@@ -597,6 +616,16 @@
                     Entity entity = (Entity) iterator.next();
 
                     if (entity instanceof EntityHuman || entity instanceof EntityIronGolem || entity instanceof EntityMinecartAbstract || this.minecart.isVehicle() || entity.isPassenger()) {
+                        // CraftBukkit start
+                        if (!this.minecart.isPassengerOfSameVehicle(entity)) {
+                            VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity());
+                            this.level().getCraftServer().getPluginManager().callEvent(collisionEvent);
+
+                            if (collisionEvent.isCancelled()) {
+                                continue;
+                            }
+                        }
+                        // CraftBukkit end
                         entity.push((Entity) this.minecart);
                         flag = true;
                     }
@@ -609,6 +638,14 @@
                 Entity entity1 = (Entity) iterator1.next();
 
                 if (!this.minecart.hasPassenger(entity1) && entity1.isPushable() && entity1 instanceof EntityMinecartAbstract) {
+                    // CraftBukkit start
+                    VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity1.getBukkitEntity());
+                    this.level().getCraftServer().getPluginManager().callEvent(collisionEvent);
+
+                    if (collisionEvent.isCancelled()) {
+                        continue;
+                    }
+                    // CraftBukkit end
                     entity1.push((Entity) this.minecart);
                     flag = true;
                 }
