terrain_service.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include "terrain_service.h"
  2. #include <cmath>
  3. #include "../systems/building_collision_registry.h"
  4. #include "map_definition.h"
  5. #include <QDebug>
  6. namespace Game::Map {
  7. TerrainService &TerrainService::instance() {
  8. static TerrainService s_instance;
  9. return s_instance;
  10. }
  11. void TerrainService::initialize(const MapDefinition &mapDef) {
  12. m_heightMap = std::make_unique<TerrainHeightMap>(
  13. mapDef.grid.width, mapDef.grid.height, mapDef.grid.tileSize);
  14. m_heightMap->buildFromFeatures(mapDef.terrain);
  15. m_biomeSettings = mapDef.biome;
  16. m_heightMap->applyBiomeVariation(m_biomeSettings);
  17. qDebug() << "TerrainService initialized with" << mapDef.terrain.size()
  18. << "terrain features";
  19. }
  20. float TerrainService::getTerrainHeight(float worldX, float worldZ) const {
  21. if (!m_heightMap)
  22. return 0.0f;
  23. return m_heightMap->getHeightAt(worldX, worldZ);
  24. }
  25. float TerrainService::getTerrainHeightGrid(int gridX, int gridZ) const {
  26. if (!m_heightMap)
  27. return 0.0f;
  28. return m_heightMap->getHeightAtGrid(gridX, gridZ);
  29. }
  30. bool TerrainService::isWalkable(int gridX, int gridZ) const {
  31. if (!m_heightMap)
  32. return true;
  33. return m_heightMap->isWalkable(gridX, gridZ);
  34. }
  35. bool TerrainService::isForbidden(int gridX, int gridZ) const {
  36. if (!m_heightMap)
  37. return false;
  38. if (!m_heightMap->isWalkable(gridX, gridZ))
  39. return true;
  40. float halfW = m_heightMap->getWidth() * 0.5f - 0.5f;
  41. float halfH = m_heightMap->getHeight() * 0.5f - 0.5f;
  42. const float tile = m_heightMap->getTileSize();
  43. float worldX = (static_cast<float>(gridX) - halfW) * tile;
  44. float worldZ = (static_cast<float>(gridZ) - halfH) * tile;
  45. auto &registry = Game::Systems::BuildingCollisionRegistry::instance();
  46. if (registry.isPointInBuilding(worldX, worldZ))
  47. return true;
  48. return false;
  49. }
  50. bool TerrainService::isForbiddenWorld(float worldX, float worldZ) const {
  51. if (!m_heightMap)
  52. return false;
  53. const float gridHalfWidth = m_heightMap->getWidth() * 0.5f - 0.5f;
  54. const float gridHalfHeight = m_heightMap->getHeight() * 0.5f - 0.5f;
  55. float gx = worldX / m_heightMap->getTileSize() + gridHalfWidth;
  56. float gz = worldZ / m_heightMap->getTileSize() + gridHalfHeight;
  57. int ix = static_cast<int>(std::round(gx));
  58. int iz = static_cast<int>(std::round(gz));
  59. return isForbidden(ix, iz);
  60. }
  61. bool TerrainService::isHillEntrance(int gridX, int gridZ) const {
  62. if (!m_heightMap)
  63. return false;
  64. return m_heightMap->isHillEntrance(gridX, gridZ);
  65. }
  66. TerrainType TerrainService::getTerrainType(int gridX, int gridZ) const {
  67. if (!m_heightMap)
  68. return TerrainType::Flat;
  69. return m_heightMap->getTerrainType(gridX, gridZ);
  70. }
  71. } // namespace Game::Map