find_compactbiomes.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "finders.h"
  2. #include "generator.h"
  3. struct compactinfo_t
  4. {
  5. int64_t seedStart, seedEnd;
  6. unsigned int range;
  7. BiomeFilter filter;
  8. int withHut, withMonument;
  9. int minscale;
  10. };
  11. #ifdef USE_PTHREAD
  12. static void *searchCompactBiomesThread(void *data)
  13. #else
  14. static DWORD WINAPI searchCompactBiomesThread(LPVOID data)
  15. #endif
  16. {
  17. struct compactinfo_t info = *(struct compactinfo_t *)data;
  18. int ax = -info.range, az = -info.range;
  19. int w = 2*info.range, h = 2*info.range;
  20. int64_t s;
  21. int mcversion = MC_1_14;
  22. LayerStack g;
  23. setupGenerator(&g, mcversion);
  24. int *cache = allocCache(&g.layers[L_VORONOI_ZOOM_1], w, h);
  25. for (s = info.seedStart; s != info.seedEnd; s++)
  26. {
  27. if (!hasAllTemps(&g, s, 0, 0))
  28. continue;
  29. if (checkForBiomes(&g, L_VORONOI_ZOOM_1, cache, s, ax, az, w, h, info.filter, 1) > 0)
  30. {
  31. int x, z;
  32. if (info.withHut)
  33. {
  34. int r = info.range / SWAMP_HUT_CONFIG.regionSize;
  35. for (z = -r; z < r; z++)
  36. {
  37. for (x = -r; x < r; x++)
  38. {
  39. Pos p;
  40. p = getStructurePos(SWAMP_HUT_CONFIG, s, x, z, NULL);
  41. if (isViableStructurePos(Swamp_Hut, mcversion, &g, s, p.x, p.z))
  42. goto L_hut_found;
  43. }
  44. }
  45. continue;
  46. L_hut_found:;
  47. }
  48. if (info.withMonument)
  49. {
  50. int r = info.range / MONUMENT_CONFIG.regionSize;
  51. for (z = -r; z < r; z++)
  52. {
  53. for (x = -r; x < r; x++)
  54. {
  55. Pos p;
  56. p = getStructurePos(MONUMENT_CONFIG, s, x, z, NULL);
  57. if (isViableStructurePos(Monument, mcversion, &g, s, p.x, p.z))
  58. goto L_monument_found;
  59. }
  60. }
  61. continue;
  62. L_monument_found:;
  63. }
  64. printf("%" PRId64 "\n", s);
  65. fflush(stdout);
  66. }
  67. }
  68. free(cache);
  69. #ifdef USE_PTHREAD
  70. pthread_exit(NULL);
  71. #endif
  72. return 0;
  73. }
  74. int main(int argc, char *argv[])
  75. {
  76. initBiomes();
  77. int64_t seedStart, seedEnd;
  78. unsigned int threads, t, range;
  79. BiomeFilter filter;
  80. int withHut, withMonument;
  81. int minscale;
  82. // arguments
  83. if (argc <= 1)
  84. {
  85. printf( "find_compactbiomes [seed_start] [seed_end] [threads] [range]\n"
  86. "\n"
  87. " seed_start starting seed for search [long, default=0]\n"
  88. " end_start end seed for search [long, default=-1]\n"
  89. " threads number of threads to use [uint, default=1]\n"
  90. " range search range (in blocks) [uint, default=1024]\n");
  91. exit(1);
  92. }
  93. if (argc <= 1 || sscanf(argv[1], "%" PRId64, &seedStart) != 1) seedStart = 0;
  94. if (argc <= 2 || sscanf(argv[2], "%" PRId64, &seedEnd) != 1) seedEnd = -1;
  95. if (argc <= 3 || sscanf(argv[3], "%u", &threads) != 1) threads = 1;
  96. if (argc <= 4 || sscanf(argv[4], "%u", &range) != 1) range = 1024;
  97. // TODO: set up a customisable biome filter
  98. filter = setupBiomeFilter(BIOMES_L13_OCEAN_MIX_4,
  99. sizeof(BIOMES_L13_OCEAN_MIX_4)/sizeof(int));
  100. minscale = 1; // terminate search at this layer scale
  101. // TODO: simple structure filter
  102. withHut = 0;
  103. withMonument = 0;
  104. printf("Starting search through seeds %" PRId64 " to %" PRId64", using %u threads.\n"
  105. "Search radius = %u.\n", seedStart, seedEnd, threads, range);
  106. thread_id_t threadID[threads];
  107. struct compactinfo_t info[threads];
  108. // store thread information
  109. uint64_t seedCnt = ((uint64_t)seedEnd - (uint64_t)seedStart) / threads;
  110. for (t = 0; t < threads; t++)
  111. {
  112. info[t].seedStart = (int64_t)(seedStart + seedCnt * t);
  113. info[t].seedEnd = (int64_t)(seedStart + seedCnt * (t+1));
  114. info[t].range = range;
  115. info[t].filter = filter;
  116. info[t].withHut = withHut;
  117. info[t].withMonument = withMonument;
  118. info[t].minscale = minscale;
  119. }
  120. info[threads-1].seedEnd = seedEnd;
  121. // start threads
  122. #ifdef USE_PTHREAD
  123. for (t = 0; t < threads; t++)
  124. {
  125. pthread_create(&threadID[t], NULL, searchCompactBiomesThread, (void*)&info[t]);
  126. }
  127. for (t = 0; t < threads; t++)
  128. {
  129. pthread_join(threadID[t], NULL);
  130. }
  131. #else
  132. for (t = 0; t < threads; t++)
  133. {
  134. threadID[t] = CreateThread(NULL, 0, searchCompactBiomesThread, (LPVOID)&info[t], 0, NULL);
  135. }
  136. WaitForMultipleObjects(threads, threadID, TRUE, INFINITE);
  137. #endif
  138. return 0;
  139. }