Beispiel #1
0
        public IToolImpact Use(IDynamicEntity owner)
        {
            IToolImpact checkImpact;

            if (!CanDoBlockAction(owner, out checkImpact))
            {
                return(checkImpact);
            }

            var impact = new BlockToolImpact
            {
                SrcBlueprintId = BluePrintId
            };

            var cursor = LandscapeManager.GetCursor(owner.EntityState.PickedBlockPosition);

            if (cursor == null)
            {
                impact.Dropped = true;
                return(impact);
            }

            cursor.OwnerDynamicId = owner.DynamicId;

            var selectedCube = cursor.Read();

            var  treeSystem = new TreeLSystem();
            bool removed    = false;

            foreach (var soul in EntityFactory.LandscapeManager.AroundChunks(owner.Position, 16).SelectMany(c => c.Entities.Enumerate <TreeSoul>()))
            {
                var treeBlueprint = EntityFactory.Config.TreeBluePrintsDico[soul.TreeTypeId];

                if (selectedCube != treeBlueprint.TrunkBlock && selectedCube != treeBlueprint.FoliageBlock)
                {
                    continue;
                }

                var blocks = treeSystem.Generate(soul.TreeRndSeed, BlockHelper.EntityToBlock(soul.Position), treeBlueprint);

                if (blocks.Any(b => b.WorldPosition == owner.EntityState.PickedBlockPosition))
                {
                    cursor.RemoveEntity(soul.GetLink());
                    removed = true;
                    break;
                }
            }

            if (!removed)
            {
                impact.Message = "This is not an alive tree";
                return(impact);
            }

            TakeFromPlayer(owner);
            return(impact);
        }
Beispiel #2
0
        public IToolImpact BlockImpact(IDynamicEntity owner, bool runOnServer = false)
        {
            var entity = owner;
            var impact = new BlockToolImpact {
                SrcBlueprintId = BluePrintId
            };

            if (entity.EntityState.IsBlockPicked)
            {
                //Do Dynamic entity collision testing (Cannot place a block if a dynamic entity intersect.
                var blockBB = new BoundingBox(entity.EntityState.NewBlockPosition, entity.EntityState.NewBlockPosition + Vector3.One);
                foreach (var dynEntity in EntityFactory.DynamicEntityManager.EnumerateAround(entity.EntityState.NewBlockPosition))
                {
                    var dynBB = new BoundingBox(dynEntity.Position.AsVector3(), dynEntity.Position.AsVector3() + dynEntity.DefaultSize);
                    if (blockBB.Intersects(ref dynBB))
                    {
                        impact.Message = "Cannot place a block where someone is standing";
                        return(impact);
                    }
                }

                // Get the chunk where the entity will be added and check if another block static entity is present inside this block
                var workingchunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.NewBlockPosition);
                if (workingchunk == null)
                {
                    //Impossible to find chunk, chunk not existing, event dropped
                    impact.Message = "Chunk is not existing, event dropped";
                    impact.Dropped = true;
                    return(impact);
                }
                foreach (var staticEntity in workingchunk.Entities.OfType <IBlockLocationRoot>())
                {
                    if (staticEntity.BlockLocationRoot == entity.EntityState.NewBlockPosition)
                    {
                        impact.Message = "There is something there, remove it first " + staticEntity.BlockLocationRoot;
                        return(impact);
                    }
                }

                //Add new block
                var cursor = LandscapeManager.GetCursor(entity.EntityState.NewBlockPosition);
                if (cursor == null)
                {
                    //Impossible to find chunk, chunk not existing, event dropped
                    impact.Message = "Block not existing, event dropped";
                    impact.Dropped = true;
                    return(impact);
                }
                if (cursor.Read() == WorldConfiguration.CubeId.Air)
                {
                    if (!EntityFactory.Config.IsInfiniteResources)
                    {
                        var charEntity = owner as CharacterEntity;
                        if (charEntity == null)
                        {
                            impact.Message = "Character entity is expected";
                            return(impact);
                        }

                        var slot = charEntity.Inventory.FirstOrDefault(s => s.Item.StackType == StackType);

                        if (slot == null)
                        {
                            // we have no more items in the inventory, remove from the hand
                            slot           = charEntity.Equipment[EquipmentSlotType.Hand];
                            impact.Success = charEntity.Equipment.TakeItem(slot.GridPosition);
                        }
                        else
                        {
                            impact.Success = charEntity.Inventory.TakeItem(slot.GridPosition);
                        }

                        if (!impact.Success)
                        {
                            impact.Message = "Unable to take an item from the inventory";
                            return(impact);
                        }
                    }

                    cursor.Write(CubeId);
                    impact.Success = true;
                    impact.CubeId  = CubeId;

                    if (SoundEngine != null && EntityFactory.Config.ResourcePut != null)
                    {
                        SoundEngine.StartPlay3D(EntityFactory.Config.ResourcePut, entity.EntityState.NewBlockPosition + new Vector3(0.5f));
                    }

                    return(impact);
                }
            }
            impact.Message = "Pick a cube to use this tool";
            return(impact);
        }
        private IToolImpact BlockHit(IDynamicEntity owner)
        {
            var impact = new BlockToolImpact {
                SrcBlueprintId = BluePrintId,
                Position       = owner.EntityState.PickedBlockPosition
            };

            var cursor = LandscapeManager.GetCursor(owner.EntityState.PickedBlockPosition);

            if (cursor == null)
            {
                //Impossible to find chunk, chunk not existing, event dropped
                impact.Message = "Block not existing, event dropped";
                impact.Dropped = true;
                return(impact);
            }
            cursor.OwnerDynamicId = owner.DynamicId;

            if (cursor.PeekProfile().Indestructible)
            {
                impact.Message = "Indestrutible cube, cannot be removed !";
                return(impact);
            }

            DamageTag damage;

            var cube = cursor.Read(out damage);

            if (cube != WorldConfiguration.CubeId.Air)
            {
                impact.CubeId = cube;
                var profile  = cursor.PeekProfile();
                var hardness = profile.Hardness;

                if (damage == null)
                {
                    damage = new DamageTag {
                        Strength      = (int)hardness,
                        TotalStrength = (int)hardness
                    };
                }

                var toolBlockDamage = Damage;

                if (SpecialDamages != null)
                {
                    var index = SpecialDamages.FindIndex(cd => cd.CubeId == cube);

                    if (index != -1)
                    {
                        toolBlockDamage = SpecialDamages[index].Damage;
                    }
                }

                damage.Strength -= toolBlockDamage;

                if (toolBlockDamage > 0 && SoundEngine != null)
                {
                    if (profile.HitSounds.Count > 0)
                    {
                        var random = new Random();
                        var sound  = profile.HitSounds[random.Next(0, profile.HitSounds.Count)];
                        SoundEngine.StartPlay3D(sound, owner.EntityState.PickedBlockPosition + new Vector3(0.5f));
                    }
                }

                if (damage.Strength <= 0)
                {
                    var chunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.PickedBlockPosition);
                    if (chunk == null)
                    {
                        //Impossible to find chunk, chunk not existing, event dropped
                        impact.Message = "Chunk is not existing, event dropped";
                        impact.Dropped = true;
                        return(impact);
                    }
                    chunk.Entities.RemoveAll <BlockLinkedItem>(e => e.Linked && e.LinkedCube == owner.EntityState.PickedBlockPosition, owner.DynamicId);
                    cursor.Write(WorldConfiguration.CubeId.Air);

                    #region TreeSoul remove logic
                    foreach (var treeSoul in EntityFactory.LandscapeManager.AroundEntities(owner.EntityState.PickedBlockPosition, 16).OfType <TreeSoul>())
                    {
                        var treeBp = EntityFactory.Config.TreeBluePrintsDico[treeSoul.TreeTypeId];

                        if (cube != treeBp.FoliageBlock && cube != treeBp.TrunkBlock)
                        {
                            continue;
                        }

                        var treeLSystem = new TreeLSystem();

                        var treeBlocks = treeLSystem.Generate(treeSoul.TreeRndSeed, (Vector3I)treeSoul.Position, treeBp);

                        // did we remove the block of the tree?
                        if (treeBlocks.Exists(b => b.WorldPosition == owner.EntityState.PickedBlockPosition))
                        {
                            treeSoul.IsDamaged = true;

                            // count removed trunk blocks
                            var totalTrunks = treeBlocks.Count(b => b.BlockId == treeBp.TrunkBlock);

                            var existsTrunks = treeBlocks.Count(b =>
                            {
                                if (b.BlockId == treeBp.TrunkBlock)
                                {
                                    cursor.GlobalPosition = b.WorldPosition;
                                    return(cursor.Read() == treeBp.TrunkBlock);
                                }
                                return(false);
                            });

                            if (existsTrunks < totalTrunks / 2)
                            {
                                treeSoul.IsDying = true;
                            }
                        }
                    }
                    #endregion

                    if (SoundEngine != null && EntityFactory.Config.ResourceTake != null)
                    {
                        SoundEngine.StartPlay3D(EntityFactory.Config.ResourceTake, owner.EntityState.PickedBlockPosition + new Vector3(0.5f));
                    }

                    var charEntity = owner as CharacterEntity;
                    if (charEntity == null)
                    {
                        impact.Message = "Charater entity is expected";
                        return(impact);
                    }

                    var putItems = new List <KeyValuePair <IItem, int> >();
                    putItems.Add(new KeyValuePair <IItem, int>((IItem)EntityFactory.CreateFromBluePrint(cube), 1));

                    if (profile.Transformations != null)
                    {
                        var random = new FastRandom(owner.EntityState.PickedEntityPosition.GetHashCode() ^ owner.EntityState.Entropy);
                        foreach (var itemTransformation in profile.Transformations)
                        {
                            if (random.NextDouble() < itemTransformation.TransformChance)
                            {
                                // don't give the block
                                putItems.Clear();
                                foreach (var slot in itemTransformation.GeneratedItems)
                                {
                                    putItems.Add(new KeyValuePair <IItem, int>((Item)EntityFactory.CreateFromBluePrint(slot.BlueprintId), slot.Count));
                                }
                                break;
                            }
                        }
                    }

                    // in case of infinite resources we will not add more than 1 block entity
                    var existingSlot = charEntity.FindSlot(s => s.Item.BluePrintId == cube);

                    if (!EntityFactory.Config.IsInfiniteResources || existingSlot == null)
                    {
                        if (!charEntity.Inventory.PutMany(putItems))
                        {
                            impact.Message = "Can't put the item(s) to inventory";
                        }
                    }

                    impact.CubeId = WorldConfiguration.CubeId.Air;
                }
                else if (damage.Strength >= hardness)
                {
                    cursor.Write(cube);
                }
                else
                {
                    cursor.Write(cube, damage);
                }

                impact.Success = true;
                return(impact);
            }

            impact.Message = "Cannot hit air block";
            return(impact);
        }