Exemplo n.º 1
0
        public override EntityPosition GetPosition(IDynamicEntity owner)
        {
            var pos = new EntityPosition();

            if (!owner.EntityState.IsBlockPicked)
            {
                return(pos);
            }

            // Get the chunk where the entity will be added and check if another entity is present inside this block
            var workingchunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.NewBlockPosition);

            foreach (var entity in workingchunk.Entities.OfType <IBlockLocationRoot>())
            {
                if (entity.BlockLocationRoot == BlockLocationRoot)
                {
                    // IBlockLocationRoot Entity already present at this location
                    return(pos);
                }
            }

            pos.Position = new Vector3D(owner.EntityState.NewBlockPosition.X + 0.5f,
                                        owner.EntityState.NewBlockPosition.Y,
                                        owner.EntityState.NewBlockPosition.Z + 0.5f);

            pos.Rotation = Quaternion.Identity;
            pos.Valid    = true;

            return(pos);
        }
Exemplo n.º 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);
        }
Exemplo n.º 3
0
        public override EntityPosition GetPosition(IDynamicEntity owner)
        {
            var pos = new EntityPosition();

            Vector3I?newBlockPos = null;

            var playerRotation = owner.HeadRotation.GetLookAtVector();

            if (owner.EntityState.IsBlockPicked)
            {
                newBlockPos = owner.EntityState.NewBlockPosition;
            }
            else if (owner.EntityState.IsEntityPicked && owner.EntityState.PickedEntityLink.IsStatic)
            {
                var entity = owner.EntityState.PickedEntityLink.ResolveStatic(LandscapeManager);

                if (entity is BlockItem)
                {
                    newBlockPos = owner.EntityState.PickedEntityPosition.ToCubePosition();

                    var rotation  = entity.Rotation;
                    var normal    = Vector3.TransformNormal(owner.EntityState.PickPointNormal, Matrix.RotationQuaternion(rotation));
                    var converted = new Vector3I((int)Math.Round(normal.X, MidpointRounding.ToEven), (int)Math.Round(normal.Y, MidpointRounding.ToEven), (int)Math.Round(normal.Z, MidpointRounding.ToEven));
                    newBlockPos += converted;
                }
            }

            if (newBlockPos == null)
            {
                return(pos);
            }

            var cursor = LandscapeManager.GetCursor(newBlockPos.Value);

            if (cursor == null || cursor.Read() != WorldConfiguration.CubeId.Air || LandscapeManager.GetChunkFromBlock(newBlockPos.Value).Entities.OfType <BlockItem>().Any(i => i.BlockLocationRoot == newBlockPos))
            {
                return(pos);
            }

            // locate the entity, set translation in World space
            pos.Position = new Vector3D(newBlockPos.Value.X + 0.5f,
                                        newBlockPos.Value.Y,
                                        newBlockPos.Value.Z + 0.5f);

            //Set Orientation
            double entityRotation;

            if (Math.Abs(playerRotation.Z) >= Math.Abs(playerRotation.X))
            {
                if (playerRotation.Z < 0)
                {
                    entityRotation  = MathHelper.Pi;
                    pos.Orientation = ItemOrientation.North;
                }
                else
                {
                    entityRotation  = 0;
                    pos.Orientation = ItemOrientation.South;
                }
            }
            else
            {
                if (playerRotation.X < 0)
                {
                    entityRotation  = MathHelper.PiOver2;
                    pos.Orientation = ItemOrientation.East;
                }
                else
                {
                    entityRotation  = -MathHelper.PiOver2;
                    pos.Orientation = ItemOrientation.West;
                }
            }

            //Specific Item Rotation for this instance
            pos.Rotation = Quaternion.RotationAxis(new Vector3(0, 1, 0), (float)entityRotation);
            pos.Valid    = true;

            return(pos);
        }
Exemplo n.º 4
0
        public override EntityPosition GetPosition(IDynamicEntity owner)
        {
            var pos = new EntityPosition();

            if (!AllowFreeMount && !owner.EntityState.IsBlockPicked)
            {
                return(pos);
            }

            if (!MountPoint.HasFlag(BlockFace.Top) && owner.EntityState.PickPointNormal.Y == 1)
            {
                return(pos);
            }

            if (!MountPoint.HasFlag(BlockFace.Bottom) && owner.EntityState.PickPointNormal.Y == -1)
            {
                return(pos);
            }

            if (!MountPoint.HasFlag(BlockFace.Sides) && (owner.EntityState.PickPointNormal.X != 0 || owner.EntityState.PickPointNormal.Z != 0))
            {
                return(pos);
            }

            if (BlockEmptyRequired && owner.EntityState.IsBlockPicked)
            {
                //Get the chunk where the entity will be added and check if another entity is not present at the destination root block !
                var workingchunk = LandscapeManager.GetChunkFromBlock(owner.EntityState.PickedBlockPosition);

                if (workingchunk == null)
                {
                    return(pos);
                }

                foreach (var entity in workingchunk.Entities.OfType <BlockLinkedItem>().Where(x => x.Linked && x.LinkedCube == owner.EntityState.PickedBlockPosition))
                {
                    if (entity.BlockLocationRoot == owner.EntityState.NewBlockPosition && entity.LinkedCube == owner.EntityState.PickedBlockPosition)
                    {
                        //CubePlaced Entity already present at this location
                        return(pos);
                    }
                }
            }

            // locate the entity
            if (owner.EntityState.PickPointNormal.Y == 1) // = Put on TOP
            {
                if (BlockFaceCentered)
                {
                    var newBlockPos = owner.EntityState.IsBlockPicked ? owner.EntityState.NewBlockPosition : owner.EntityState.PickPoint.ToCubePosition();
                    pos.Position = new Vector3D(
                        newBlockPos + new Vector3(0.5f - (float)owner.EntityState.PickPointNormal.X / 2,
                                                  owner.EntityState.PickPoint.Y % 1,
                                                  0.5f - (float)owner.EntityState.PickPointNormal.Z / 2)
                        );
                }
                else
                {
                    pos.Position = new Vector3D(owner.EntityState.PickPoint);
                }
            }
            else if (owner.EntityState.PickPointNormal.Y == -1) //PUT on cube Bottom = (Ceiling)
            {
                pos.Position    = new Vector3D(owner.EntityState.PickPoint);
                pos.Position.Y -= DefaultSize.Y;
            }
            else //Put on a side
            {
                if (BlockFaceCentered)
                {
                    var newBlockPos = owner.EntityState.IsBlockPicked ? owner.EntityState.NewBlockPosition : owner.EntityState.PickPoint.ToCubePosition();
                    pos.Position = new Vector3D(
                        newBlockPos + new Vector3(0.5f - (float)owner.EntityState.PickPointNormal.X / 2,
                                                  0.5f,
                                                  0.5f - (float)owner.EntityState.PickPointNormal.Z / 2)
                        );
                }
                else
                {
                    pos.Position = new Vector3D(owner.EntityState.PickPoint);
                }

                pos.Position += new Vector3D(owner.EntityState.PickPointNormal.X == -1 ? -0.01 : 0,
                                             0,
                                             owner.EntityState.PickPointNormal.Z == -1 ? -0.01 : 0);


                var slope = 0d;

                if (owner.EntityState.PickPointNormal.X == -1)
                {
                    slope = -Math.PI / 2;
                }
                if (owner.EntityState.PickPointNormal.X == 1)
                {
                    slope = Math.PI / 2;                                             // ok
                }
                if (owner.EntityState.PickPointNormal.Z == -1)
                {
                    slope = Math.PI;                                             // ok
                }
                if (owner.EntityState.PickPointNormal.Z == 1)
                {
                    slope = 0;
                }

                pos.Rotation = Quaternion.RotationAxis(new Vector3(0, 1, 0), (float)slope);
            }

            pos.Valid = true;

            return(pos);
        }
Exemplo n.º 5
0
        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);
        }