Untitled

mail@pastecode.io avatar
unknown
diff
2 months ago
2.9 kB
3
Indexable
Never
diff --git a/src/map.cpp b/src/map.cpp
index 44091e9..e8943ea 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -507,62 +507,41 @@ bool Map::isTileClear(uint16_t x, uint16_t y, uint8_t z, bool blockFloor /*= fal
 	return !tile->hasProperty(CONST_PROP_BLOCKPROJECTILE);
 }
 
-namespace {
-
-bool checkSteepLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t z)
+bool Map::checkSightLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t z) const
 {
-	float dx = x1 - x0;
-	float slope = (dx == 0) ? 1 : (y1 - y0) / dx;
-	float yi = y0 + slope;
-
-	for (uint16_t x = x0 + 1; x < x1; ++x) {
-		//0.1 is necessary to avoid loss of precision during calculation
-		if (!g_game.map.isTileClear(std::floor(yi + 0.1), x, z)) {
-			return false;
-		}
-		yi += slope;
+	if (x0 == x1 && y0 == y1) {
+		return true;
 	}
 
-	return true;
-}
+	Position start(x0, y0, z);
+	Position destination(x1, y1, z);
 
-bool checkSlightLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t z)
-{
-	float dx = x1 - x0;
-	float slope = (dx == 0) ? 1 : (y1 - y0) / dx;
-	float yi = y0 + slope;
+	const int8_t mx = start.x < destination.x ? 1 : start.x == destination.x ? 0 : -1;
+	const int8_t my = start.y < destination.y ? 1 : start.y == destination.y ? 0 : -1;
 
-	for (uint16_t x = x0 + 1; x < x1; ++x) {
-		//0.1 is necessary to avoid loss of precision during calculation
-		if (!g_game.map.isTileClear(x, std::floor(yi + 0.1), z)) {
-			return false;
-		}
-		yi += slope;
-	}
+	int32_t A = Position::getOffsetY(destination, start);
+	int32_t B = Position::getOffsetX(start, destination);
+	int32_t C = -(A * destination.x + B * destination.y);
 
-	return true;
-}
-
-}
+	while (start.x != destination.x || start.y != destination.y) {
+		int32_t move_hor = std::abs(A * (start.x + mx) + B * (start.y) + C);
+		int32_t move_ver = std::abs(A * (start.x) + B * (start.y + my) + C);
+		int32_t move_cross = std::abs(A * (start.x + mx) + B * (start.y + my) + C);
 
-bool Map::checkSightLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t z) const
-{
-	if (x0 == x1 && y0 == y1) {
-		return true;
-	}
+		if (start.y != destination.y && (start.x == destination.x || move_hor > move_ver || move_hor > move_cross)) {
+			start.y += my;
+		}
 
-	if (std::abs(y1 - y0) > std::abs(x1 - x0)) {
-		if (y1 > y0) {
-			return checkSteepLine(y0, x0, y1, x1, z);
+		if (start.x != destination.x && (start.y == destination.y || move_ver > move_hor || move_ver > move_cross)) {
+			start.x += mx;
 		}
-		return checkSteepLine(y1, x1, y0, x0, z);
-	}
 
-	if (x0 > x1) {
-		return checkSlightLine(x1, y1, x0, y0, z);
+		if (!g_game.map.isTileClear(start.x, start.y, start.z)) {
+			return false;
+		}
 	}
 
-	return checkSlightLine(x0, y0, x1, y1, z);
+	return true;
 }
 
 bool Map::isSightClear(const Position& fromPos, const Position& toPos, bool sameFloor /*= false*/) const
Leave a Comment