Skip to content

Commit 0e7423d

Browse files
authored
Implemented climbing up/down
Implemented climbing up/down
2 parents e6c66fb + 616591e commit 0e7423d

File tree

2 files changed

+136
-17
lines changed

2 files changed

+136
-17
lines changed

MinecraftClient/Mapping/MaterialExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,27 @@ public static bool IsLiquid(this Material m)
766766
}
767767
}
768768

769+
/// <summary>
770+
/// Check if the player can climb up this block
771+
/// </summary>
772+
/// <param name="m">Material to test</param>
773+
/// <returns>True if the material can be climbed on</returns>
774+
public static bool CanBeClimbedOn(this Material m)
775+
{
776+
switch (m)
777+
{
778+
case Material.Ladder:
779+
case Material.Vine:
780+
case Material.TwistingVines:
781+
case Material.TwistingVinesPlant:
782+
case Material.WeepingVines:
783+
case Material.WeepingVinesPlant:
784+
return true;
785+
default:
786+
return false;
787+
}
788+
}
789+
769790
/// <summary>
770791
/// Check if the provided material is a bed
771792
/// </summary>

MinecraftClient/Mapping/Movement.cs

Lines changed: 115 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,8 @@ public bool ContainsLocation(Location loc)
463463

464464
/* ========= LOCATION PROPERTIES ========= */
465465

466+
// TODO: Find a way to remove this Hack for Vines here.
467+
466468
/// <summary>
467469
/// Check if the specified location is on the ground
468470
/// </summary>
@@ -477,29 +479,108 @@ public static bool IsOnGround(World world, Location location)
477479

478480
Location down = Move(location, Direction.Down);
479481

480-
bool result = world.GetBlock(down).Type.IsSolid();
482+
Material currentMaterial = world.GetBlock(down).Type;
483+
484+
bool result = currentMaterial.IsSolid()
485+
|| currentMaterial == Material.TwistingVines || currentMaterial == Material.TwistingVinesPlant
486+
|| currentMaterial == Material.WeepingVines || currentMaterial == Material.WeepingVinesPlant
487+
|| currentMaterial == Material.Vine;
481488

482489
bool northCheck = 1 + Math.Floor(down.Z) - down.Z > 0.7;
483490
bool eastCheck = down.X - Math.Floor(down.X) > 0.7;
484491
bool southCheck = down.Z - Math.Floor(down.Z) > 0.7;
485492
bool westCheck = 1 + Math.Floor(down.X) - down.X > 0.7;
486493

487494
if (!result && northCheck)
488-
result |= world.GetBlock(Move(down, Direction.North)).Type.IsSolid();
495+
{
496+
Location locationDownNorth = Move(down, Direction.North);
497+
result |= world.GetBlock(locationDownNorth).Type.IsSolid()
498+
|| world.GetBlock(locationDownNorth).Type == Material.TwistingVines
499+
|| world.GetBlock(locationDownNorth).Type == Material.TwistingVinesPlant
500+
|| world.GetBlock(locationDownNorth).Type == Material.WeepingVines
501+
|| world.GetBlock(locationDownNorth).Type == Material.WeepingVinesPlant
502+
|| world.GetBlock(locationDownNorth).Type == Material.Vine;
503+
}
504+
489505
if (!result && northCheck && eastCheck)
490-
result |= world.GetBlock(Move(down, Direction.NorthEast)).Type.IsSolid();
506+
{
507+
Location locationDownNorthEast = Move(down, Direction.NorthEast);
508+
result |= world.GetBlock(locationDownNorthEast).Type.IsSolid()
509+
|| world.GetBlock(locationDownNorthEast).Type == Material.TwistingVines
510+
|| world.GetBlock(locationDownNorthEast).Type == Material.TwistingVinesPlant
511+
|| world.GetBlock(locationDownNorthEast).Type == Material.WeepingVines
512+
|| world.GetBlock(locationDownNorthEast).Type == Material.WeepingVinesPlant
513+
|| world.GetBlock(locationDownNorthEast).Type == Material.Vine;
514+
}
515+
491516
if (!result && eastCheck)
492-
result |= world.GetBlock(Move(down, Direction.East)).Type.IsSolid();
517+
{
518+
Location locationDownEast = Move(down, Direction.East);
519+
result |= world.GetBlock(locationDownEast).Type.IsSolid()
520+
|| world.GetBlock(locationDownEast).Type == Material.TwistingVines
521+
|| world.GetBlock(locationDownEast).Type == Material.TwistingVinesPlant
522+
|| world.GetBlock(locationDownEast).Type == Material.WeepingVines
523+
|| world.GetBlock(locationDownEast).Type == Material.WeepingVinesPlant
524+
|| world.GetBlock(locationDownEast).Type == Material.Vine;
525+
}
526+
493527
if (!result && eastCheck && southCheck)
494-
result |= world.GetBlock(Move(down, Direction.SouthEast)).Type.IsSolid();
528+
{
529+
Location locationDownSouthEast = Move(down, Direction.SouthEast);
530+
result |= world.GetBlock(locationDownSouthEast).Type.IsSolid()
531+
|| world.GetBlock(locationDownSouthEast).Type == Material.TwistingVines
532+
|| world.GetBlock(locationDownSouthEast).Type == Material.TwistingVinesPlant
533+
|| world.GetBlock(locationDownSouthEast).Type == Material.WeepingVines
534+
|| world.GetBlock(locationDownSouthEast).Type == Material.WeepingVinesPlant
535+
|| world.GetBlock(locationDownSouthEast).Type == Material.Vine;
536+
}
537+
495538
if (!result && southCheck)
496-
result |= world.GetBlock(Move(down, Direction.South)).Type.IsSolid();
539+
{
540+
Location locationDownSouth = Move(down, Direction.South);
541+
result |= world.GetBlock(locationDownSouth).Type.IsSolid()
542+
|| world.GetBlock(locationDownSouth).Type == Material.TwistingVines
543+
|| world.GetBlock(locationDownSouth).Type == Material.TwistingVinesPlant
544+
|| world.GetBlock(locationDownSouth).Type == Material.WeepingVines
545+
|| world.GetBlock(locationDownSouth).Type == Material.WeepingVinesPlant
546+
|| world.GetBlock(locationDownSouth).Type == Material.Vine;
547+
}
548+
497549
if (!result && southCheck && westCheck)
498-
result |= world.GetBlock(Move(down, Direction.SouthWest)).Type.IsSolid();
550+
{
551+
Location locationDownSouthWest = Move(down, Direction.SouthWest);
552+
result |= world.GetBlock(locationDownSouthWest).Type.IsSolid()
553+
|| world.GetBlock(locationDownSouthWest).Type == Material.TwistingVines
554+
|| world.GetBlock(locationDownSouthWest).Type == Material.TwistingVinesPlant
555+
|| world.GetBlock(locationDownSouthWest).Type == Material.WeepingVines
556+
|| world.GetBlock(locationDownSouthWest).Type == Material.WeepingVinesPlant
557+
|| world.GetBlock(locationDownSouthWest).Type == Material.Vine;
558+
}
559+
560+
499561
if (!result && westCheck)
500-
result |= world.GetBlock(Move(down, Direction.West)).Type.IsSolid();
562+
{
563+
Location locationDownWest = Move(down, Direction.West);
564+
result |= world.GetBlock(locationDownWest).Type.IsSolid()
565+
|| world.GetBlock(locationDownWest).Type == Material.TwistingVines
566+
|| world.GetBlock(locationDownWest).Type == Material.TwistingVinesPlant
567+
|| world.GetBlock(locationDownWest).Type == Material.WeepingVines
568+
|| world.GetBlock(locationDownWest).Type == Material.WeepingVinesPlant
569+
|| world.GetBlock(locationDownWest).Type == Material.Vine;
570+
}
571+
572+
501573
if (!result && westCheck && northCheck)
502-
result |= world.GetBlock(Move(down, Direction.NorthWest)).Type.IsSolid();
574+
{
575+
Location locationDownNorthWest = Move(down, Direction.NorthWest);
576+
result |= world.GetBlock(locationDownNorthWest).Type.IsSolid()
577+
|| world.GetBlock(locationDownNorthWest).Type == Material.TwistingVines
578+
|| world.GetBlock(locationDownNorthWest).Type == Material.TwistingVinesPlant
579+
|| world.GetBlock(locationDownNorthWest).Type == Material.WeepingVines
580+
|| world.GetBlock(locationDownNorthWest).Type == Material.WeepingVinesPlant
581+
|| world.GetBlock(locationDownNorthWest).Type == Material.Vine;
582+
583+
}
503584

504585
return result && (location.Y <= Math.Truncate(location.Y) + 0.0001);
505586
}
@@ -515,6 +596,17 @@ public static bool IsSwimming(World world, Location location)
515596
return world.GetBlock(location).Type.IsLiquid();
516597
}
517598

599+
/// <summary>
600+
/// Check if the specified location can be climbed on
601+
/// </summary>
602+
/// <param name="world">World for performing check</param>
603+
/// <param name="location">Location to check</param>
604+
/// <returns>True if the specified location can be climbed on</returns>
605+
public static bool IsClimbing(World world, Location location)
606+
{
607+
return world.GetBlock(location).Type.CanBeClimbedOn();
608+
}
609+
518610
/// <summary>
519611
/// Check if the specified location is safe
520612
/// </summary>
@@ -530,9 +622,9 @@ public static bool IsSafe(World world, Location location)
530622
&& !world.GetBlock(Move(location, Direction.Down)).Type.CanHarmPlayers()
531623

532624
//No fall from a too high place
533-
&& (world.GetBlock(Move(location, Direction.Down)).Type.IsSolid()
534-
|| world.GetBlock(Move(location, Direction.Down, 2)).Type.IsSolid()
535-
|| world.GetBlock(Move(location, Direction.Down, 3)).Type.IsSolid())
625+
&& (world.GetBlock(Move(location, Direction.Down)).Type.IsSolid() || IsClimbing(world, Move(location, Direction.Down))
626+
|| world.GetBlock(Move(location, Direction.Down, 2)).Type.IsSolid() || IsClimbing(world, Move(location, Direction.Down, 2))
627+
|| world.GetBlock(Move(location, Direction.Down, 3)).Type.IsSolid() || IsClimbing(world, Move(location, Direction.Down, 3)))
536628

537629
//Not an underwater location
538630
&& !(world.GetBlock(Move(location, Direction.Up)).Type.IsLiquid());
@@ -553,10 +645,16 @@ public static bool CanMove(World world, Location location, Direction direction)
553645
{
554646
// Move vertical
555647
case Direction.Down:
556-
return !IsOnGround(world, location);
648+
return IsClimbing(world, Move(location, Direction.Down)) || !IsOnGround(world, location);
557649
case Direction.Up:
558-
return (IsOnGround(world, location) || IsSwimming(world, location))
559-
&& !world.GetBlock(Move(Move(location, Direction.Up), Direction.Up)).Type.IsSolid();
650+
bool nextTwoBlocks = !world.GetBlock(Move(Move(location, Direction.Up), Direction.Up)).Type.IsSolid();
651+
652+
// Check if the current block can be climbed on
653+
if (IsClimbing(world, location))
654+
// Check if next block after the next one can be climbed uppon
655+
return IsClimbing(world, Move(location, Direction.Up)) || nextTwoBlocks;
656+
657+
return (IsOnGround(world, location) || IsSwimming(world, location)) && nextTwoBlocks;
560658

561659
// Move horizontal
562660
case Direction.East:
@@ -588,8 +686,8 @@ public static bool CanMove(World world, Location location, Direction direction)
588686
/// <returns>True if a player is able to stand in this location</returns>
589687
public static bool PlayerFitsHere(World world, Location location)
590688
{
591-
return !world.GetBlock(location).Type.IsSolid()
592-
&& !world.GetBlock(Move(location, Direction.Up)).Type.IsSolid();
689+
return (IsClimbing(world, location) && IsClimbing(world, Move(location, Direction.Up)))
690+
|| !world.GetBlock(location).Type.IsSolid() && !world.GetBlock(Move(location, Direction.Up)).Type.IsSolid();
593691
}
594692

595693
/// <summary>

0 commit comments

Comments
 (0)