Example #1
0
        private void SpawnSeeds(ServerChunk chunk, TreeSoul soul)
        {
            // TODO: check other constraints (season, maxseeds etc)

            var seeds = chunk.Entities.OfType <TreeGrowingEntity>().Count(e => e.TreeTypeId == soul.TreeTypeId);

            if (seeds == 0)
            {
                var pos = new Vector2I(_fastRandom.Next(chunk.BlockData.ChunkSize.X),
                                       _fastRandom.Next(chunk.BlockData.ChunkSize.Z));

                var metaData = chunk.BlockData.GetColumnInfo(pos);

                var cursor =
                    _server.LandscapeManager.GetCursor(BlockHelper.ConvertToGlobal(chunk.Position,
                                                                                   new Vector3I(pos.X, metaData.MaxGroundHeight + 1, pos.Y)));

                while (cursor.GlobalPosition.Y > 0)
                {
                    var val = cursor.PeekValue(Vector3I.Down);

                    if (val != WorldConfiguration.CubeId.Air)
                    {
                        break;
                    }

                    cursor.Move(Vector3I.Down);
                }

                if (cursor.Read() != WorldConfiguration.CubeId.Air)
                {
                    return;
                }

                if (cursor.GlobalPosition.Y == 0)
                {
                    return;
                }

                var config   = _server.EntityFactory.Config;
                var treeBp   = config.TreeBluePrintsDico[soul.TreeTypeId];
                var treeSeed = _server.EntityFactory.CreateEntity <TreeGrowingEntity>();
                treeSeed.TreeTypeId         = soul.TreeTypeId;
                treeSeed.TreeRndSeed        = _fastRandom.Next();
                treeSeed.ModelName          = treeBp.SeedModel;
                treeSeed.Name               = "Seed of " + treeBp.Name;
                treeSeed.IsPickable         = true;
                treeSeed.IsPlayerCollidable = true;
                treeSeed.CollisionType      = Entity.EntityCollisionType.Model;
                treeSeed.MountPoint         = BlockFace.Top;
                treeSeed.Position           = cursor.GlobalPosition + new Vector3D(0.5, 0, 0.5);
                treeSeed.LinkedCube         = cursor.GlobalPosition - Vector3I.Up;
                treeSeed.BlockFaceCentered  = true;
                treeSeed.GrowingSeasons     = config.TreeBluePrintsDico[soul.TreeTypeId].GrowingSeasons;
                treeSeed.GrowingBlocks      = config.TreeBluePrintsDico[soul.TreeTypeId].GrowingBlocks;
                cursor.AddEntity(treeSeed);
            }
        }
Example #2
0
        private void TreeIntegrity(ServerChunk chunk, TreeSoul soul)
        {
            if (!soul.IsDamaged)
            {
                return;
            }

            // the tree will regenerate or die after one day
            if ((_server.Clock.Now - soul.LastUpdate) < UtopiaTimeSpan.FromDays(1))
            {
                return;
            }

            var config     = _server.EntityFactory.Config;
            var treeBp     = config.TreeBluePrintsDico[soul.TreeTypeId];
            var treeBlocks = _treeLSystem.Generate(soul.TreeRndSeed, new Vector3I(), treeBp);

            var cursor = _server.LandscapeManager.GetCursor(soul.Position);

            if (soul.IsDying)
            {
                // remove the tree
                using (cursor.TransactionScope())
                {
                    foreach (var blockWithPosition in treeBlocks)
                    {
                        cursor.GlobalPosition = (Vector3I)soul.Position + blockWithPosition.WorldPosition;

                        if (cursor.Read() == blockWithPosition.BlockId)
                        {
                            cursor.Write(WorldConfiguration.CubeId.Air);
                        }
                    }
                }
                chunk.Entities.Remove(soul);
            }
            else
            {
                // restore the tree
                using (cursor.TransactionScope())
                {
                    foreach (var blockWithPosition in treeBlocks)
                    {
                        cursor.GlobalPosition = (Vector3I)soul.Position + blockWithPosition.WorldPosition;

                        if (cursor.Read() == WorldConfiguration.CubeId.Air)
                        {
                            cursor.Write(blockWithPosition.BlockId);
                        }
                    }
                }

                soul.IsDamaged = false;
            }
        }
Example #3
0
        private void SpawnTreeEntities(ServerChunk chunk, TreeSoul soul)
        {
            var config = _server.EntityFactory.Config;
            var treeBp = config.TreeBluePrintsDico[soul.TreeTypeId];

            if (_server.Clock.Now - soul.LastItemsRegeneration < treeBp.ItemsRegenerationTime)
            {
                return;
            }

            List <BlockWithPosition> treeBlocks = null;

            soul.LastItemsRegeneration = _server.Clock.Now;

            foreach (var item in treeBp.StaticItems)
            {
                // check quantity limit
                var maxItems = _fastRandom.Next(item.Quantity.Min, item.Quantity.Max + 1);
                if (_server.LandscapeManager.AroundEntities(soul.Position, item.SpawningRange).Count(e => e.BluePrintId == item.ItemblueprintId) >= maxItems)
                {
                    continue;
                }

                var point = _fastRandom.NextVector2IInRadius(item.SpawningRange) + new Vector2I((int)soul.Position.X, (int)soul.Position.Z);

                var groundSpawning = item.SpawningType == SpawningType.Ground || (item.SpawningType == SpawningType.Both && _fastRandom.NextDouble() < 0.5f);

                if (groundSpawning)
                {
                    var cursor = _server.LandscapeManager.GetCursor(new Vector3I(point.X, AbstractChunk.ChunkSize.Y - 1, point.Y));

                    while (true)
                    {
                        var block = cursor.Read();

                        if (block != WorldConfiguration.CubeId.Air && block != treeBp.FoliageBlock)
                        {
                            break;
                        }

                        cursor.Move(Vector3I.Down);
                    }
                    cursor.Move(Vector3I.Up);

                    if (cursor.Read() == WorldConfiguration.CubeId.Air)
                    {
                        if (Vector3I.Distance(cursor.GlobalPosition, (Vector3I)soul.Position) <= item.SpawningRange)
                        {
                            var entity = (IStaticEntity)_server.EntityFactory.CreateFromBluePrint(item.ItemblueprintId);
                            entity.Position = cursor.GlobalPosition;

                            var blockLinkedItem = entity as IBlockLinkedEntity;
                            if (blockLinkedItem != null)
                            {
                                blockLinkedItem.LinkedCube = cursor.GlobalPosition + Vector3I.Down;
                            }

                            cursor.AddEntity(entity);
                        }
                    }
                }
                else
                {
                    // lazy initialization of tree
                    treeBlocks = treeBlocks ?? _treeLSystem.Generate(soul.TreeRndSeed, (Vector3I)soul.Position, treeBp);

                    // find the lowest Y in our point
                    var minY = treeBlocks.Where(b => b.WorldPosition.X == point.X && b.WorldPosition.Z == point.Y).Select(b => b.WorldPosition.Y).DefaultIfEmpty().Min();


                    if (minY == 0 || minY <= soul.Position.Y)
                    {
                        // the point is outside of tree
                        continue;
                    }

                    var cursor = _server.LandscapeManager.GetCursor(new Vector3I(point.X, minY - 1, point.Y));
                    if (cursor.Read() == WorldConfiguration.CubeId.Air)
                    {
                        var entity = (IStaticEntity)_server.EntityFactory.CreateFromBluePrint(item.ItemblueprintId);
                        entity.Position = cursor.GlobalPosition;

                        var blockLinkedItem = entity as IBlockLinkedEntity;
                        if (blockLinkedItem != null)
                        {
                            blockLinkedItem.LinkedCube = cursor.GlobalPosition + Vector3I.Down;
                        }

                        cursor.AddEntity(entity);
                    }
                }
            }
        }