// Token: 0x06000DB4 RID: 3508 RVA: 0x000620B8 File Offset: 0x000602B8 public HeightmapBuilder.HMBuildData RequestTerrain(Vector3 center, int width, float scale, bool distantLod, WorldGenerator worldGen) { this.m_lock.WaitOne(); for (int i = 0; i < this.m_ready.Count; i++) { HeightmapBuilder.HMBuildData hmbuildData = this.m_ready[i]; if (hmbuildData.IsEqual(center, width, scale, distantLod, worldGen)) { this.m_ready.RemoveAt(i); this.m_lock.ReleaseMutex(); return(hmbuildData); } } for (int j = 0; j < this.m_toBuild.Count; j++) { if (this.m_toBuild[j].IsEqual(center, width, scale, distantLod, worldGen)) { this.m_lock.ReleaseMutex(); return(null); } } this.m_toBuild.Add(new HeightmapBuilder.HMBuildData(center, width, scale, distantLod, worldGen)); this.m_lock.ReleaseMutex(); return(null); }
static bool Prefix(Minimap __instance) { if (!modEnabled.Value || !CheckKeyHeld(modKey.Value) || !Player.m_localPlayer) { return(true); } Vector3 pos = Traverse.Create(__instance).Method("ScreenToWorldPoint", new object[] { Input.mousePosition }).GetValue <Vector3>(); Dbgl($"trying to teleport from {Player.m_localPlayer.transform.position} to {pos}"); if (pos != Vector3.zero) { if (Player.m_localPlayer) { typeof(Minimap).GetMethod("SetMapMode", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Minimap.instance, new object[] { 1 }); Minimap.instance.m_smallRoot.SetActive(true); HeightmapBuilder.HMBuildData data = new HeightmapBuilder.HMBuildData(pos, 1, 1, false, WorldGenerator.instance); Traverse.Create(HeightmapBuilder.instance).Method("Build", new object[] { data }).GetValue(); pos.y = data.m_baseHeights[0]; Dbgl($"teleporting from {Player.m_localPlayer.transform.position} to {pos}"); Player.m_localPlayer.TeleportTo(pos, Player.m_localPlayer.transform.rotation, true); } } return(false); }
// Token: 0x06000DB1 RID: 3505 RVA: 0x00061BD0 File Offset: 0x0005FDD0 private void BuildThread() { ZLog.Log("Builder started"); while (!this.m_stop) { this.m_lock.WaitOne(); bool flag = this.m_toBuild.Count > 0; this.m_lock.ReleaseMutex(); if (flag) { this.m_lock.WaitOne(); HeightmapBuilder.HMBuildData hmbuildData = this.m_toBuild[0]; this.m_lock.ReleaseMutex(); new Stopwatch().Start(); this.Build(hmbuildData); this.m_lock.WaitOne(); this.m_toBuild.Remove(hmbuildData); this.m_ready.Add(hmbuildData); while (this.m_ready.Count > 16) { this.m_ready.RemoveAt(0); } this.m_lock.ReleaseMutex(); } Thread.Sleep(10); } }
private static bool BuildPrefix(HeightmapBuilder.HMBuildData data, out Stopwatch __state) { __state = new Stopwatch(); __state.Start(); if (BetterContinents.ConfigExperimentalMultithreadedHeightmapBuild.Value) { BuildMT(data); return(false); } else { return(true); } }
private void Generate() { this.Initialize(); int num1 = this.m_width + 1; int num2 = num1 * num1; Vector3 position = this.transform.position; if (this.m_buildData == null || this.m_buildData.m_baseHeights.Count != num2 || (this.m_buildData.m_center != position || (double)this.m_buildData.m_scale != (double)this.m_scale) || this.m_buildData.m_worldGen != WorldGenerator.instance) { this.m_buildData = HeightmapBuilder.instance.RequestTerrainSync(position, this.m_width, this.m_scale, this.m_isDistantLod, WorldGenerator.instance); this.m_cornerBiomes = this.m_buildData.m_cornerBiomes; } for (int index = 0; index < num2; ++index) { this.m_heights[index] = this.m_buildData.m_baseHeights[index]; } this.m_clearedMask.SetPixels(new Color[this.m_clearedMask.width * this.m_clearedMask.height]); this.ApplyModifiers(); }
public void Clear() { this.m_heights.Clear(); this.m_clearedMask = (Texture2D)null; this.m_materialInstance = (Material)null; this.m_buildData = (HeightmapBuilder.HMBuildData)null; if ((bool)(Object)this.m_collisionMesh) { this.m_collisionMesh.Clear(); } if ((bool)(Object)this.m_renderMesh) { this.m_renderMesh.Clear(); } if (!(bool)(Object)this.m_collider) { return; } this.m_collider.set_sharedMesh((Mesh)null); }
private static void RelocateMerchant(Vector2 coords) { if (merchantObject != null) { if (WorldGenerator.instance.GetBiome(coords.x, coords.y) != Heightmap.Biome.BlackForest) { Dbgl("Coordinates not in Black Forest"); return; } Vector3 position = new Vector3(coords.x, 0, coords.y); HeightmapBuilder.HMBuildData data = new HeightmapBuilder.HMBuildData(position, 1, 1, false, WorldGenerator.instance); Traverse.Create(HeightmapBuilder.instance).Method("Build", new object[] { data }).GetValue(); position.y = data.m_baseHeights[0]; merchantPosition.Value = position; merchantObject.transform.position = position; Dbgl($"Merchant relocated to position {position}"); } }
// Token: 0x06000DB2 RID: 3506 RVA: 0x00061CAC File Offset: 0x0005FEAC private void Build(HeightmapBuilder.HMBuildData data) { int num = data.m_width + 1; int num2 = num * num; Vector3 vector = data.m_center + new Vector3((float)data.m_width * data.m_scale * -0.5f, 0f, (float)data.m_width * data.m_scale * -0.5f); WorldGenerator worldGen = data.m_worldGen; data.m_cornerBiomes = new Heightmap.Biome[4]; data.m_cornerBiomes[0] = worldGen.GetBiome(vector.x, vector.z); data.m_cornerBiomes[1] = worldGen.GetBiome(vector.x + (float)data.m_width * data.m_scale, vector.z); data.m_cornerBiomes[2] = worldGen.GetBiome(vector.x, vector.z + (float)data.m_width * data.m_scale); data.m_cornerBiomes[3] = worldGen.GetBiome(vector.x + (float)data.m_width * data.m_scale, vector.z + (float)data.m_width * data.m_scale); Heightmap.Biome biome = data.m_cornerBiomes[0]; Heightmap.Biome biome2 = data.m_cornerBiomes[1]; Heightmap.Biome biome3 = data.m_cornerBiomes[2]; Heightmap.Biome biome4 = data.m_cornerBiomes[3]; data.m_baseHeights = new List <float>(num * num); for (int i = 0; i < num2; i++) { data.m_baseHeights.Add(0f); } for (int j = 0; j < num; j++) { float wy = vector.z + (float)j * data.m_scale; float t = Mathf.SmoothStep(0f, 1f, (float)j / (float)data.m_width); for (int k = 0; k < num; k++) { float wx = vector.x + (float)k * data.m_scale; float t2 = Mathf.SmoothStep(0f, 1f, (float)k / (float)data.m_width); float value; if (data.m_distantLod) { Heightmap.Biome biome5 = worldGen.GetBiome(wx, wy); value = worldGen.GetBiomeHeight(biome5, wx, wy); } else if (biome3 == biome && biome2 == biome && biome4 == biome) { value = worldGen.GetBiomeHeight(biome, wx, wy); } else { float biomeHeight = worldGen.GetBiomeHeight(biome, wx, wy); float biomeHeight2 = worldGen.GetBiomeHeight(biome2, wx, wy); float biomeHeight3 = worldGen.GetBiomeHeight(biome3, wx, wy); float biomeHeight4 = worldGen.GetBiomeHeight(biome4, wx, wy); float a = Mathf.Lerp(biomeHeight, biomeHeight2, t2); float b = Mathf.Lerp(biomeHeight3, biomeHeight4, t2); value = Mathf.Lerp(a, b, t); } data.m_baseHeights[j * num + k] = value; } } if (data.m_distantLod) { for (int l = 0; l < 4; l++) { List <float> list = new List <float>(data.m_baseHeights); for (int m = 1; m < num - 1; m++) { for (int n = 1; n < num - 1; n++) { float num3 = list[m * num + n]; float num4 = list[(m - 1) * num + n]; float num5 = list[(m + 1) * num + n]; float num6 = list[m * num + n - 1]; float num7 = list[m * num + n + 1]; if (Mathf.Abs(num3 - num4) > 10f) { num3 = (num3 + num4) * 0.5f; } if (Mathf.Abs(num3 - num5) > 10f) { num3 = (num3 + num5) * 0.5f; } if (Mathf.Abs(num3 - num6) > 10f) { num3 = (num3 + num6) * 0.5f; } if (Mathf.Abs(num3 - num7) > 10f) { num3 = (num3 + num7) * 0.5f; } data.m_baseHeights[m * num + n] = num3; } } } } }
private static bool BuildThreadPrefix(HeightmapBuilder __instance) { ZLog.Log("Builder started"); while (!__instance.m_stop) { if (!BetterContinents.ConfigExperimentalParallelChunksBuild.Value) { __instance.m_lock.WaitOne(); bool flag = __instance.m_toBuild.Count > 0; __instance.m_lock.ReleaseMutex(); if (flag) { __instance.m_lock.WaitOne(); HeightmapBuilder.HMBuildData hmbuildData = __instance.m_toBuild[0]; __instance.m_lock.ReleaseMutex(); var st = new Stopwatch(); st.Start(); __instance.Build(hmbuildData); buildTimes.Add(st.ElapsedMilliseconds); if (buildTimes.Count > 100) { buildTimes.RemoveAt(0); } BetterContinents.Log($"Average chunk build time with vanilla {buildTimes.Average()} ms"); __instance.m_lock.WaitOne(); __instance.m_toBuild.Remove(hmbuildData); __instance.m_ready.Add(hmbuildData); while (__instance.m_ready.Count > 16) { __instance.m_ready.RemoveAt(0); } __instance.m_lock.ReleaseMutex(); } Thread.Sleep(10); } else { __instance.m_lock.WaitOne(); var buildTasks = __instance.m_toBuild .Select(b => new { task = Task.Run(() => BuildFn(__instance, b)), buildData = b }) .ToList(); // Important to use ToList for force immediate enumeration inside the lock! __instance.m_toBuild.Clear(); __instance.m_lock.ReleaseMutex(); if (buildTasks.Any()) { var st = new Stopwatch(); st.Start(); Task.WaitAll(buildTasks.Select(bt => bt.task).ToArray()); buildTimes.Add(st.ElapsedMilliseconds / (float)buildTasks.Count); if (buildTimes.Count > 100) { buildTimes.RemoveAt(0); } BetterContinents.Log($"Average chunk build time with MT {buildTimes.Average()} ms"); __instance.m_lock.WaitOne(); foreach (var bt in buildTasks) { __instance.m_ready.Add(bt.buildData); } while (__instance.m_ready.Count > 16) { __instance.m_ready.RemoveAt(0); } __instance.m_lock.ReleaseMutex(); } } Thread.Sleep(10); } return(false); }
private static bool ApplyModifier_Prefix(TerrainModifier modifier, Heightmap __instance, int ___m_width, ref List <float> ___m_heights, ref Texture2D ___m_clearedMask, HeightmapBuilder.HMBuildData ___m_buildData) { if (ZoneSystem.instance == null) { return(true); } Vector2i zoneID = ZoneSystem.instance.GetZone(__instance.transform.position); BetterTerrain.ZoneInfo zone = HMAPManager.GetZoneInfo(zoneID); if (zone == null || modifier == null || __instance != zone.hmap) { return(false); } bool was_applied = zone.applied_tmods.Contains(modifier); if (!was_applied) { zone.applied_tmods.Add(modifier); } bool can_delete = true; float modifier_radius = modifier.GetRadius(); if (!zone.deletable_tmods.Contains(modifier)) { for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { BetterTerrain.ZoneInfo check_zone = HMAPManager.GetZoneInfo(new Vector2i(zoneID.x + x, zoneID.y + y)); if (check_zone != null && check_zone.generated) { foreach (TerrainModifier tmod in check_zone.tmods.Except(check_zone.applied_tmods)) { if (tmod != null) { float radius = Math.Max(tmod.GetRadius(), modifier_radius); if (tmod != modifier && Vector3.Distance(tmod.transform.position, modifier.transform.position) <= radius) { Debug.Log(Vector3.Distance(tmod.transform.position, modifier.transform.position)); can_delete = false; } } } } else { can_delete = false; } } } if (can_delete) { Debug.Log("x"); zone.deletable_tmods.Add(modifier); } } if (was_applied) { return(false); } if (zone.saved && HMAPManager.loading_object) { return(false); } return(true); }
private static bool Generate_Prefix(Heightmap __instance, int ___m_width, ref List <float> ___m_heights, ref Texture2D ___m_clearedMask, HeightmapBuilder.HMBuildData ___m_buildData) { if (ZoneSystem.instance == null) { return(true); } Vector3 position = __instance.transform.position; __instance.Initialize(); int num3 = __instance.m_width + 1; int num2 = num3 * num3; BetterTerrain.ZoneInfo zone = HMAPManager.GetZoneInfo(__instance.transform.position); if (zone == null || zone.game_object != __instance.gameObject) { return(true); } if (!zone.generated) { if (__instance.m_buildData == null || __instance.m_buildData.m_baseHeights.Count != num2 || __instance.m_buildData.m_center != position || __instance.m_buildData.m_scale != __instance.m_scale || __instance.m_buildData.m_worldGen != WorldGenerator.instance) { __instance.m_buildData = HeightmapBuilder.instance.RequestTerrainSync(position, __instance.m_width, __instance.m_scale, __instance.m_isDistantLod, WorldGenerator.instance); __instance.m_cornerBiomes = __instance.m_buildData.m_cornerBiomes; } for (int i = 0; i < num2; i++) { __instance.m_heights[i] = __instance.m_buildData.m_baseHeights[i]; } Color[] pixels = new Color[__instance.m_clearedMask.width * __instance.m_clearedMask.height]; __instance.m_clearedMask.SetPixels(pixels); zone.generated = true; zone.hmap = __instance; } HMAPManager.RegenerateZone(zone); return(false); }