spawn_validator_test.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #include <gtest/gtest.h>
  2. #include "render/ground/spawn_validator.h"
  3. using namespace Render::Ground;
  4. using namespace Game::Map;
  5. class SpawnValidatorTest : public ::testing::Test {
  6. protected:
  7. void SetUp() override {
  8. // Create a simple 10x10 terrain for testing
  9. width = 10;
  10. height = 10;
  11. tile_size = 1.0F;
  12. // Initialize height data (flat terrain)
  13. height_data.resize(static_cast<size_t>(width * height), 0.0F);
  14. // Initialize terrain types (all flat by default)
  15. terrain_types.resize(static_cast<size_t>(width * height),
  16. TerrainType::Flat);
  17. }
  18. void build_cache() {
  19. terrain_cache.build_from_height_map(height_data, terrain_types, width,
  20. height, tile_size);
  21. }
  22. int width = 0;
  23. int height = 0;
  24. float tile_size = 1.0F;
  25. std::vector<float> height_data;
  26. std::vector<TerrainType> terrain_types;
  27. SpawnTerrainCache terrain_cache;
  28. };
  29. TEST_F(SpawnValidatorTest, TerrainCacheBuildFromHeightMap) {
  30. build_cache();
  31. EXPECT_EQ(terrain_cache.width, width);
  32. EXPECT_EQ(terrain_cache.height, height);
  33. EXPECT_EQ(terrain_cache.tile_size, tile_size);
  34. EXPECT_FALSE(terrain_cache.normals.empty());
  35. EXPECT_FALSE(terrain_cache.heights.empty());
  36. }
  37. TEST_F(SpawnValidatorTest, TerrainCacheSampleHeightFlat) {
  38. build_cache();
  39. // Flat terrain should return 0 everywhere
  40. EXPECT_FLOAT_EQ(terrain_cache.sample_height_at(5.0F, 5.0F), 0.0F);
  41. EXPECT_FLOAT_EQ(terrain_cache.sample_height_at(0.0F, 0.0F), 0.0F);
  42. EXPECT_FLOAT_EQ(terrain_cache.sample_height_at(9.0F, 9.0F), 0.0F);
  43. }
  44. TEST_F(SpawnValidatorTest, TerrainCacheGetSlopeFlat) {
  45. build_cache();
  46. // Flat terrain should have zero slope
  47. float slope = terrain_cache.get_slope_at(5, 5);
  48. EXPECT_LT(slope, 0.01F);
  49. }
  50. TEST_F(SpawnValidatorTest, TerrainCacheGetTerrainType) {
  51. // Set some specific terrain types
  52. terrain_types[static_cast<size_t>(5 * width + 5)] = TerrainType::Mountain;
  53. terrain_types[static_cast<size_t>(3 * width + 3)] = TerrainType::River;
  54. build_cache();
  55. EXPECT_EQ(terrain_cache.get_terrain_type_at(5, 5), TerrainType::Mountain);
  56. EXPECT_EQ(terrain_cache.get_terrain_type_at(3, 3), TerrainType::River);
  57. EXPECT_EQ(terrain_cache.get_terrain_type_at(0, 0), TerrainType::Flat);
  58. }
  59. TEST_F(SpawnValidatorTest, SpawnValidatorAllowsFlatTerrain) {
  60. build_cache();
  61. SpawnValidationConfig config = make_plant_spawn_config();
  62. config.grid_width = width;
  63. config.grid_height = height;
  64. config.tile_size = tile_size;
  65. config.edge_padding = 0.0F; // No edge padding for this test
  66. SpawnValidator validator(terrain_cache, config);
  67. // Center of map should be valid for spawning on flat terrain
  68. EXPECT_TRUE(validator.can_spawn_at_grid(5.0F, 5.0F));
  69. }
  70. TEST_F(SpawnValidatorTest, SpawnValidatorBlocksMountainTerrain) {
  71. // Make center a mountain
  72. terrain_types[static_cast<size_t>(5 * width + 5)] = TerrainType::Mountain;
  73. build_cache();
  74. SpawnValidationConfig config = make_plant_spawn_config();
  75. config.grid_width = width;
  76. config.grid_height = height;
  77. config.tile_size = tile_size;
  78. config.edge_padding = 0.0F;
  79. config.allow_mountain = false;
  80. SpawnValidator validator(terrain_cache, config);
  81. // Mountain should not be valid for spawning
  82. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 5.0F));
  83. }
  84. TEST_F(SpawnValidatorTest, SpawnValidatorBlocksRiverTerrain) {
  85. // Make center a river
  86. terrain_types[static_cast<size_t>(5 * width + 5)] = TerrainType::River;
  87. build_cache();
  88. SpawnValidationConfig config = make_plant_spawn_config();
  89. config.grid_width = width;
  90. config.grid_height = height;
  91. config.tile_size = tile_size;
  92. config.edge_padding = 0.0F;
  93. config.allow_river = false;
  94. SpawnValidator validator(terrain_cache, config);
  95. // River should not be valid for spawning
  96. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 5.0F));
  97. }
  98. TEST_F(SpawnValidatorTest, SpawnValidatorRiverMarginCheck) {
  99. // Make a cell a river
  100. terrain_types[static_cast<size_t>(5 * width + 5)] = TerrainType::River;
  101. build_cache();
  102. SpawnValidationConfig config = make_plant_spawn_config();
  103. config.grid_width = width;
  104. config.grid_height = height;
  105. config.tile_size = tile_size;
  106. config.edge_padding = 0.0F;
  107. config.river_margin = 1;
  108. config.check_river_margin = true;
  109. SpawnValidator validator(terrain_cache, config);
  110. // Adjacent cell should also be blocked due to river margin
  111. EXPECT_FALSE(validator.can_spawn_at_grid(4.0F, 5.0F));
  112. EXPECT_FALSE(validator.can_spawn_at_grid(6.0F, 5.0F));
  113. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 4.0F));
  114. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 6.0F));
  115. // Cell far from river should be valid
  116. EXPECT_TRUE(validator.can_spawn_at_grid(0.0F, 0.0F));
  117. }
  118. TEST_F(SpawnValidatorTest, SpawnValidatorEdgePaddingCheck) {
  119. build_cache();
  120. SpawnValidationConfig config = make_plant_spawn_config();
  121. config.grid_width = width;
  122. config.grid_height = height;
  123. config.tile_size = tile_size;
  124. config.edge_padding = 0.2F; // 20% edge padding
  125. SpawnValidator validator(terrain_cache, config);
  126. // Edge positions should be blocked
  127. EXPECT_FALSE(validator.can_spawn_at_grid(0.0F, 5.0F));
  128. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 0.0F));
  129. EXPECT_FALSE(validator.can_spawn_at_grid(9.0F, 5.0F));
  130. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 9.0F));
  131. // Center should be valid
  132. EXPECT_TRUE(validator.can_spawn_at_grid(5.0F, 5.0F));
  133. }
  134. TEST_F(SpawnValidatorTest, GridToWorldConversion) {
  135. build_cache();
  136. SpawnValidationConfig config = make_plant_spawn_config();
  137. config.grid_width = width;
  138. config.grid_height = height;
  139. config.tile_size = 2.0F; // 2 units per tile
  140. config.edge_padding = 0.0F;
  141. SpawnValidator validator(terrain_cache, config);
  142. float world_x = 0.0F;
  143. float world_z = 0.0F;
  144. // Center of 10x10 grid should be at (0, 0) in world coordinates
  145. // half_width = 10 * 0.5 - 0.5 = 4.5
  146. // world_x = (5.0 - 4.5) * 2.0 = 1.0
  147. validator.grid_to_world(5.0F, 5.0F, world_x, world_z);
  148. EXPECT_NEAR(world_x, 1.0F, 0.01F);
  149. EXPECT_NEAR(world_z, 1.0F, 0.01F);
  150. }
  151. TEST_F(SpawnValidatorTest, MakePlantSpawnConfigDefaults) {
  152. SpawnValidationConfig config = make_plant_spawn_config();
  153. EXPECT_TRUE(config.allow_flat);
  154. EXPECT_FALSE(config.allow_hill);
  155. EXPECT_FALSE(config.allow_mountain);
  156. EXPECT_FALSE(config.allow_river);
  157. EXPECT_TRUE(config.check_buildings);
  158. EXPECT_TRUE(config.check_roads);
  159. EXPECT_TRUE(config.check_slope);
  160. EXPECT_TRUE(config.check_river_margin);
  161. }
  162. TEST_F(SpawnValidatorTest, MakeStoneSpawnConfigDefaults) {
  163. SpawnValidationConfig config = make_stone_spawn_config();
  164. EXPECT_TRUE(config.allow_flat);
  165. EXPECT_FALSE(config.allow_hill);
  166. EXPECT_FALSE(config.allow_mountain);
  167. EXPECT_FALSE(config.allow_river);
  168. EXPECT_TRUE(config.check_buildings);
  169. EXPECT_FALSE(config.check_roads);
  170. }
  171. TEST_F(SpawnValidatorTest, MakeFirecampSpawnConfigDefaults) {
  172. SpawnValidationConfig config = make_firecamp_spawn_config();
  173. EXPECT_TRUE(config.allow_flat);
  174. EXPECT_TRUE(config.allow_hill);
  175. EXPECT_FALSE(config.allow_mountain);
  176. EXPECT_FALSE(config.allow_river);
  177. EXPECT_TRUE(config.check_buildings);
  178. EXPECT_TRUE(config.check_roads);
  179. }
  180. TEST_F(SpawnValidatorTest, MakeGrassSpawnConfigDefaults) {
  181. SpawnValidationConfig config = make_grass_spawn_config();
  182. EXPECT_TRUE(config.allow_flat);
  183. EXPECT_FALSE(config.allow_hill);
  184. EXPECT_FALSE(config.allow_mountain);
  185. EXPECT_FALSE(config.allow_river);
  186. EXPECT_TRUE(config.check_buildings);
  187. EXPECT_TRUE(config.check_roads);
  188. }
  189. TEST_F(SpawnValidatorTest, PlantSpawnConfigBlocksHills) {
  190. // Make center a hill
  191. terrain_types[static_cast<size_t>(5 * width + 5)] = TerrainType::Hill;
  192. build_cache();
  193. SpawnValidationConfig config = make_plant_spawn_config();
  194. config.grid_width = width;
  195. config.grid_height = height;
  196. config.tile_size = tile_size;
  197. config.edge_padding = 0.0F;
  198. SpawnValidator validator(terrain_cache, config);
  199. // Hill should not be valid for plant spawning
  200. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 5.0F));
  201. // But flat terrain should be valid
  202. EXPECT_TRUE(validator.can_spawn_at_grid(0.0F, 0.0F));
  203. }
  204. TEST_F(SpawnValidatorTest, TreeSpawnConfigRespectsRiverMargin) {
  205. // Make center a river
  206. terrain_types[static_cast<size_t>(5 * width + 5)] = TerrainType::River;
  207. build_cache();
  208. SpawnValidationConfig config = make_tree_spawn_config();
  209. config.grid_width = width;
  210. config.grid_height = height;
  211. config.tile_size = tile_size;
  212. config.edge_padding = 0.0F;
  213. SpawnValidator validator(terrain_cache, config);
  214. // River should not be valid for tree spawning
  215. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 5.0F));
  216. // Adjacent cells should also be blocked due to river margin
  217. EXPECT_FALSE(validator.can_spawn_at_grid(4.0F, 5.0F));
  218. EXPECT_FALSE(validator.can_spawn_at_grid(6.0F, 5.0F));
  219. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 4.0F));
  220. EXPECT_FALSE(validator.can_spawn_at_grid(5.0F, 6.0F));
  221. // Cell far from river should be valid
  222. EXPECT_TRUE(validator.can_spawn_at_grid(0.0F, 0.0F));
  223. }