ObstaclePlacer.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * ObstaclePlacer.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "ObstaclePlacer.h"
  12. #include "ObjectManager.h"
  13. #include "TreasurePlacer.h"
  14. #include "RockPlacer.h"
  15. #include "WaterRoutes.h"
  16. #include "WaterProxy.h"
  17. #include "RoadPlacer.h"
  18. #include "RiverPlacer.h"
  19. #include "../RmgMap.h"
  20. #include "../CMapGenerator.h"
  21. #include "../../CRandomGenerator.h"
  22. #include "../Functions.h"
  23. #include "../../mapping/CMapEditManager.h"
  24. #include "../../mapping/CMap.h"
  25. #include "../../mapping/ObstacleProxy.h"
  26. VCMI_LIB_NAMESPACE_BEGIN
  27. void ObstaclePlacer::process()
  28. {
  29. manager = zone.getModificator<ObjectManager>();
  30. if(!manager)
  31. return;
  32. collectPossibleObstacles(zone.getTerrainType());
  33. {
  34. Zone::Lock lock(zone.areaMutex);
  35. blockedArea = zone.area().getSubarea([this](const int3& t)
  36. {
  37. return map.shouldBeBlocked(t);
  38. });
  39. blockedArea.subtract(zone.areaUsed());
  40. zone.areaPossible().subtract(blockedArea);
  41. prohibitedArea = zone.freePaths() + zone.areaUsed() + manager->getVisitableArea();
  42. //Progressively block tiles, but make sure they don't seal any gap between blocks
  43. rmg::Area toBlock;
  44. do
  45. {
  46. toBlock.clear();
  47. for (const auto& tile : zone.areaPossible().getTiles())
  48. {
  49. rmg::Area neighbors;
  50. rmg::Area t;
  51. t.add(tile);
  52. for (const auto& n : t.getBorderOutside())
  53. {
  54. //Area outside the map is also impassable
  55. if (!map.isOnMap(n) || map.shouldBeBlocked(n))
  56. {
  57. neighbors.add(n);
  58. }
  59. }
  60. if (neighbors.empty())
  61. {
  62. continue;
  63. }
  64. //Will only be added if it doesn't connect two disjointed blocks
  65. if (neighbors.connected(true)) //Do not block diagonal pass
  66. {
  67. toBlock.add(tile);
  68. }
  69. }
  70. zone.areaPossible().subtract(toBlock);
  71. for (const auto& tile : toBlock.getTiles())
  72. {
  73. map.setOccupied(tile, ETileType::BLOCKED);
  74. }
  75. } while (!toBlock.empty());
  76. prohibitedArea.unite(zone.areaPossible());
  77. }
  78. auto objs = createObstacles(zone.getRand());
  79. mapProxy->insertObjects(objs);
  80. }
  81. void ObstaclePlacer::init()
  82. {
  83. DEPENDENCY(ObjectManager);
  84. DEPENDENCY(TreasurePlacer);
  85. DEPENDENCY(WaterRoutes);
  86. DEPENDENCY(WaterProxy);
  87. DEPENDENCY(RoadPlacer);
  88. DEPENDENCY_ALL(RockPlacer);
  89. }
  90. bool ObstaclePlacer::isInTheMap(const int3& tile)
  91. {
  92. return map.isOnMap(tile);
  93. }
  94. void ObstaclePlacer::placeObject(rmg::Object & object, std::set<CGObjectInstance*> &)
  95. {
  96. manager->placeObject(object, false, false);
  97. }
  98. std::pair<bool, bool> ObstaclePlacer::verifyCoverage(const int3 & t) const
  99. {
  100. return {map.shouldBeBlocked(t), zone.areaPossible().contains(t)};
  101. }
  102. void ObstaclePlacer::postProcess(const rmg::Object & object)
  103. {
  104. //river processing
  105. riverManager = zone.getModificator<RiverPlacer>();
  106. if(riverManager)
  107. {
  108. const auto objTypeName = object.instances().front()->object().typeName;
  109. if(objTypeName == "mountain")
  110. riverManager->riverSource().unite(object.getArea());
  111. else if(objTypeName == "lake")
  112. riverManager->riverSink().unite(object.getArea());
  113. }
  114. }
  115. bool ObstaclePlacer::isProhibited(const rmg::Area & objArea) const
  116. {
  117. if(prohibitedArea.overlap(objArea))
  118. return true;
  119. if(!zone.area().contains(objArea))
  120. return true;
  121. return false;
  122. }
  123. VCMI_LIB_NAMESPACE_END