From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 23 Aug 2020 20:59:00 +0200
Subject: [PATCH] Climbing should not bypass cramming gamerule


diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 7609a58979388cb62be7ae94a51cc14774464214..fc40880fadb20f7c274c94b1e6a2fa6d0118e672 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2219,6 +2219,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
     }
 
     public boolean isPushable() {
+        // Paper start - Climbing should not bypass cramming gamerule
+        return isCollidable(false);
+    }
+
+    public boolean isCollidable(boolean ignoreClimbing) {
+        // Paper end - Climbing should not bypass cramming gamerule
         return false;
     }
 
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
index b8d57e25851dd7da905100dfd4022e4b99fd7f02..721321a19ce056f82de2bef44a8791dc9d5b3418 100644
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
@@ -45,11 +45,16 @@ public final class EntitySelector {
     }
 
     public static Predicate<Entity> pushableBy(Entity entity) {
+        // Paper start - Climbing should not bypass cramming gamerule
+        return pushable(entity, false);
+    }
+    public static Predicate<Entity> pushable(Entity entity, boolean ignoreClimbing) {
+        // Paper end - Climbing should not bypass cramming gamerule
         PlayerTeam scoreboardteam = entity.getTeam();
         Team.CollisionRule scoreboardteambase_enumteampush = scoreboardteam == null ? Team.CollisionRule.ALWAYS : scoreboardteam.getCollisionRule();
 
         return (Predicate) (scoreboardteambase_enumteampush == Team.CollisionRule.NEVER ? Predicates.alwaysFalse() : EntitySelector.NO_SPECTATORS.and((entity1) -> {
-            if (!entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API
+            if (!entity1.isCollidable(ignoreClimbing) || !entity1.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(entity1)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
                 return false;
             } else if (entity1 instanceof Player && entity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions) { // Paper - Configurable player collision
                 return false;
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index b742a42b2c86db79fb88399f40e8682afd600507..f025d36c8ae8606172e8166721f09c851784c3cc 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3722,7 +3722,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
                 return;
             }
             // Paper end - don't run getEntities if we're not going to use its result
-            List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushableBy(this));
+            List list = this.level().getEntities((Entity) this, this.getBoundingBox(), EntitySelector.pushable(this, this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule)); // Paper - Climbing should not bypass cramming gamerule
 
             if (!list.isEmpty()) {
                 // Paper - don't run getEntities if we're not going to use its result; moved up
@@ -3923,9 +3923,16 @@ public abstract class LivingEntity extends Entity implements Attackable {
         return !this.isRemoved() && this.collides; // CraftBukkit
     }
 
+    // Paper start - Climbing should not bypass cramming gamerule
     @Override
     public boolean isPushable() {
-        return this.isAlive() && !this.isSpectator() && !this.onClimbable() && this.collides; // CraftBukkit
+        return this.isCollidable(this.level().paperConfig().collisions.fixClimbingBypassingCrammingRule);
+    }
+
+    @Override
+    public boolean isCollidable(boolean ignoreClimbing) {
+        return this.isAlive() && !this.isSpectator() && (ignoreClimbing || !this.onClimbable()) && this.collides; // CraftBukkit
+        // Paper end - Climbing should not bypass cramming gamerule
     }
 
     // CraftBukkit start - collidable API
diff --git a/src/main/java/net/minecraft/world/entity/ambient/Bat.java b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
index d8a2fbb33f4b77ffb1b3c928a369c2824ad815d7..60c2868f255d372226e0c1389caaa5477bbef41e 100644
--- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java
+++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java
@@ -91,7 +91,7 @@ public class Bat extends AmbientCreature {
     }
 
     @Override
-    public boolean isPushable() {
+    public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
         return false;
     }
 
diff --git a/src/main/java/net/minecraft/world/entity/animal/Parrot.java b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
index e9219921fe63a05bee4b6e18d5c1558cbcd88220..a2f0b79599799ad2aa85aff821d8ac76a8e650bd 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Parrot.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Parrot.java
@@ -362,8 +362,8 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder<Parrot
     }
 
     @Override
-    public boolean isPushable() {
-        return super.isPushable(); // CraftBukkit - collidable API
+    public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
+        return super.isCollidable(ignoreClimbing); // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
index 4e0ab5c3feb6350ab6c25db6227879d41ed8a749..709237639ef0ec1cb623f270302a27b0072e8685 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
@@ -369,7 +369,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
     }
 
     @Override
-    public boolean isPushable() {
+    public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
         return !this.isVehicle();
     }
 
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
index 59fbfe8de2dc5ec020dd61a5e446b0b6f67d76e4..2bb2b36f793d25b6e49d1a72bb665cfa9f212730 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -354,7 +354,7 @@ public class ArmorStand extends LivingEntity {
     }
 
     @Override
-    public boolean isPushable() {
+    public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
         return false;
     }
 
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
index 0e6e707935c6567b1fbad1d01ca48ac7eb3259ce..e2bbb4b519010cbabc0796c5b2f749b4fac32bb7 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractBoat.java
@@ -144,7 +144,7 @@ public abstract class AbstractBoat extends VehicleEntity implements Leashable {
     }
 
     @Override
-    public boolean isPushable() {
+    public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
         return true;
     }
 
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
index a4ab0e50a245790b1767047c384859f06c3f9526..fb9f0a62201dfeccd0eec9bb399f9edc6a01f1f0 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
@@ -161,7 +161,7 @@ public abstract class AbstractMinecart extends VehicleEntity {
     }
 
     @Override
-    public boolean isPushable() {
+    public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule
         return true;
     }