private void saveChunkColumn(int planetId, Index2 index, IChunkColumn value)
 {
     if (!disablePersistence && value.Chunks.Any(c => c.ChangeCounter > 0))
     {
         persistenceManager.SaveColumn(universe.Id, planetId, value);
     }
 }
Example #2
0
        private IEnumerable <IChunkColumn> GenerateChunks(ChunkCoordinates center, int renderDistance)
        {
            var oldChunks = _loadedChunks.ToArray();

            double radiusSquared = Math.Pow(renderDistance, 2);

            List <ChunkCoordinates> newChunkCoordinates = new List <ChunkCoordinates>();

            List <ChunkCoordinates> results = new List <ChunkCoordinates>((renderDistance * 2) * (renderDistance * 2));

            for (int y = -renderDistance; y <= renderDistance; y++)
            {
                for (int x = -renderDistance; x <= renderDistance; x++)
                {
                    results.Add(new ChunkCoordinates(x, y));
                }
            }

            foreach (var cc in results.OrderBy(p =>
            {
                int dx = p.X;
                int dy = p.Z;
                return(dx * dx + dy * dy);
            })
                     .TakeWhile(p =>
            {
                int dx = p.X;
                int dy = p.Z;
                var r = dx * dx + dy * dy;
                return(r < radiusSquared);
            }))
            {
                var acc = center + cc;
                newChunkCoordinates.Add(acc);

                if (!_loadedChunks.Contains(acc))
                {
                    IChunkColumn chunk =
                        _generator.GenerateChunkColumn(acc);

                    if (chunk == null)
                    {
                        continue;
                    }

                    _loadedChunks.Add(acc);

                    yield return(chunk);
                }
            }

            foreach (var chunk in oldChunks)
            {
                if (!newChunkCoordinates.Contains((ChunkCoordinates)chunk))
                {
                    UnloadChunk(chunk.X, chunk.Z);
                    _loadedChunks.Remove(chunk);
                }
            }
        }
Example #3
0
        private void GenerateHeightMap(IChunkColumn chunk)
        {
            BlockCoordinates coords;
            var map = new byte[16, 16];

            for (byte x = 0; x < 16; x++)
            {
                for (byte z = 0; z < 16; z++)
                {
                    for (byte y = (byte)(chunk.GetHeight(x, z) + 2); y > 0; y--)
                    {
                        if (y >= 255)
                        {
                            continue;
                        }
                        coords.X = x; coords.Y = y - 1; coords.Z = z;

                        var provider = chunk.GetBlockState(coords.X, coords.Y, coords.Z).Block;

                        if (!provider.Renderable)
                        {
                            continue;
                        }

                        if (provider == null || provider.LightOpacity != 0)
                        {
                            map[x, z] = y;
                            break;
                        }
                    }
                }
            }
            HeightMaps[new ChunkCoordinates(chunk.X, chunk.Z)] = map;
        }
Example #4
0
        public void AddChunk(IChunkColumn chunk, ChunkCoordinates position, bool doUpdates = false)
        {
            var c = Chunks.AddOrUpdate(position, coordinates =>
            {
                return(chunk);
            }, (vector3, chunk1) =>
            {
                if (!ReferenceEquals(chunk1, chunk))
                {
                    chunk1.Dispose();
                }

                Log.Warn($"Replaced/Updated chunk at {position}");
                return(chunk);
            });

            if (doUpdates)
            {
                ScheduleChunkUpdate(position, ScheduleType.Full);

                ScheduleChunkUpdate(new ChunkCoordinates(position.X + 1, position.Z), ScheduleType.Border);
                ScheduleChunkUpdate(new ChunkCoordinates(position.X - 1, position.Z), ScheduleType.Border);
                ScheduleChunkUpdate(new ChunkCoordinates(position.X, position.Z + 1), ScheduleType.Border);
                ScheduleChunkUpdate(new ChunkCoordinates(position.X, position.Z - 1), ScheduleType.Border);
            }

            //InitiateChunk(c, position);
        }
        /// <summary>
        /// Lädt eine <see cref="IChunkColumn"/>.
        /// </summary>
        /// <param name="universeGuid">GUID des Universums.</param>
        /// <param name="planet">Index des Planeten.</param>
        /// <param name="columnIndex">Zu serialisierende ChunkColumn.</param>
        /// <returns>Die neu geladene ChunkColumn.</returns>
        public Awaiter Load(out IChunkColumn column, Guid universeGuid, IPlanet planet, Index2 columnIndex)
        {
            string file = Path.Combine(GetRoot(), universeGuid.ToString(), planet.Id.ToString(), string.Format(ColumnFilename, columnIndex.X, columnIndex.Y));

            column = new ChunkColumn();
            if (!File.Exists(file))
            {
                return(null);
            }

            try
            {
                using (Stream stream = File.Open(file, FileMode.Open, FileAccess.Read))
                {
                    using (GZipStream zip = new GZipStream(stream, CompressionMode.Decompress))
                    {
                        var awaiter = new Awaiter();
                        awaiter.Serializable = column;
                        awaiter.SetResult(planet.Generator.GenerateColumn(zip, definitionManager, planet.Id, columnIndex));
                        return(awaiter);
                    }
                }
            }
            catch (IOException)
            {
                try
                {
                    File.Delete(file);
                }
                catch (IOException) { }
                return(null);
            }
        }
Example #6
0
        public override void Populate(IDefinitionManager definitionManager, IPlanet planet, IChunkColumn column00, IChunkColumn column10, IChunkColumn column01, IChunkColumn column11)
        {
            // Tree Definitions initialisieren
            if (treeDefinitions == null)
            {
                treeDefinitions = definitionManager.GetDefinitions<ITreeDefinition>().OrderBy(d => d.Order).ToArray();
                foreach (var treeDefinition in treeDefinitions)
                    treeDefinition.Init(definitionManager);
            }

            int salt = (column00.Index.X & 0xffff) + ((column00.Index.Y & 0xffff) << 16);
            Random random = new Random(planet.Seed + salt);

            Index3 sample = new Index3(column00.Index.X * Chunk.CHUNKSIZE_X, column00.Index.Y * Chunk.CHUNKSIZE_Y, column00.Heights[0, 0]);
            foreach (var treeDefinition in treeDefinitions)
            {
                int density = treeDefinition.GetDensity(planet, sample);
                if (density <= 0) continue;

                for (int i = 0; i < density; i++)
                {
                    int x = random.Next(Chunk.CHUNKSIZE_X / 2, Chunk.CHUNKSIZE_X * 3 / 2);
                    int y = random.Next(Chunk.CHUNKSIZE_Y / 2, Chunk.CHUNKSIZE_Y * 3 / 2);
                    int z = LocalBuilder.GetSurfaceHeight(column00, column10, column01, column11, x, y);

                    LocalBuilder builder = new LocalBuilder(x, y, z + 1, column00, column10, column01, column11);
                    treeDefinition.PlantTree(definitionManager, planet, new Index3(x, y, z), builder, random.Next(int.MaxValue));
                }
            }
        }
Example #7
0
        public void ChunkReceived(IChunkColumn chunkColumn, int x, int z, bool update)
        {
            var c = new ChunkCoordinates(x, z);

            ChunkManager.AddChunk(chunkColumn, c, update);
            //InitiateChunk(chunkColumn as ChunkColumn);
        }
        /// <summary>
        /// Liefert den Chunk an der angegebenen Chunk-Koordinate zurück.
        /// </summary>
        /// <param name="x">X Koordinate</param>
        /// <param name="y">Y Koordinate</param>
        /// <param name="z">Z Koordinate</param>
        /// <returns>Instanz des Chunks</returns>
        public IChunk GetChunk(int x, int y, int z)
        {
            if (planet == null)
            {
                return(null);
            }
            if (z < 0)
            {
                return(null);
            }
            if (z >= planet.Size.Z)
            {
                return(null);
            }
            x = Index2.NormalizeAxis(x, planet.Size.X);
            y = Index2.NormalizeAxis(y, planet.Size.Y);

            IChunkColumn chunkColumn = chunkColumns[FlatIndex(x, y)];

            if (chunkColumn != null && chunkColumn.Index.X == x && chunkColumn.Index.Y == y)
            {
                return(chunkColumn.Chunks[z]);
            }
            return(null);
        }
Example #9
0
        public async ValueTask <IChunk> GetOrAddChunk(ChunkPosition position)
        {
            IChunkColumn chunkColumn = await GetOrAddChunkColumn(position.Column).Unchain();

            IChunk chunk = await chunkColumn.GetOrAddChunk(position.Y).Unchain();

            return(chunk);
        }
Example #10
0
        /// <summary>
        /// Erzeugt eine neue Instanz der Klasse LocalBuilder
        /// </summary>
        /// <param name="originX"></param>
        /// <param name="originY"></param>
        /// <param name="originZ"></param>
        /// <param name="column00"></param>
        /// <param name="column10"></param>
        /// <param name="column01"></param>
        /// <param name="column11"></param>
        public LocalBuilder(int originX, int originY, int originZ, IChunkColumn column00, IChunkColumn column10, IChunkColumn column01, IChunkColumn column11)
        {
            this.originX = originX;
            this.originY = originY;
            this.originZ = originZ;

            this.column00 = column00;
            this.column01 = column01;
            this.column10 = column10;
            this.column11 = column11;
        }
Example #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="block"></param>
        /// <param name="meta"></param>
        public void SetBlock(int x, int y, int z, ushort block, int meta = 0)
        {
            x += originX;
            y += originY;
            z += originZ;
            IChunkColumn column = GetColumn(column00, column10, column01, column11, x, y);

            x %= Chunk.CHUNKSIZE_X;
            y %= Chunk.CHUNKSIZE_Y;
            column.SetBlock(x, y, z, block, meta);
        }
Example #12
0
        public LocalBuilder(int originX, int originY, int originZ, IChunkColumn column00, IChunkColumn column10, IChunkColumn column01, IChunkColumn column11)
        {
            this.originX = originX;
            this.originY = originY;
            this.originZ = originZ;

            this.column00 = column00;
            this.column01 = column01;
            this.column10 = column10;
            this.column11 = column11;
        }
Example #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public ushort GetBlock(int x, int y, int z)
        {
            x += originX;
            y += originY;
            z += originZ;
            IChunkColumn column = GetColumn(column00, column10, column01, column11, x, y);

            x %= Chunk.CHUNKSIZE_X;
            y %= Chunk.CHUNKSIZE_Y;
            return(column.GetBlock(x, y, z));
        }
        // TODO: dont allow public constructor, use a chunk manager/provider instead

        public LocalChunk(IChunkColumn parent, int y, IBlockPalette blockPalette, BlockState airBlock)
        {
            // TODO: validate Y through a chunk manager or something
            Y = y;

            Column       = parent ?? throw new ArgumentNullException(nameof(parent));
            BlockPalette = blockPalette ?? throw new ArgumentNullException(nameof(blockPalette));
            AirBlock     = airBlock;

            // TODO: pool storage arrays
            _blocks = BitArray32.AllocateUninitialized(BlockCount, BlockPalette.BitsPerBlock);
        }
Example #15
0
 private void SetUpperVoxels(IChunkColumn chunk)
 {
     for (int x = 0; x < 16; x++)
     {
         for (int z = 0; z < 16; z++)
         {
             for (int y = chunk.GetHeighest() + 1; y < 255; y++)
             {
                 chunk.SetSkyLight(x, y, z, 15);
             }
         }
     }
 }
        /// <summary>
        /// Speichert eine <see cref="IChunkColumn"/>.
        /// </summary>
        /// <param name="universeGuid">GUID des Universums.</param>
        /// <param name="planetId">Index des Planeten.</param>
        /// <param name="column">Zu serialisierende ChunkColumn.</param>
        public void SaveColumn(Guid universeGuid, int planetId, IChunkColumn column)
        {
            string path = Path.Combine(GetRoot(), universeGuid.ToString(), planetId.ToString());

            Directory.CreateDirectory(path);

            string file = path = Path.Combine(path, string.Format(ColumnFilename, column.Index.X, column.Index.Y));

            using (Stream stream = File.Open(file, FileMode.Create, FileAccess.Write))
                using (GZipStream zip = new GZipStream(stream, CompressionMode.Compress))
                    using (BinaryWriter writer = new BinaryWriter(zip))
                        column.Serialize(writer, definitionManager);
        }
Example #17
0
        /// <summary>
        /// Leert den Cache und gibt sie beim GlobalChunkCache wieder frei
        /// </summary>
        public void Flush()
        {
            for (int i = 0; i < chunkColumns.Length; i++)
            {
                if (chunkColumns[i] == null)
                    continue;

                IChunkColumn chunkColumn = chunkColumns[i];

                globalCache.Release(chunkColumn.Index);
                chunkColumns[i] = null;
            }
        }
        public void SendChangedChunkColumn(IChunkColumn chunkColumn)
        {
            //var package = new Package((ushort)OfficialCommand.SaveColumn, 0);

            //using (var ms = new MemoryStream())
            //using (var bw = new BinaryWriter(ms))
            //{
            //    chunkColumn.Serialize(bw, definitionManager);
            //    package.Payload = ms.ToArray();
            //}


            //client.SendPackage(package);
        }
Example #19
0
        public static IChunkColumn GetColumn(IChunkColumn column00, IChunkColumn column10, IChunkColumn column01, IChunkColumn column11, int x, int y)
        {
            IChunkColumn column;
            if (x >= Chunk.CHUNKSIZE_X && y >= Chunk.CHUNKSIZE_Y)
                column = column11;
            else if (x < Chunk.CHUNKSIZE_X && y >= Chunk.CHUNKSIZE_Y)
                column = column01;
            else if (x >= Chunk.CHUNKSIZE_X && y < Chunk.CHUNKSIZE_Y)
                column = column10;
            else
                column = column00;

            return column;
        }
Example #20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="block"></param>
        /// <param name="meta"></param>
        public void SetBlock(int x, int y, int z, ushort block, int meta = 0)
        {
            x += originX;
            y += originY;
            z += originZ;
            IChunkColumn column = GetColumn(column00, column10, column01, column11, x, y);
            var          index  = z / Chunk.CHUNKSIZE_Z;

            x %= Chunk.CHUNKSIZE_X;
            y %= Chunk.CHUNKSIZE_Y;
            z %= Chunk.CHUNKSIZE_Z;
            var flatIndex = Chunk.GetFlatIndex(x, y, z);

            column.Chunks[index].Blocks[flatIndex] = block;
        }
Example #21
0
        /// <summary>
        /// Leert den Cache und gibt sie beim GlobalChunkCache wieder frei
        /// </summary>
        public void Flush()
        {
            for (int i = 0; i < chunkColumns.Length; i++)
            {
                if (chunkColumns[i] == null)
                {
                    continue;
                }

                IChunkColumn chunkColumn = chunkColumns[i];

                globalCache.Release(chunkColumn.Planet, chunkColumn.Index, IsPassive);
                chunkColumns[i] = null;
            }
        }
Example #22
0
        /// <summary>
        /// Liefert den Chunk an der angegebenen Chunk-Koordinate zurück.
        /// </summary>
        /// <param name="x">X Koordinate</param>
        /// <param name="y">Y Koordinate</param>
        /// <param name="z">Z Koordinate</param>
        /// <returns>Instanz des Chunks</returns>
        public IChunk GetChunk(int x, int y, int z)
        {
            if (Planet == null || z < 0 || z >= Planet.Size.Z)
                return null;

            x = Index2.NormalizeAxis(x, Planet.Size.X);
            y = Index2.NormalizeAxis(y, Planet.Size.Y);

            IChunkColumn chunkColumn = chunkColumns[FlatIndex(x, y)];

            if (chunkColumn != null && chunkColumn.Index.X == x && chunkColumn.Index.Y == y)
                return chunkColumn.Chunks[z];

            return null;
        }
Example #23
0
        public void LoadChunkTest()
        {
            int          planet          = 2;
            Index2       index           = new Index2(6, 7);
            IChunkColumn result          = null;
            int          loadCallCounter = 0;
            int          saveCallCounter = 0;

            GlobalChunkCache cache = new GlobalChunkCache(
                (p, i) =>
            {
                Assert.Equals(i, index);
                loadCallCounter++;
                return(result = new TestChunkColumn(planet, index));
            },
                (i) => null,
                (p, i, c) =>
            {
                Assert.Equals(p, planet);
                Assert.Equals(i, index);
                Assert.Equals(c, result);
                saveCallCounter++;
            });

            Assert.Equals(0, cache.LoadedChunkColumns);
            Assert.Equals(0, loadCallCounter);
            Assert.Equals(0, saveCallCounter);

            // Chunk laden
            IChunkColumn x = cache.Subscribe(planet, index, false);

            Assert.Equals(x, result);
            Assert.Equals(x.Planet, planet);
            Assert.Equals(x.Index, index);
            Assert.Equals(1, loadCallCounter);
            Assert.Equals(0, saveCallCounter);

            Assert.Equals(1, cache.LoadedChunkColumns);

            // Chunk unload
            cache.Release(planet, index, false);
            System.Threading.Thread.Sleep(150);//TODO: dirty fix wait till completly cleaned up
            Assert.Equals(0, cache.LoadedChunkColumns);
            Assert.Equals(1, loadCallCounter);
            Assert.Equals(0, saveCallCounter);//Expected 0 cause chunk wasn't changed
        }
Example #24
0
        public void LoadChunkTest()
        {
            int          planet          = 2;
            Index2       index           = new Index2(6, 7);
            IChunkColumn result          = null;
            int          loadCallCounter = 0;
            int          saveCallCounter = 0;

            GlobalChunkCache cache = new GlobalChunkCache(
                (p, i) =>
            {
                Assert.AreEqual(i, index);
                loadCallCounter++;
                return(result = new TestChunkColumn(planet, index));
            },
                (p, i, c) =>
            {
                Assert.AreEqual(p, planet);
                Assert.AreEqual(i, index);
                Assert.AreEqual(c, result);
                saveCallCounter++;
            });

            Assert.AreEqual(0, cache.LoadedChunkColumns);
            Assert.AreEqual(0, loadCallCounter);
            Assert.AreEqual(0, saveCallCounter);

            // Chunk laden
            IChunkColumn x = cache.Subscribe(planet, index);

            Assert.AreEqual(x, result);
            Assert.AreEqual(x.Planet, planet);
            Assert.AreEqual(x.Index, index);
            Assert.AreEqual(1, loadCallCounter);
            Assert.AreEqual(0, saveCallCounter);

            Assert.AreEqual(1, cache.LoadedChunkColumns);

            // Chunk unload
            cache.Release(planet, index);

            Assert.AreEqual(0, cache.LoadedChunkColumns);
            Assert.AreEqual(1, loadCallCounter);
            Assert.AreEqual(1, saveCallCounter);
        }
Example #25
0
        private void InitiateChunk(IChunkColumn chunkColumn, ChunkCoordinates chunkCoordinates)
        {
            var chunkCoords = new BlockCoordinates(chunkCoordinates.X * 16, 0, chunkCoordinates.Z * 16);

            for (int x = 0; x < 16; x++)
            {
                for (int z = 0; z < 16; z++)
                {
                    for (int y = 255; y > 0; y--)
                    {
                        var blockState = chunkColumn.GetBlockState(x, y, z);
                        if (blockState.Block is Block b)
                        {
                            b.BlockPlaced(World, blockState, chunkCoords + new BlockCoordinates(x, y, z));
                        }
                    }
                }
            }
        }
Example #26
0
        /// <summary>
        /// Lädt eine <see cref="IChunkColumn"/>.
        /// </summary>
        /// <param name="universeGuid">GUID des Universums.</param>
        /// <param name="planet">Index des Planeten.</param>
        /// <param name="columnIndex">Zu serialisierende ChunkColumn.</param>
        /// <returns>Die neu geladene ChunkColumn.</returns>
        public Awaiter Load(out IChunkColumn column, Guid universeGuid, IPlanet planet, Index2 columnIndex)
        {
            var chunkColumContext = new ChunkColumnDbContext(databaseProvider.GetDatabase <Index2Tag>(universeGuid, planet.Id, false), planet);

            column = chunkColumContext.Get(columnIndex);

            if (column == null)
            {
                return(null);
            }
            //var localColumn = column;

            ApplyChunkDiff(column, universeGuid, planet);

            var awaiter = awaiterPool.Get();

            awaiter.SetResult(column);
            return(awaiter);
        }
Example #27
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="blockInfos"></param>
 public void SetBlocks(bool issueNotification, params BlockInfo[] blockInfos)
 => blockInfos
 .Select(b =>
 {
     var x = b.Position.X + originX;
     var y = b.Position.Y + originY;
     var z = b.Position.Z + originZ;
     IChunkColumn column = GetColumn(column00, column10, column01, column11, x, y);
     var index           = z / Chunk.CHUNKSIZE_Z;
     x       %= Chunk.CHUNKSIZE_X;
     y       %= Chunk.CHUNKSIZE_Y;
     z       %= Chunk.CHUNKSIZE_Z;
     var info = new BlockInfo(x, y, z, b.Block, b.Meta);
     return(new { info, index, column });
 })
 .GroupBy(a => a.column)
 .ForEach(column => column
          .GroupBy(i => i.index)
          .ForEach(i => column.Key.Chunks[i.Key].SetBlocks(issueNotification, i.Select(b => b.info).ToArray())));
Example #28
0
        /// <summary>
        /// Queues the initial lighting pass for a newly generated chunk.
        /// </summary>
        public void CalculateLighting(IChunkColumn chunk, bool skyLight = true, bool initial = false)
        {
            if (!chunk.SkyLightDirty)
            {
                return;
            }
            // Set voxels above max height to 0xFF
            if (initial)
            {
                SetUpperVoxels(chunk);
            }

            var coords = new ChunkCoordinates(chunk.X * 16, chunk.Z * 16);
            var min    = new Vector3(coords.X, 0, coords.Z);
            var max    = new Vector3(coords.X + 16, chunk.GetHeighest() + 2, coords.Z + 16);

            EnqueueOperation(new ChunkCoordinates(chunk.X, chunk.Z), new BoundingBox(min, max),
                             skyLight, initial);
        }
        public Awaiter Load(out IChunkColumn column, Guid universeGuid, IPlanet planet, Index2 columnIndex)
        {
            var package = new Package((ushort)OfficialCommand.LoadColumn, 0);

            using (var memoryStream = new MemoryStream())
                using (var binaryWriter = new BinaryWriter(memoryStream))
                {
                    binaryWriter.Write(universeGuid.ToByteArray());
                    binaryWriter.Write(planet.Id);
                    binaryWriter.Write(columnIndex.X);
                    binaryWriter.Write(columnIndex.Y);

                    package.Payload = memoryStream.ToArray();
                }
            column = new ChunkColumn();
            var awaiter = GetAwaiter(column, package.UId);

            client.SendPackage(package);

            return(awaiter);
        }
Example #30
0
        public void Populate(IResourceManager resourcemanager, IPlanet planet, IChunkColumn column00, IChunkColumn column01, IChunkColumn column10, IChunkColumn column11)
        {
            return;

            if (ispop-- <= 0)
            {
                return;
            }

            WauziEntity wauzi = new WauziEntity();

            var x = r.Next(0, Chunk.CHUNKSIZE_X / 2);
            var y = r.Next(0, Chunk.CHUNKSIZE_Y / 2);

            PositionComponent position = new PositionComponent()
            {
                Position = new Coordinate(0, new Index3(x + column00.Index.X * Chunk.CHUNKSIZE_X, y + column00.Index.Y * Chunk.CHUNKSIZE_Y, 200), new Vector3(0, 0, 0))
            };

            wauzi.Components.AddComponent(position);
            column00.Entities.Add(wauzi);
        }
Example #31
0
        private async Task OnGameTick(object sender, GameTickArgs e)
        {
            if (e.WorldAge % 512 == 0 && e.TimeOfDay > 12000 && e.TimeOfDay < 24000)
            {
                EntityWorldPos playerPosition = AttachedObject.GetValue(EntityWorldPositionComponent.EntityWorldPositionProperty);
                int            x = random.Next(9) - 4 + (int)playerPosition.X;
                int            z = random.Next(9) - 4 + (int)playerPosition.Z;
                BlockWorldPos  monsterBlockPos = new BlockWorldPos(x, 0, z);
                ChunkWorldPos  monsterChunkPos = monsterBlockPos.ToChunkWorldPos();
                var            chunkAccessor   = AttachedObject.GetComponent <ChunkAccessorComponent>();
                BiomeId        biomeId         = await chunkAccessor.GetBlockBiome(monsterBlockPos);

                IWorld            world   = AttachedObject.GetValue(WorldComponent.WorldProperty);
                GeneratorSettings setting = await world.GetGeneratorSettings();

                Biome        biome = Biome.GetBiome((int)biomeId, setting);
                IChunkColumn chunk = await chunkAccessor.GetChunk(monsterChunkPos);

                // TODO
                biome.SpawnMonster(world, GrainFactory, await chunk.GetState(), random, monsterBlockPos);
            }
        }
Example #32
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="column00"></param>
        /// <param name="column10"></param>
        /// <param name="column01"></param>
        /// <param name="column11"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static IChunkColumn GetColumn(IChunkColumn column00, IChunkColumn column10, IChunkColumn column01, IChunkColumn column11, int x, int y)
        {
            IChunkColumn column;

            if (x >= Chunk.CHUNKSIZE_X && y >= Chunk.CHUNKSIZE_Y)
            {
                column = column11;
            }
            else if (x < Chunk.CHUNKSIZE_X && y >= Chunk.CHUNKSIZE_Y)
            {
                column = column01;
            }
            else if (x >= Chunk.CHUNKSIZE_X && y < Chunk.CHUNKSIZE_Y)
            {
                column = column10;
            }
            else
            {
                column = column00;
            }

            return(column);
        }
Example #33
0
        /// <summary>
        /// Interne Methode, in der der zentrale Chunk gesetzt wird. Die Chunks um den Zentrumschunk werden auch nachgeladen falls nötig
        /// </summary>
        /// <param name="token">Token, um zu prüfen, ob die aktualisierung abgeborchen werden soll</param>
        /// <param name="planet">Der Planet, auf dem die Chunks aktualisiert werden sollen</param>
        /// <param name="index">Der ins Zentrum zu setzende Chunk</param>
        /// <param name="successCallback">Routine die Aufgerufen werden soll, falls das setzen erfolgreich war oder nicht</param>
        private void InternalSetCenter(CancellationToken token, IPlanet planet, Index2 index, Action <bool> successCallback)
        {
            if (planet == null)
            {
                successCallback?.Invoke(true);
                return;
            }

            List <Index2> requiredChunkColumns = new List <Index2>();

            for (int x = -range; x <= range; x++)
            {
                for (int y = -range; y <= range; y++)
                {
                    Index2 local = new Index2(index.X + x, index.Y + y);
                    local.NormalizeXY(planet.Size);
                    requiredChunkColumns.Add(local);
                }
            }

            // Erste Abbruchmöglichkeit
            if (token.IsCancellationRequested)
            {
                successCallback?.Invoke(false);
                return;
            }

            foreach (var chunkColumnIndex in requiredChunkColumns
                     .OrderBy(c => index.ShortestDistanceXY(c, new Index2(planet.Size))
                              .LengthSquared()))
            {
                int          localX      = chunkColumnIndex.X & mask;
                int          localY      = chunkColumnIndex.Y & mask;
                int          flatIndex   = FlatIndex(localX, localY);
                IChunkColumn chunkColumn = chunkColumns[flatIndex];

                // Alten Chunk entfernen, falls notwendig
                if (chunkColumn != null && chunkColumn.Index != chunkColumnIndex)
                {
                    globalCache.Release(planet.Id, chunkColumn.Index, IsPassive);
                    chunkColumns[flatIndex] = null;
                    chunkColumn             = null;
                }

                // Zweite Abbruchmöglichkeit
                if (token.IsCancellationRequested)
                {
                    successCallback?.Invoke(false);
                    return;
                }

                // Neuen Chunk laden
                if (chunkColumn == null)
                {
                    chunkColumn             = globalCache.Subscribe(planet.Id, new Index2(chunkColumnIndex), IsPassive);
                    chunkColumns[flatIndex] = chunkColumn;

                    if (chunkColumn == null)
                    {
                        successCallback?.Invoke(false);
                        return;
                    }
                }

                // Dritte Abbruchmöglichkeit
                if (token.IsCancellationRequested)
                {
                    successCallback?.Invoke(false);
                    return;
                }
            }

            successCallback?.Invoke(true);
        }
        /// <summary>
        /// Speichert eine <see cref="IChunkColumn"/>.
        /// </summary>
        /// <param name="universeGuid">GUID des Universums.</param>
        /// <param name="planetId">Index des Planeten.</param>
        /// <param name="column">Zu serialisierende ChunkColumn.</param>
        public void SaveColumn(Guid universeGuid, int planetId, IChunkColumn column)
        {
            string path = Path.Combine(GetRoot(), universeGuid.ToString(), planetId.ToString());
            Directory.CreateDirectory(path);

            string file = path = Path.Combine(path, string.Format(ColumnFilename, column.Index.X, column.Index.Y));
            using (Stream stream = File.Open(file, FileMode.Create, FileAccess.Write))
            {
                using (GZipStream zip = new GZipStream(stream, CompressionMode.Compress))
                {
                    column.Serialize(zip, DefinitionManager.Instance);
                }
            }
        }
Example #35
0
 /// <summary>
 /// Versieht einen Chunk mit Items
 /// </summary>
 /// <param name="definitionManager">Definition Manager</param>
 /// <param name="planet">Index des Planeten</param>
 /// <param name="column00">TODO: Kommentieren</param>
 /// <param name="column01">TODO: Kommentieren</param>
 /// <param name="column10">TODO: Kommentieren</param>
 /// <param name="column11">TODO: Kommentieren</param>
 public abstract void Populate(IDefinitionManager definitionManager, IPlanet planet, IChunkColumn column00, IChunkColumn column01, IChunkColumn column10, IChunkColumn column11);
Example #36
0
 private void saveChunkColumn(int planetId, Index2 index, IChunkColumn value)
 {
     if (!disablePersistence && value.Chunks.Any(c => c.ChangeCounter > 0))
     {
         persistenceManager.SaveColumn(universe.Id, planetId, value);
     }
 }
Example #37
0
 public static int GetSurfaceHeight(IChunkColumn column00, IChunkColumn column10, IChunkColumn column01, IChunkColumn column11, int x, int y)
 {
     IChunkColumn curColumn = GetColumn(column00, column10, column01, column11, x, y);
     return curColumn.Heights[x % Chunk.CHUNKSIZE_X, y % Chunk.CHUNKSIZE_Y];
 }