예제 #1
0
        /// <summary>
        ///   Attempts to swap the <see cref="CarriedBlock"/>s currently carried in the
        ///   entity's <paramref name="first"/> and <paramref name="second"/> slots.
        /// </summary>
        /// <example cref="ArgumentNullException"> Thrown if entity is null. </exception>
        public static bool Swap(this Entity entity, CarrySlot first, CarrySlot second)
        {
            if (first == second)
            {
                throw new ArgumentException("Slots can't be the same");
            }

            var carriedFirst  = CarriedBlock.Get(entity, first);
            var carriedSecond = CarriedBlock.Get(entity, second);

            if ((carriedFirst == null) && (carriedSecond == null))
            {
                return(false);
            }

            CarriedBlock.Remove(entity, first);
            CarriedBlock.Remove(entity, second);

            if (carriedFirst != null)
            {
                carriedFirst.Set(entity, second);
            }
            if (carriedSecond != null)
            {
                carriedSecond.Set(entity, first);
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        ///   Attempts to get this player to place down its
        ///   <see cref="CarriedBlock"/> (if any) at the specified
        ///   selection, returning whether it was successful.
        /// </summary>
        /// <example cref="ArgumentNullException"> Thrown if player or selection is null. </exception>
        public static bool PlaceCarried(this IPlayer player, BlockSelection selection, CarrySlot slot)
        {
            if (player == null)
            {
                throw new ArgumentNullException(nameof(player));
            }
            if (selection == null)
            {
                throw new ArgumentNullException(nameof(selection));
            }

            if (!player.Entity.World.Claims.TryAccess(
                    player, selection.Position, EnumBlockAccessFlags.BuildOrBreak))
            {
                return(false);
            }
            var carried = CarriedBlock.Get(player.Entity, slot);

            if (carried == null)
            {
                return(false);
            }

            return(carried.PlaceDown(player.Entity.World, selection, player.Entity));
        }
예제 #3
0
        /// <summary>
        ///   Attempts to get this entity to pick up the block the
        ///   specified position as a <see cref="CarriedBlock"/>,
        ///   returning whether it was successful.
        /// </summary>
        /// <example cref="ArgumentNullException"> Thrown if entity or pos is null. </exception>
        public static bool Carry(this Entity entity, BlockPos pos,
                                 CarrySlot slot, bool checkIsCarryable = true)
        {
            if (CarriedBlock.Get(entity, slot) != null)
            {
                return(false);
            }
            var carried = CarriedBlock.PickUp(entity.World, pos, slot, checkIsCarryable);

            if (carried == null)
            {
                return(false);
            }

            carried.Set(entity, slot);
            carried.PlaySound(pos, entity.World, (entity as EntityPlayer));
            return(true);
        }
예제 #4
0
        /// <summary>
        ///   Attempts to get this player to place down its
        ///   <see cref="CarriedBlock"/> (if any) at the specified
        ///   selection, returning whether it was successful.
        /// </summary>
        /// <example cref="ArgumentNullException"> Thrown if player or selection is null. </exception>
        public static bool PlaceCarried(this IPlayer player, BlockSelection selection, CarrySlot slot)
        {
            if (player == null)
            {
                throw new ArgumentNullException(nameof(player));
            }
            if (selection == null)
            {
                throw new ArgumentNullException(nameof(selection));
            }

            var carried = CarriedBlock.Get(player.Entity, slot);

            if (carried == null)
            {
                return(false);
            }

            return(carried.PlaceDown(player.Entity.World, selection, player.Entity));
        }
예제 #5
0
        /// <summary>
        ///   Attempts to make this entity drop its <see cref="CarriedBlock"/>
        ///   (if any) at the specified position, returning whether it was successful.
        /// </summary>
        /// <example cref="ArgumentNullException"> Thrown if entity or pos is null. </exception>
        public static bool DropCarried(this IEntity entity, BlockPos pos)
        {
            if (pos == null)
            {
                throw new ArgumentNullException(nameof(pos));
            }

            var carried = CarriedBlock.Get(entity);

            if (carried == null)
            {
                return(false);
            }

            var selection = new BlockSelection {
                Position    = pos,
                Face        = BlockFacing.UP,
                HitPosition = new Vec3d(0.5, 0.5, 0.5),
            };

            return(carried.PlaceDown(entity.World, selection, entity));
        }
예제 #6
0
        /// <summary> Attempts to make this entity drop its carried blocks from the
        ///           specified slots around its current position in the specified area. </summary>
        /// <example cref="ArgumentNullException"> Thrown if entity or slots is null. </exception>
        /// <example cref="ArgumentOutOfRangeException"> Thrown if hSize or vSize is negative. </exception>
        public static void DropCarried(this Entity entity, IEnumerable <CarrySlot> slots,
                                       int hSize = 2, int vSize = 4)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }
            if (slots == null)
            {
                throw new ArgumentNullException(nameof(slots));
            }
            if (hSize < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(hSize));
            }
            if (vSize < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(vSize));
            }

            var remaining = new HashSet <CarriedBlock>(
                slots.Select(s => entity.GetCarried(s))
                .Where(c => (c != null)));

            if (remaining.Count == 0)
            {
                return;
            }

            bool Drop(BlockPos pos, CarriedBlock block)
            {
                if (!block.PlaceDown(entity.World, new BlockSelection {
                    Position = pos
                }, null))
                {
                    return(false);
                }
                CarriedBlock.Remove(entity, block.Slot);
                return(true);
            }

            var centerBlock  = entity.Pos.AsBlockPos;
            var nearbyBlocks = new List <BlockPos>((hSize * 2 + 1) * (hSize * 2 + 1));

            for (int x = -hSize; x <= hSize; x++)
            {
                for (int z = -hSize; z <= hSize; z++)
                {
                    nearbyBlocks.Add(centerBlock.AddCopy(x, 0, z));
                }
            }
            nearbyBlocks = nearbyBlocks.OrderBy(b => b.DistanceTo(centerBlock)).ToList();

            var accessor   = entity.World.BlockAccessor;
            var blockIndex = 0;
            var distance   = 0;

            while (remaining.Count > 0)
            {
                var pos = nearbyBlocks[blockIndex];
                if (Math.Abs(pos.Y - centerBlock.Y) <= vSize)
                {
                    var sign      = Math.Sign(pos.Y - centerBlock.Y);
                    var testBlock = accessor.GetBlock(pos);
                    var placeable = remaining.FirstOrDefault(c => testBlock.IsReplacableBy(c.Block));
                    if (sign == 0)
                    {
                        sign = ((placeable != null) ? -1 : 1);
                    }
                    else if (sign > 0)
                    {
                        if ((placeable != null) && Drop(pos, placeable))
                        {
                            remaining.Remove(placeable);
                        }
                    }
                    else if ((placeable == null))
                    {
                        var above = pos.UpCopy();
                        testBlock = accessor.GetBlock(above);
                        placeable = remaining.FirstOrDefault(c => testBlock.IsReplacableBy(c.Block));
                        if ((placeable != null) && Drop(above, placeable))
                        {
                            remaining.Remove(placeable);
                        }
                    }
                    pos.Add(0, sign, 0);
                }
                else if (blockIndex >= nearbyBlocks.Count)
                {
                    break;
                }

                if (++distance > 2)
                {
                    distance = 0;
                    blockIndex++;
                    if (blockIndex % 4 == 4)
                    {
                        if (++blockIndex >= nearbyBlocks.Count)
                        {
                            blockIndex = 0;
                        }
                    }
                }
            }

            // FIXME: Drop container contents if blocks could not be placed.
            //        Right now, the player just gets to keep them equipped.
        }
예제 #7
0
 /// <summary> Returns the <see cref="CarriedBlock"/> this entity
 ///           is carrying in the specified slot, or null of none. </summary>
 /// <example cref="ArgumentNullException"> Thrown if entity or pos is null. </exception>
 public static CarriedBlock GetCarried(this Entity entity, CarrySlot slot)
 => CarriedBlock.Get(entity, slot);
예제 #8
0
 /// <summary> Returns the <see cref="CarriedBlock"/>
 ///           this entity is carrying, or null of none. </summary>
 /// <example cref="ArgumentNullException"> Thrown if entity or pos is null. </exception>
 public static CarriedBlock GetCarried(this IEntity entity)
 => CarriedBlock.Get(entity);