--- a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
+++ b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
@@ -25,146 +25,168 @@
 import org.apache.commons.lang3.mutable.MutableObject;
 
 public class InteractWithDoor {
+
     private static final int COOLDOWN_BEFORE_RERUNNING_IN_SAME_NODE = 20;
-    private static final double SKIP_CLOSING_DOOR_IF_FURTHER_AWAY_THAN = 3.0;
-    private static final double MAX_DISTANCE_TO_HOLD_DOOR_OPEN_FOR_OTHER_MOBS = 2.0;
+    private static final double SKIP_CLOSING_DOOR_IF_FURTHER_AWAY_THAN = 3.0D;
+    private static final double MAX_DISTANCE_TO_HOLD_DOOR_OPEN_FOR_OTHER_MOBS = 2.0D;
+
+    public InteractWithDoor() {}
 
     public static BehaviorControl<LivingEntity> create() {
-        MutableObject<Node> mutableObject = new MutableObject<>(null);
-        MutableInt mutableInt = new MutableInt(0);
-        return BehaviorBuilder.create(
-            context -> context.group(
-                        context.present(MemoryModuleType.PATH),
-                        context.registered(MemoryModuleType.DOORS_TO_CLOSE),
-                        context.registered(MemoryModuleType.NEAREST_LIVING_ENTITIES)
-                    )
-                    .apply(
-                        context,
-                        (path, doorsToClose, mobs) -> (world, entity, time) -> {
-                                Path pathx = context.get(path);
-                                Optional<Set<GlobalPos>> optional = context.tryGet(doorsToClose);
-                                if (!pathx.notStarted() && !pathx.isDone()) {
-                                    if (Objects.equals(mutableObject.getValue(), pathx.getNextNode())) {
-                                        mutableInt.setValue(20);
-                                    } else if (mutableInt.decrementAndGet() > 0) {
-                                        return false;
-                                    }
+        MutableObject<Node> mutableobject = new MutableObject((Object) null);
+        MutableInt mutableint = new MutableInt(0);
 
-                                    mutableObject.setValue(pathx.getNextNode());
-                                    Node node = pathx.getPreviousNode();
-                                    Node node2 = pathx.getNextNode();
-                                    BlockPos blockPos = node.asBlockPos();
-                                    BlockState blockState = world.getBlockState(blockPos);
-                                    if (blockState.is(BlockTags.WOODEN_DOORS, state -> state.getBlock() instanceof DoorBlock)) {
-                                        DoorBlock doorBlock = (DoorBlock)blockState.getBlock();
-                                        if (!doorBlock.isOpen(blockState)) {
-                                            doorBlock.setOpen(entity, world, blockState, blockPos, true);
-                                        }
+        return BehaviorBuilder.create((behaviorbuilder_b) -> {
+            return behaviorbuilder_b.group(behaviorbuilder_b.present(MemoryModuleType.PATH), behaviorbuilder_b.registered(MemoryModuleType.DOORS_TO_CLOSE), behaviorbuilder_b.registered(MemoryModuleType.NEAREST_LIVING_ENTITIES)).apply(behaviorbuilder_b, (memoryaccessor, memoryaccessor1, memoryaccessor2) -> {
+                return (worldserver, entityliving, i) -> {
+                    Path pathentity = (Path) behaviorbuilder_b.get(memoryaccessor);
+                    Optional<Set<GlobalPos>> optional = behaviorbuilder_b.tryGet(memoryaccessor1);
 
-                                        optional = rememberDoorToClose(doorsToClose, optional, world, blockPos);
-                                    }
+                    if (!pathentity.notStarted() && !pathentity.isDone()) {
+                        if (Objects.equals(mutableobject.getValue(), pathentity.getNextNode())) {
+                            mutableint.setValue(20);
+                        } else if (mutableint.decrementAndGet() > 0) {
+                            return false;
+                        }
 
-                                    BlockPos blockPos2 = node2.asBlockPos();
-                                    BlockState blockState2 = world.getBlockState(blockPos2);
-                                    if (blockState2.is(BlockTags.WOODEN_DOORS, state -> state.getBlock() instanceof DoorBlock)) {
-                                        DoorBlock doorBlock2 = (DoorBlock)blockState2.getBlock();
-                                        if (!doorBlock2.isOpen(blockState2)) {
-                                            doorBlock2.setOpen(entity, world, blockState2, blockPos2, true);
-                                            optional = rememberDoorToClose(doorsToClose, optional, world, blockPos2);
-                                        }
-                                    }
+                        mutableobject.setValue(pathentity.getNextNode());
+                        Node pathpoint = pathentity.getPreviousNode();
+                        Node pathpoint1 = pathentity.getNextNode();
+                        BlockPos blockposition = pathpoint.asBlockPos();
+                        BlockState iblockdata = worldserver.getBlockState(blockposition);
 
-                                    optional.ifPresent(
-                                        doors -> closeDoorsThatIHaveOpenedOrPassedThrough(
-                                                world, entity, node, node2, (Set<GlobalPos>)doors, context.tryGet(mobs)
-                                            )
-                                    );
-                                    return true;
-                                } else {
+                        if (iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> {
+                            return blockbase_blockdata.getBlock() instanceof DoorBlock;
+                        })) {
+                            DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock();
+
+                            if (!blockdoor.isOpen(iblockdata)) {
+                                // CraftBukkit start - entities opening doors
+                                org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entityliving.level(), blockposition));
+                                entityliving.level().getCraftServer().getPluginManager().callEvent(event);
+                                if (event.isCancelled()) {
                                     return false;
                                 }
+                                // CraftBukkit end
+                                blockdoor.setOpen(entityliving, worldserver, iblockdata, blockposition, true);
                             }
-                    )
-        );
+
+                            optional = InteractWithDoor.rememberDoorToClose(memoryaccessor1, optional, worldserver, blockposition);
+                        }
+
+                        BlockPos blockposition1 = pathpoint1.asBlockPos();
+                        BlockState iblockdata1 = worldserver.getBlockState(blockposition1);
+
+                        if (iblockdata1.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> {
+                            return blockbase_blockdata.getBlock() instanceof DoorBlock;
+                        })) {
+                            DoorBlock blockdoor1 = (DoorBlock) iblockdata1.getBlock();
+
+                            if (!blockdoor1.isOpen(iblockdata1)) {
+                                // CraftBukkit start - entities opening doors
+                                org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entityliving.level(), blockposition1));
+                                entityliving.level().getCraftServer().getPluginManager().callEvent(event);
+                                if (event.isCancelled()) {
+                                    return false;
+                                }
+                                // CraftBukkit end
+                                blockdoor1.setOpen(entityliving, worldserver, iblockdata1, blockposition1, true);
+                                optional = InteractWithDoor.rememberDoorToClose(memoryaccessor1, optional, worldserver, blockposition1);
+                            }
+                        }
+
+                        optional.ifPresent((set) -> {
+                            InteractWithDoor.closeDoorsThatIHaveOpenedOrPassedThrough(worldserver, entityliving, pathpoint, pathpoint1, set, behaviorbuilder_b.tryGet(memoryaccessor2));
+                        });
+                        return true;
+                    } else {
+                        return false;
+                    }
+                };
+            });
+        });
     }
 
-    public static void closeDoorsThatIHaveOpenedOrPassedThrough(
-        ServerLevel world,
-        LivingEntity entity,
-        @Nullable Node lastNode,
-        @Nullable Node currentNode,
-        Set<GlobalPos> doors,
-        Optional<List<LivingEntity>> otherMobs
-    ) {
+    public static void closeDoorsThatIHaveOpenedOrPassedThrough(ServerLevel world, LivingEntity entity, @Nullable Node lastNode, @Nullable Node currentNode, Set<GlobalPos> doors, Optional<List<LivingEntity>> otherMobs) {
         Iterator<GlobalPos> iterator = doors.iterator();
 
         while (iterator.hasNext()) {
-            GlobalPos globalPos = iterator.next();
-            BlockPos blockPos = globalPos.pos();
-            if ((lastNode == null || !lastNode.asBlockPos().equals(blockPos)) && (currentNode == null || !currentNode.asBlockPos().equals(blockPos))) {
-                if (isDoorTooFarAway(world, entity, globalPos)) {
+            GlobalPos globalpos = (GlobalPos) iterator.next();
+            BlockPos blockposition = globalpos.pos();
+
+            if ((lastNode == null || !lastNode.asBlockPos().equals(blockposition)) && (currentNode == null || !currentNode.asBlockPos().equals(blockposition))) {
+                if (InteractWithDoor.isDoorTooFarAway(world, entity, globalpos)) {
                     iterator.remove();
                 } else {
-                    BlockState blockState = world.getBlockState(blockPos);
-                    if (!blockState.is(BlockTags.WOODEN_DOORS, state -> state.getBlock() instanceof DoorBlock)) {
+                    BlockState iblockdata = world.getBlockState(blockposition);
+
+                    if (!iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> {
+                        return blockbase_blockdata.getBlock() instanceof DoorBlock;
+                    })) {
                         iterator.remove();
                     } else {
-                        DoorBlock doorBlock = (DoorBlock)blockState.getBlock();
-                        if (!doorBlock.isOpen(blockState)) {
+                        DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock();
+
+                        if (!blockdoor.isOpen(iblockdata)) {
                             iterator.remove();
-                        } else if (areOtherMobsComingThroughDoor(entity, blockPos, otherMobs)) {
+                        } else if (InteractWithDoor.areOtherMobsComingThroughDoor(entity, blockposition, otherMobs)) {
                             iterator.remove();
                         } else {
-                            doorBlock.setOpen(entity, world, blockState, blockPos, false);
+                            blockdoor.setOpen(entity, world, iblockdata, blockposition, false);
                             iterator.remove();
                         }
                     }
                 }
             }
         }
+
     }
 
     private static boolean areOtherMobsComingThroughDoor(LivingEntity entity, BlockPos pos, Optional<List<LivingEntity>> otherMobs) {
-        return !otherMobs.isEmpty()
-            && otherMobs.get()
-                .stream()
-                .filter(mob -> mob.getType() == entity.getType())
-                .filter(mob -> pos.closerToCenterThan(mob.position(), 2.0))
-                .anyMatch(mob -> isMobComingThroughDoor(mob.getBrain(), pos));
+        return otherMobs.isEmpty() ? false : (otherMobs.get()).stream().filter((entityliving1) -> { // CraftBukkit - decompile error
+            return entityliving1.getType() == entity.getType();
+        }).filter((entityliving1) -> {
+            return pos.closerToCenterThan(entityliving1.position(), 2.0D);
+        }).anyMatch((entityliving1) -> {
+            return InteractWithDoor.isMobComingThroughDoor(entityliving1.getBrain(), pos);
+        });
     }
 
     private static boolean isMobComingThroughDoor(Brain<?> brain, BlockPos pos) {
         if (!brain.hasMemoryValue(MemoryModuleType.PATH)) {
             return false;
         } else {
-            Path path = brain.getMemory(MemoryModuleType.PATH).get();
-            if (path.isDone()) {
+            Path pathentity = (Path) brain.getMemory(MemoryModuleType.PATH).get();
+
+            if (pathentity.isDone()) {
                 return false;
             } else {
-                Node node = path.getPreviousNode();
-                if (node == null) {
+                Node pathpoint = pathentity.getPreviousNode();
+
+                if (pathpoint == null) {
                     return false;
                 } else {
-                    Node node2 = path.getNextNode();
-                    return pos.equals(node.asBlockPos()) || pos.equals(node2.asBlockPos());
+                    Node pathpoint1 = pathentity.getNextNode();
+
+                    return pos.equals(pathpoint.asBlockPos()) || pos.equals(pathpoint1.asBlockPos());
                 }
             }
         }
     }
 
     private static boolean isDoorTooFarAway(ServerLevel world, LivingEntity entity, GlobalPos doorPos) {
-        return doorPos.dimension() != world.dimension() || !doorPos.pos().closerToCenterThan(entity.position(), 3.0);
+        return doorPos.dimension() != world.dimension() || !doorPos.pos().closerToCenterThan(entity.position(), 3.0D);
     }
 
-    private static Optional<Set<GlobalPos>> rememberDoorToClose(
-        MemoryAccessor<Mu, Set<GlobalPos>> queryResult, Optional<Set<GlobalPos>> doors, ServerLevel world, BlockPos pos
-    ) {
-        GlobalPos globalPos = GlobalPos.of(world.dimension(), pos);
-        return Optional.of(doors.<Set<GlobalPos>>map(doorSet -> {
-            doorSet.add(globalPos);
-            return doorSet;
+    private static Optional<Set<GlobalPos>> rememberDoorToClose(MemoryAccessor<Mu, Set<GlobalPos>> queryResult, Optional<Set<GlobalPos>> doors, ServerLevel world, BlockPos pos) {
+        GlobalPos globalpos = GlobalPos.of(world.dimension(), pos);
+
+        return Optional.of((Set) doors.map((set) -> {
+            set.add(globalpos);
+            return set;
         }).orElseGet(() -> {
-            Set<GlobalPos> set = Sets.newHashSet(globalPos);
+            Set<GlobalPos> set = Sets.newHashSet(new GlobalPos[]{globalpos});
+
             queryResult.set(set);
             return set;
         }));
