bool Map::isSightClear(const Position& fromPos, const Position& toPos, bool sameFloor /*= false*/) const
{
// Check if fromPos and toPos are the same
if (fromPos == toPos)
return true;
// Calculate distance between fromPos and toPos
int dx = std::abs(fromPos.x - toPos.x);
int dy = std::abs(fromPos.y - toPos.y);
int dz = std::abs(fromPos.z - toPos.z);
// Check for same floor or skip if they are next to each other
if (dz == 0 && (dx < 2 && dy < 2)) {
// Sight is clear or sameFloor is enabled
bool sightClear = checkSightLine(fromPos.x, fromPos.y, toPos.x, toPos.y, fromPos.z);
return sightClear || sameFloor || (fromPos.z == 0);
}
// Check if fromPos and toPos cross the ground floor
if ((fromPos.z < 8 && toPos.z > 7) || (fromPos.z > 7 && toPos.z < 8))
return false;
// Check if tiles above or below the target are clear
uint8_t startZ = std::min(fromPos.z, toPos.z);
uint8_t endZ = std::max(fromPos.z, toPos.z);
for (uint8_t z = startZ; z < endZ; ++z) {
if (!isTileClear(toPos.x, toPos.y, z, true))
return false;
}
// Check if we can throw to the tile above the target
return checkSightLine(fromPos.x, fromPos.y, toPos.x, toPos.y, fromPos.z);
}