Advertisement
Guest User

Untitled

a guest
Aug 21st, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.36 KB | None | 0 0
  1. public static class InfestationCellFinder
  2. {
  3. private struct LocationCandidate
  4. {
  5. public IntVec3 cell;
  6.  
  7. public float score;
  8.  
  9. public LocationCandidate(IntVec3 cell, float score)
  10. {
  11. this.cell = cell;
  12. this.score = score;
  13. }
  14. }
  15.  
  16. private const float MinRequiredScore = 7.5f;
  17.  
  18. private const float MinMountainousnessScore = 0.17f;
  19.  
  20. private const int MountainousnessScoreRadialPatternIdx = 700;
  21.  
  22. private const int MountainousnessScoreRadialPatternSkip = 10;
  23.  
  24. private const float MountainousnessScorePerRock = 1f;
  25.  
  26. private const float MountainousnessScorePerThickRoof = 0.5f;
  27.  
  28. private const float MinCellTempToSpawnHive = -17f;
  29.  
  30. private const float MaxDistanceToColonyBuilding = 30f;
  31.  
  32. private static List<InfestationCellFinder.LocationCandidate> locationCandidates = new List<InfestationCellFinder.LocationCandidate>();
  33.  
  34. private static Dictionary<Region, float> regionsDistanceToUnroofed = new Dictionary<Region, float>();
  35.  
  36. private static ByteGrid closedAreaSize;
  37.  
  38. private static ByteGrid distToColonyBuilding;
  39.  
  40. private static HashSet<Region> tempUnroofedRegions = new HashSet<Region>();
  41.  
  42. private static List<IntVec3> tmpColonyBuildingsLocs = new List<IntVec3>();
  43.  
  44. private static List<KeyValuePair<IntVec3, float>> tmpDistanceResult = new List<KeyValuePair<IntVec3, float>>();
  45.  
  46. public static bool TryFindCell(out IntVec3 cell, Map map)
  47. {
  48. InfestationCellFinder.CalculateLocationCandidates(map);
  49. InfestationCellFinder.LocationCandidate locationCandidate;
  50. if (!InfestationCellFinder.locationCandidates.TryRandomElementByWeight((InfestationCellFinder.LocationCandidate x) => x.score, out locationCandidate))
  51. {
  52. cell = IntVec3.Invalid;
  53. return false;
  54. }
  55. cell = locationCandidate.cell;
  56. return true;
  57. }
  58.  
  59. private static float GetScoreAt(IntVec3 cell, Map map)
  60. {
  61. if ((float)InfestationCellFinder.distToColonyBuilding[cell] > 30f)
  62. {
  63. return 0f;
  64. }
  65. if (!cell.Standable(map))
  66. {
  67. return 0f;
  68. }
  69. if (cell.Fogged(map))
  70. {
  71. return 0f;
  72. }
  73. if (InfestationCellFinder.CellHasBlockingThings(cell, map))
  74. {
  75. return 0f;
  76. }
  77. if (!cell.Roofed(map) || !cell.GetRoof(map).isThickRoof)
  78. {
  79. return 0f;
  80. }
  81. Region region = cell.GetRegion(map, RegionType.Set_Passable);
  82. if (region == null)
  83. {
  84. return 0f;
  85. }
  86. if (InfestationCellFinder.closedAreaSize[cell] < 16)
  87. {
  88. return 0f;
  89. }
  90. float temperature = cell.GetTemperature(map);
  91. if (temperature < -17f)
  92. {
  93. return 0f;
  94. }
  95. float mountainousnessScoreAt = InfestationCellFinder.GetMountainousnessScoreAt(cell, map);
  96. if (mountainousnessScoreAt < 0.17f)
  97. {
  98. return 0f;
  99. }
  100. int num = InfestationCellFinder.StraightLineDistToUnroofed(cell, map);
  101. float num2;
  102. if (!InfestationCellFinder.regionsDistanceToUnroofed.TryGetValue(region, out num2))
  103. {
  104. num2 = (float)num * 1.15f;
  105. }
  106. else
  107. {
  108. num2 = Mathf.Min(num2, (float)num * 4f);
  109. }
  110. num2 = Mathf.Pow(num2, 1.55f);
  111. float num3 = Mathf.InverseLerp(0f, 12f, (float)num);
  112. float num4 = Mathf.Lerp(1f, 0.18f, map.glowGrid.GameGlowAt(cell));
  113. float num5 = 1f - Mathf.Clamp(InfestationCellFinder.DistToBlocker(cell, map) / 11f, 0f, 0.6f);
  114. float num6 = Mathf.InverseLerp(-17f, -7f, temperature);
  115. float num7 = num2 * num3 * num5 * mountainousnessScoreAt * num4 * num6;
  116. num7 = Mathf.Pow(num7, 1.2f);
  117. if (num7 < 7.5f)
  118. {
  119. return 0f;
  120. }
  121. return num7;
  122. }
  123.  
  124. public static void DebugDraw()
  125. {
  126. if (DebugViewSettings.drawInfestationChance)
  127. {
  128. Map visibleMap = Find.VisibleMap;
  129. CellRect cellRect = Find.CameraDriver.CurrentViewRect;
  130. cellRect.ClipInsideMap(visibleMap);
  131. cellRect = cellRect.ExpandedBy(1);
  132. InfestationCellFinder.CalculateTraversalDistancesToUnroofed(visibleMap);
  133. InfestationCellFinder.CalculateClosedAreaSizeGrid(visibleMap);
  134. InfestationCellFinder.CalculateDistanceToColonyBuildingGrid(visibleMap);
  135. float num = 0.001f;
  136. for (int i = 0; i < visibleMap.Size.z; i++)
  137. {
  138. for (int j = 0; j < visibleMap.Size.x; j++)
  139. {
  140. IntVec3 cell = new IntVec3(j, 0, i);
  141. float scoreAt = InfestationCellFinder.GetScoreAt(cell, visibleMap);
  142. if (scoreAt > num)
  143. {
  144. num = scoreAt;
  145. }
  146. }
  147. }
  148. for (int k = 0; k < visibleMap.Size.z; k++)
  149. {
  150. for (int l = 0; l < visibleMap.Size.x; l++)
  151. {
  152. IntVec3 intVec = new IntVec3(l, 0, k);
  153. if (cellRect.Contains(intVec))
  154. {
  155. float scoreAt2 = InfestationCellFinder.GetScoreAt(intVec, visibleMap);
  156. if (scoreAt2 > 0f)
  157. {
  158. float a = GenMath.LerpDouble(7.5f, num, 0f, 1f, scoreAt2);
  159. CellRenderer.RenderCell(intVec, SolidColorMaterials.SimpleSolidColorMaterial(new Color(0f, 0f, 1f, a), false));
  160. }
  161. }
  162. }
  163. }
  164. }
  165. }
  166.  
  167. private static void CalculateLocationCandidates(Map map)
  168. {
  169. InfestationCellFinder.locationCandidates.Clear();
  170. InfestationCellFinder.CalculateTraversalDistancesToUnroofed(map);
  171. InfestationCellFinder.CalculateClosedAreaSizeGrid(map);
  172. InfestationCellFinder.CalculateDistanceToColonyBuildingGrid(map);
  173. for (int i = 0; i < map.Size.z; i++)
  174. {
  175. for (int j = 0; j < map.Size.x; j++)
  176. {
  177. IntVec3 cell = new IntVec3(j, 0, i);
  178. float scoreAt = InfestationCellFinder.GetScoreAt(cell, map);
  179. if (scoreAt > 0f)
  180. {
  181. InfestationCellFinder.locationCandidates.Add(new InfestationCellFinder.LocationCandidate(cell, scoreAt));
  182. }
  183. }
  184. }
  185. }
  186.  
  187. private static bool CellHasBlockingThings(IntVec3 cell, Map map)
  188. {
  189. List<Thing> thingList = cell.GetThingList(map);
  190. for (int i = 0; i < thingList.Count; i++)
  191. {
  192. if (thingList[i] is Pawn)
  193. {
  194. return true;
  195. }
  196. if ((thingList[i].def.category == ThingCategory.Building || thingList[i].def.category == ThingCategory.Item) && GenSpawn.SpawningWipes(ThingDefOf.Hive, thingList[i].def))
  197. {
  198. return true;
  199. }
  200. }
  201. return false;
  202. }
  203.  
  204. private static int StraightLineDistToUnroofed(IntVec3 cell, Map map)
  205. {
  206. int num = 2147483647;
  207. int i = 0;
  208. while (i < 4)
  209. {
  210. Rot4 rot = new Rot4(i);
  211. IntVec3 facingCell = rot.FacingCell;
  212. int num2 = 0;
  213. int num3;
  214. while (true)
  215. {
  216. IntVec3 intVec = cell + facingCell * num2;
  217. if (!intVec.InBounds(map))
  218. {
  219. goto Block_1;
  220. }
  221. num3 = num2;
  222. if (InfestationCellFinder.NoRoofAroundAndWalkable(intVec, map))
  223. {
  224. break;
  225. }
  226. num2++;
  227. }
  228. IL_6F:
  229. if (num3 < num)
  230. {
  231. num = num3;
  232. }
  233. i++;
  234. continue;
  235. Block_1:
  236. num3 = 2147483647;
  237. goto IL_6F;
  238. }
  239. if (num == 2147483647)
  240. {
  241. return map.Size.x;
  242. }
  243. return num;
  244. }
  245.  
  246. private static float DistToBlocker(IntVec3 cell, Map map)
  247. {
  248. int num = -2147483648;
  249. int num2 = -2147483648;
  250. for (int i = 0; i < 4; i++)
  251. {
  252. Rot4 rot = new Rot4(i);
  253. IntVec3 facingCell = rot.FacingCell;
  254. int num3 = 0;
  255. int num4;
  256. while (true)
  257. {
  258. IntVec3 c = cell + facingCell * num3;
  259. num4 = num3;
  260. if (!c.InBounds(map) || !c.Walkable(map))
  261. {
  262. break;
  263. }
  264. num3++;
  265. }
  266. if (num4 > num)
  267. {
  268. num2 = num;
  269. num = num4;
  270. }
  271. else if (num4 > num2)
  272. {
  273. num2 = num4;
  274. }
  275. }
  276. return (float)Mathf.Min(num, num2);
  277. }
  278.  
  279. private static bool NoRoofAroundAndWalkable(IntVec3 cell, Map map)
  280. {
  281. if (!cell.Walkable(map))
  282. {
  283. return false;
  284. }
  285. if (cell.Roofed(map))
  286. {
  287. return false;
  288. }
  289. for (int i = 0; i < 4; i++)
  290. {
  291. Rot4 rot = new Rot4(i);
  292. IntVec3 c = rot.FacingCell + cell;
  293. if (c.InBounds(map) && c.Roofed(map))
  294. {
  295. return false;
  296. }
  297. }
  298. return true;
  299. }
  300.  
  301. private static float GetMountainousnessScoreAt(IntVec3 cell, Map map)
  302. {
  303. float num = 0f;
  304. int num2 = 0;
  305. for (int i = 0; i < 700; i += 10)
  306. {
  307. IntVec3 c = cell + GenRadial.RadialPattern[i];
  308. if (c.InBounds(map))
  309. {
  310. Building edifice = c.GetEdifice(map);
  311. if (edifice != null && edifice.def.category == ThingCategory.Building && edifice.def.building.isNaturalRock)
  312. {
  313. num += 1f;
  314. }
  315. else if (c.Roofed(map) && c.GetRoof(map).isThickRoof)
  316. {
  317. num += 0.5f;
  318. }
  319. num2++;
  320. }
  321. }
  322. return num / (float)num2;
  323. }
  324.  
  325. private static void CalculateTraversalDistancesToUnroofed(Map map)
  326. {
  327. InfestationCellFinder.tempUnroofedRegions.Clear();
  328. for (int i = 0; i < map.Size.z; i++)
  329. {
  330. for (int j = 0; j < map.Size.x; j++)
  331. {
  332. IntVec3 intVec = new IntVec3(j, 0, i);
  333. Region region = intVec.GetRegion(map, RegionType.Set_Passable);
  334. if (region != null && InfestationCellFinder.NoRoofAroundAndWalkable(intVec, map))
  335. {
  336. InfestationCellFinder.tempUnroofedRegions.Add(region);
  337. }
  338. }
  339. }
  340. Dijkstra<Region>.Run(InfestationCellFinder.tempUnroofedRegions, (Region x) => x.Neighbors, (Region a, Region b) => Mathf.Sqrt((float)a.extentsClose.CenterCell.DistanceToSquared(b.extentsClose.CenterCell)), ref InfestationCellFinder.regionsDistanceToUnroofed);
  341. InfestationCellFinder.tempUnroofedRegions.Clear();
  342. }
  343.  
  344. private static void CalculateClosedAreaSizeGrid(Map map)
  345. {
  346. if (InfestationCellFinder.closedAreaSize == null)
  347. {
  348. InfestationCellFinder.closedAreaSize = new ByteGrid(map);
  349. }
  350. else
  351. {
  352. InfestationCellFinder.closedAreaSize.ClearAndResizeTo(map);
  353. }
  354. for (int i = 0; i < map.Size.z; i++)
  355. {
  356. for (int j = 0; j < map.Size.x; j++)
  357. {
  358. IntVec3 intVec = new IntVec3(j, 0, i);
  359. if (InfestationCellFinder.closedAreaSize[j, i] == 0 && !intVec.Impassable(map))
  360. {
  361. int area = 0;
  362. map.floodFiller.FloodFill(intVec, (IntVec3 c) => !c.Impassable(map), delegate(IntVec3 c)
  363. {
  364. area++;
  365. }, false);
  366. area = Mathf.Min(area, 255);
  367. map.floodFiller.FloodFill(intVec, (IntVec3 c) => !c.Impassable(map), delegate(IntVec3 c)
  368. {
  369. InfestationCellFinder.closedAreaSize[c] = (byte)area;
  370. }, false);
  371. }
  372. }
  373. }
  374. }
  375.  
  376. private static void CalculateDistanceToColonyBuildingGrid(Map map)
  377. {
  378. if (InfestationCellFinder.distToColonyBuilding == null)
  379. {
  380. InfestationCellFinder.distToColonyBuilding = new ByteGrid(map);
  381. }
  382. else if (!InfestationCellFinder.distToColonyBuilding.MapSizeMatches(map))
  383. {
  384. InfestationCellFinder.distToColonyBuilding.ClearAndResizeTo(map);
  385. }
  386. InfestationCellFinder.distToColonyBuilding.Clear(255);
  387. InfestationCellFinder.tmpColonyBuildingsLocs.Clear();
  388. List<Building> allBuildingsColonist = map.listerBuildings.allBuildingsColonist;
  389. for (int i = 0; i < allBuildingsColonist.Count; i++)
  390. {
  391. InfestationCellFinder.tmpColonyBuildingsLocs.Add(allBuildingsColonist[i].Position);
  392. }
  393. Dijkstra<IntVec3>.Run(InfestationCellFinder.tmpColonyBuildingsLocs, (IntVec3 x) => DijkstraUtility.AdjacentCellsNeighborsGetter(x, map), delegate(IntVec3 a, IntVec3 b)
  394. {
  395. if (a.x == b.x || a.z == b.z)
  396. {
  397. return 1f;
  398. }
  399. return 1.41421354f;
  400. }, ref InfestationCellFinder.tmpDistanceResult);
  401. for (int j = 0; j < InfestationCellFinder.tmpDistanceResult.Count; j++)
  402. {
  403. InfestationCellFinder.distToColonyBuilding[InfestationCellFinder.tmpDistanceResult[j].Key] = (byte)Mathf.Min(InfestationCellFinder.tmpDistanceResult[j].Value, 254.999f);
  404. }
  405. }
  406. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement