/// <summary> /// Allows the Companion to "slide" along walls instead of getting stuck on them /// </summary> protected void HandleWallSliding() { if (lastFrameVelocity != Vector2.Zero && lastFrameMovement == Vector2.Zero && (me.xVelocity != 0 || me.yVelocity != 0)) { Rectangle wbBB = me.GetBoundingBox(); int ts = Game1.tileSize; bool xBlocked, yBlocked; xBlocked = yBlocked = false; if (me.xVelocity != 0) { int velocitySign = Math.Sign(me.xVelocity) * 15; int leftOrRight = ((me.xVelocity > 0 ? wbBB.Right : wbBB.Left) + velocitySign) / ts; bool[] xTiles = new bool[3]; xTiles[0] = aStar.IsWalkableTile(new Vector2(leftOrRight, wbBB.Top / ts)); xTiles[1] = aStar.IsWalkableTile(new Vector2(leftOrRight, wbBB.Center.Y / ts)); xTiles[2] = aStar.IsWalkableTile(new Vector2(leftOrRight, wbBB.Bottom / ts)); foreach (bool b in xTiles) { if (!b) { me.xVelocity *= -0.25f; xBlocked = true; break; } } } if (me.yVelocity != 0) { int velocitySign = Math.Sign(me.yVelocity) * 15; int topOrBottom = ((me.yVelocity < 0 ? wbBB.Bottom : wbBB.Top) - velocitySign) / ts; bool[] yTiles = new bool[3]; yTiles[0] = aStar.IsWalkableTile(new Vector2(wbBB.Left / ts, topOrBottom)); yTiles[1] = aStar.IsWalkableTile(new Vector2(wbBB.Center.X / ts, topOrBottom)); yTiles[2] = aStar.IsWalkableTile(new Vector2(wbBB.Right / ts, topOrBottom)); foreach (bool b in yTiles) { if (!b) { me.yVelocity *= -0.25f; yBlocked = true; break; } } } if (xBlocked) { me.yVelocity *= 2.5f; } else if (yBlocked) { me.xVelocity *= 2.5f; } } }