Quellcode durchsuchen

new map generate logic

JasonWang vor 6 Jahren
Ursprung
Commit
37864553d2

+ 4 - 2
src/MineCase.Core/World/Position.cs

@@ -222,9 +222,11 @@ namespace MineCase.World
         public BlockWorldPos ToBlockWorldPos()
         {
             var x = X * 16;
-            if (x < 0) x++;
+
+            // if (x < 0) x++;
             var z = Z * 16;
-            if (z < 0) z++;
+
+            // if (z < 0) z++;
             return new BlockWorldPos(x, 0, z);
         }
 

+ 25 - 51
src/MineCase.Server.Grains/World/ChunkColumnGrain.cs

@@ -39,7 +39,7 @@ namespace MineCase.Server.World
 
         public async Task<BlockState> GetBlockState(int x, int y, int z)
         {
-            await EnsureChunkPopulated();
+            await EnsureAroundChunkPopulated();
             return State.Storage[x, y, z];
         }
 
@@ -51,7 +51,7 @@ namespace MineCase.Server.World
 
         public async Task<ChunkColumnCompactStorage> GetState()
         {
-            await EnsureChunkPopulated();
+            await EnsureAroundChunkPopulated();
             return State.Storage;
         }
 
@@ -74,7 +74,7 @@ namespace MineCase.Server.World
 
         public async Task SetBlockState(int x, int y, int z, BlockState blockState)
         {
-            await EnsureChunkPopulated();
+            await EnsureAroundChunkPopulated();
             var state = State;
             var oldState = state.Storage[x, y, z];
 
@@ -139,7 +139,7 @@ namespace MineCase.Server.World
             }
         }
 
-        private async Task EnsureChunkGenerated()
+        private async Task EnsureChunkGenerated(bool writeState = true)
         {
             if (!State.Generated)
             {
@@ -188,57 +188,14 @@ namespace MineCase.Server.World
                 }
 
                 State.Generated = true;
-
-                // await WriteStateAsync();
+                if (writeState)
+                    await WriteStateAsync();
             }
         }
 
-        private async Task EnsureChunkPopulated()
+        public async Task EnsureChunkPopulated()
         {
-            if (!State.Generated)
-            {
-                var serverSetting = GrainFactory.GetGrain<IServerSettings>(0);
-                string worldType = (await serverSetting.GetSettings()).LevelType;
-                if (worldType == "DEFAULT" || worldType == "default")
-                {
-                    var generator = GrainFactory.GetGrain<IChunkGeneratorOverworld>(await World.GetSeed());
-                    GeneratorSettings settings = new GeneratorSettings
-                    {
-                    };
-                    State.Storage = await generator.Generate(World, ChunkWorldPos.X, ChunkWorldPos.Z, settings);
-                }
-                else if (worldType == "FLAT" || worldType == "flat")
-                {
-                    var generator = GrainFactory.GetGrain<IChunkGeneratorFlat>(await World.GetSeed());
-                    GeneratorSettings settings = new GeneratorSettings
-                    {
-                        FlatBlockId = new BlockState?[]
-                        {
-                            BlockStates.Bedrock(),
-                            BlockStates.Stone(),
-                            BlockStates.Stone(),
-                            BlockStates.Dirt(),
-                            BlockStates.Dirt(),
-                            BlockStates.GrassBlock()
-                        }
-                    };
-                    State.Storage = await generator.Generate(World, ChunkWorldPos.X, ChunkWorldPos.Z, settings);
-                }
-                else
-                {
-                    throw new System.NotSupportedException("Unknown world type in server setting file.");
-                }
-
-                for (int x = 0; x < 16; ++x)
-                {
-                    for (int z = 0; z < 16; ++z)
-                    {
-                        State.GroundHeight[x, z] = GroundHeight(x, z);
-                    }
-                }
-
-                State.Generated = true;
-            }
+            await EnsureChunkGenerated(false);
 
             if (!State.Populated)
             {
@@ -278,6 +235,23 @@ namespace MineCase.Server.World
             }
         }
 
+        private async Task EnsureAroundChunkPopulated()
+        {
+            await EnsureChunkPopulated();
+
+            (var worldKey, var chunkPos) = this.GetWorldAndChunkWorldPos();
+            var world = GrainFactory.GetGrain<IWorld>(worldKey);
+            for (int xOffset = -2; xOffset <= 2; ++xOffset)
+            {
+                for (int zOffset = -2; zOffset <= 2; ++zOffset)
+                {
+                    var curChunkPos = new ChunkWorldPos(chunkPos.X + xOffset, chunkPos.Z + zOffset);
+                    var chunkColumnKey = world.MakeAddressByPartitionKey(curChunkPos);
+                    await GrainFactory.GetGrain<IChunkColumn>(chunkColumnKey).EnsureChunkPopulated();
+                }
+            }
+        }
+
         protected ClientPlayPacketGenerator GetBroadcastGenerator()
         {
             return new ClientPlayPacketGenerator(GrainFactory.GetPartitionGrain<IChunkTrackingHub>(World, ChunkWorldPos), null);

+ 3 - 4
src/MineCase.Server.Grains/World/Decoration/Biomes/BiomeForestDecoratorGrain.cs

@@ -54,11 +54,10 @@ namespace MineCase.Server.World.Decoration.Biomes
             PlantsInfo info = new PlantsInfo();
             String infoString = JsonConvert.SerializeObject(info);
 
-            var grassGenerator = GrainFactory.GetGrain<IGrassGenerator>(infoString);
-            await grassGenerator.Generate(world, chunkWorldPos, 10, 0);
-
+            // var grassGenerator = GrainFactory.GetGrain<IGrassGenerator>(infoString);
+            // await grassGenerator.Generate(world, chunkWorldPos, 10);
             var treeGenerator = GrainFactory.GetGrain<ITreeGenerator>(infoString);
-            await treeGenerator.Generate(world, chunkWorldPos, 1, 1);
+            await treeGenerator.Generate(world, chunkWorldPos, 16);
         }
 
         public override Task SpawnMob(IWorld world, ChunkWorldPos chunkWorldPos)

+ 2 - 2
src/MineCase.Server.Grains/World/Decoration/Biomes/BiomePlainsDecoratorGrain.cs

@@ -71,10 +71,10 @@ namespace MineCase.Server.World.Decoration.Biomes
             String infoString = JsonConvert.SerializeObject(info);
 
             var grassGenerator = GrainFactory.GetGrain<IGrassGenerator>(infoString);
-            await grassGenerator.Generate(world, chunkWorldPos, 10, 0);
+            await grassGenerator.Generate(world, chunkWorldPos, 10);
 
             var treeGenerator = GrainFactory.GetGrain<ITreeGenerator>(infoString);
-            await treeGenerator.Generate(world, chunkWorldPos, 2, 1);
+            await treeGenerator.Generate(world, chunkWorldPos, 2);
         }
 
         public override Task SpawnMob(IWorld world, ChunkWorldPos chunkWorldPos)

+ 12 - 19
src/MineCase.Server.Grains/World/Decoration/Plants/PlantsGeneratorGrain.cs

@@ -89,29 +89,22 @@ namespace MineCase.Server.World.Decoration.Plants
 
         public abstract Task GenerateSingle(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos);
 
-        public virtual async Task Generate(IWorld world, ChunkWorldPos pos, int countPerChunk, int range)
+        public virtual async Task Generate(IWorld world, ChunkWorldPos pos, int countPerChunk)
         {
             int seed = await world.GetSeed();
 
-            for (int chunkXOffset = -range; chunkXOffset <= range; ++chunkXOffset)
+            BlockWorldPos curChunkCorner = pos.ToBlockWorldPos();
+
+            int chunkSeed = pos.X ^ pos.Z ^ seed;
+            Random rand = new Random(chunkSeed);
+            int countCurChunk = rand.Next(countPerChunk + 1);
+
+            for (int count = 0; count < countCurChunk; ++count)
             {
-                for (int chunkZOffset = -range; chunkZOffset <= range; ++chunkZOffset)
-                {
-                    ChunkWorldPos curChunkWorldPos = new ChunkWorldPos { X = pos.X + chunkXOffset, Z = pos.Z + chunkZOffset };
-                    BlockWorldPos curChunkCorner = curChunkWorldPos.ToBlockWorldPos();
-
-                    int chunkSeed = (pos.X + chunkXOffset) ^ (pos.Z + chunkZOffset) ^ seed ^ this.GetPrimaryKeyString().GetHashCode();
-                    Random rand = new Random(chunkSeed);
-                    int countCurChunk = rand.Next(countPerChunk + 1);
-
-                    for (int count = 0; count < countCurChunk; ++count)
-                    {
-                        int x = curChunkCorner.X + rand.Next(16);
-                        int z = curChunkCorner.Z + rand.Next(16);
-                        int groundHeight = await GetGroundHeight(world, pos, x, z);
-                        await GenerateSingle(world, pos, new BlockWorldPos { X = x, Y = groundHeight, Z = z });
-                    }
-                }
+                int x = curChunkCorner.X + rand.Next(16);
+                int z = curChunkCorner.Z + rand.Next(16);
+                int groundHeight = await GetGroundHeight(world, pos, x, z);
+                await GenerateSingle(world, pos, new BlockWorldPos { X = x, Y = groundHeight, Z = z });
             }
         }
     }

+ 1 - 1
src/MineCase.Server.Interfaces/World/Decoration/Plants/IPlantsGenerator.cs

@@ -9,6 +9,6 @@ namespace MineCase.Server.World.Decoration.Plants
 {
     public interface IPlantsGenerator : IGrainWithStringKey
     {
-        Task Generate(IWorld world, ChunkWorldPos pos, int countPerChunk, int range);
+        Task Generate(IWorld world, ChunkWorldPos pos, int countPerChunk);
     }
 }

+ 2 - 0
src/MineCase.Server.Interfaces/World/IChunkColumn.cs

@@ -32,5 +32,7 @@ namespace MineCase.Server.World
         Task<int> GetGroundHeight(int x, int z);
 
         Task OnBlockNeighborChanged(int x, int y, int z, BlockWorldPos neighborPosition, BlockState oldState, BlockState newState);
+
+        Task EnsureChunkPopulated();
     }
 }