diff --git a/ClassicalSharp/Blocks/BlockInfo.cs b/ClassicalSharp/Blocks/BlockInfo.cs
index 42a0b51f5..492c2027e 100644
--- a/ClassicalSharp/Blocks/BlockInfo.cs
+++ b/ClassicalSharp/Blocks/BlockInfo.cs
@@ -61,6 +61,8 @@ namespace ClassicalSharp {
/// Lava style 'swimming'/'bobbing' interaction when player collides.
public const byte LiquidLava = 6;
+
+ public const byte ClimbRope = 7;
}
/// Stores various properties about the blocks.
diff --git a/ClassicalSharp/Blocks/DefaultSet.cs b/ClassicalSharp/Blocks/DefaultSet.cs
index 80c2656bf..e5a801f6d 100644
--- a/ClassicalSharp/Blocks/DefaultSet.cs
+++ b/ClassicalSharp/Blocks/DefaultSet.cs
@@ -54,6 +54,8 @@ namespace ClassicalSharp.Blocks {
}
public static byte MapOldCollide(BlockID b, byte collide) {
+ if (b == Block.Rope && collide == CollideType.Gas)
+ return CollideType.ClimbRope;
if (b == Block.Ice && collide == CollideType.Solid)
return CollideType.Ice;
if ((b == Block.Water || b == Block.StillWater) && collide == CollideType.Liquid)
diff --git a/ClassicalSharp/Entities/Entity.cs b/ClassicalSharp/Entities/Entity.cs
index 444a6de4a..1c01207f5 100644
--- a/ClassicalSharp/Entities/Entity.cs
+++ b/ClassicalSharp/Entities/Entity.cs
@@ -214,7 +214,7 @@ namespace ClassicalSharp.Entities {
return TouchesAny(bounds, touchesRope);
}
static Predicate touchesRope = IsRope;
- static bool IsRope(BlockID b) { return b == Block.Rope; }
+ static bool IsRope(BlockID b) { return BlockInfo.ExtendedCollide[b] == CollideType.ClimbRope; }
static readonly Vector3 liqExpand = new Vector3(0.25f/16f, 0/16f, 0.25f/16f);
diff --git a/ClassicalSharp/Singleplayer/LiquidPhysics.cs b/ClassicalSharp/Singleplayer/LiquidPhysics.cs
index 7e016ecab..7b5b65723 100644
--- a/ClassicalSharp/Singleplayer/LiquidPhysics.cs
+++ b/ClassicalSharp/Singleplayer/LiquidPhysics.cs
@@ -138,7 +138,7 @@ namespace ClassicalSharp.Singleplayer {
BlockID block = map.blocks[posIndex];
if (block == Block.Lava || block == Block.StillLava) {
game.UpdateBlock(x, y, z, Block.Stone);
- } else if (BlockInfo.Collide[block] == CollideType.Gas && block != Block.Rope) {
+ } else if (BlockInfo.ExtendedCollide[block] == CollideType.Gas) {
// Sponge check
for (int yy = (y < 2 ? 0 : y - 2); yy <= (y > maxWaterY ? maxY : y + 2); yy++)
for (int zz = (z < 2 ? 0 : z - 2); zz <= (z > maxWaterZ ? maxZ : z + 2); zz++)
diff --git a/src/Client/Block.c b/src/Client/Block.c
index 1bc1b0d8b..8d4389342 100644
--- a/src/Client/Block.c
+++ b/src/Client/Block.c
@@ -616,6 +616,8 @@ UInt8 DefaultSet_Collide(BlockID b) {
}
UInt8 DefaultSet_MapOldCollide(BlockID b, UInt8 collide) {
+ if (b == BLOCK_ROPE && collide == COLLIDE_GAS)
+ return COLLIDE_CLIMB_ROPE;
if (b == BLOCK_ICE && collide == COLLIDE_SOLID)
return COLLIDE_ICE;
if ((b == BLOCK_WATER || b == BLOCK_STILL_WATER) && collide == COLLIDE_LIQUID)
diff --git a/src/Client/Block.h b/src/Client/Block.h
index 5f7686636..6db0c8821 100644
--- a/src/Client/Block.h
+++ b/src/Client/Block.h
@@ -39,6 +39,7 @@
#define COLLIDE_SLIPPERY_ICE 4 /* Block is solid and fully slidable on. */
#define COLLIDE_LIQUID_WATER 5 /* Water style 'swimming'/'bobbing' interaction when player collides. */
#define COLLIDE_LIQUID_LAVA 6 /* Lava style 'swimming'/'bobbing' interaction when player collides. */
+#define COLLIDE_CLIMB_ROPE 7 /* Rope/Ladder style climbing interaction when player collides */
UInt8 Block_NamesBuffer[String_BufferSize(STRING_SIZE) * BLOCK_COUNT];
#define Block_NamePtr(i) &Block_NamesBuffer[String_BufferSize(STRING_SIZE) * i]
diff --git a/src/Client/Entity.c b/src/Client/Entity.c
index e4209bf9f..d0cbc8740 100644
--- a/src/Client/Entity.c
+++ b/src/Client/Entity.c
@@ -190,7 +190,7 @@ bool Entity_TouchesAny(AABB* bounds, TouchesAny_Condition condition) {
return false;
}
-bool Entity_IsRope(BlockID b) { return b == BLOCK_ROPE; }
+bool Entity_IsRope(BlockID b) { return Block_ExtendedCollide[b] == COLLIDE_CLIMB_ROPE; }
bool Entity_TouchesAnyRope(Entity* entity) {
AABB bounds; Entity_GetBounds(entity, &bounds);
bounds.Max.Y += 0.5f / 16.0f;