// 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);
 }
Esempio n. 2
0
            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);
     }
 }
Esempio n. 5
0
    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();
    }
Esempio n. 6
0
 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);
 }
Esempio n. 7
0
        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);
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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);
        }