Пример #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> Removes the <see cref="CarriedBlock"/>
        ///           carried by the specified entity in that slot. </summary>
        /// <example cref="ArgumentNullException"> Thrown if entity is null. </exception>
        public static void Remove(Entity entity, CarrySlot slot)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            var animation = entity.GetCarried(slot)?.Behavior?.Slots?[slot]?.Animation;

            if (animation != null)
            {
                entity.StopAnimation(animation);
            }

            if (entity is EntityAgent agent)
            {
                agent.Stats.Remove("walkspeed", $"{ CarrySystem.MOD_ID }:{ slot }");

                if (slot == CarrySlot.Hands)
                {
                    LockedItemSlot.Restore(agent.RightHandItemSlot);
                }
                if (slot != CarrySlot.Back)
                {
                    LockedItemSlot.Restore(agent.LeftHandItemSlot);
                }
                CarryHandler.SendLockSlotsMessage(agent as EntityPlayer);
            }

            entity.WatchedAttributes.Remove(ATTRIBUTE_ID, slot.ToString());
            ((SyncedTreeAttribute)entity.WatchedAttributes).MarkPathDirty(ATTRIBUTE_ID);
            entity.Attributes.Remove(ATTRIBUTE_ID, slot.ToString());
        }
Пример #3
0
 public SwapSlotsMessage(CarrySlot first, CarrySlot second)
 {
     if (first == second)
     {
         throw new ArgumentException("Slots can't be the same");
     }
     First  = first;
     Second = second;
 }
Пример #4
0
 public PlaceDownMessage(CarrySlot slot, BlockSelection selection)
 {
     Slot  = slot;
     _pos  = selection.Position;
     _face = (byte)selection.Face.Index;
     _x    = (float)selection.HitPosition.X;
     _y    = (float)selection.HitPosition.Y;
     _z    = (float)selection.HitPosition.Z;
 }
Пример #5
0
 public CarriedBlock(CarrySlot slot, ItemStack stack, ITreeAttribute blockEntityData)
 {
     if (stack == null)
     {
         throw new ArgumentNullException(nameof(stack));
     }
     Slot            = slot;
     ItemStack       = stack;
     BlockEntityData = blockEntityData;
 }
Пример #6
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);
        }
Пример #7
0
        /// <summary> Stores the specified stack and blockEntityData (may be null)
        ///           as the <see cref="CarriedBlock"/> of the entity in that slot. </summary>
        /// <example cref="ArgumentNullException"> Thrown if entity is null. </exception>
        public static void Set(Entity entity, CarrySlot slot, ItemStack stack, ITreeAttribute blockEntityData)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            entity.WatchedAttributes.Set(stack, ATTRIBUTE_ID, slot.ToString(), "Stack");
            ((SyncedTreeAttribute)entity.WatchedAttributes).MarkPathDirty(ATTRIBUTE_ID);

            if ((entity.World.Side == EnumAppSide.Server) && (blockEntityData != null))
            {
                entity.Attributes.Set(blockEntityData, ATTRIBUTE_ID, slot.ToString(), "Data");
            }

            var behavior     = stack.Block.GetBehaviorOrDefault(BlockBehaviorCarryable.DEFAULT);
            var slotSettings = behavior.Slots[slot];

            if (slotSettings?.Animation != null)
            {
                entity.StartAnimation(slotSettings.Animation);
            }

            if (entity is EntityAgent agent)
            {
                var speed = slotSettings?.WalkSpeedModifier ?? 0.0F;
                if (speed != 0.0F)
                {
                    agent.Stats.Set("walkspeed",
                                    $"{ CarrySystem.MOD_ID }:{ slot }", speed, false);
                }

                if (slot == CarrySlot.Hands)
                {
                    LockedItemSlot.Lock(agent.RightHandItemSlot);
                }
                if (slot != CarrySlot.Back)
                {
                    LockedItemSlot.Lock(agent.LeftHandItemSlot);
                }
                CarryHandler.SendLockSlotsMessage(agent as EntityPlayer);
            }
        }
Пример #8
0
        /// <summary> Attempts to pick up a <see cref="CarriedBlock"/> from the specified
        ///           world and position, removing it. Returns null if unsuccessful. </summary>
        /// <example cref="ArgumentNullException"> Thrown if world or pos is null. </exception>
        public static CarriedBlock PickUp(IWorldAccessor world, BlockPos pos,
                                          CarrySlot slot, bool checkIsCarryable = false)
        {
            var carried = Get(world, pos, slot);

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

            if (checkIsCarryable && !carried.Block.IsCarryable(slot))
            {
                return(null);
            }

            world.BlockAccessor.RemoveBlockEntity(pos);
            world.BlockAccessor.SetBlock(0, pos);
            return(carried);
        }
Пример #9
0
        /// <summary> Attempts to pick up a <see cref="CarriedBlock"/> from the specified
        ///           world and position, removing it. Returns null if unsuccessful. </summary>
        /// <example cref="ArgumentNullException"> Thrown if world or pos is null. </exception>
        public static CarriedBlock PickUp(IWorldAccessor world, BlockPos pos,
                                          CarrySlot slot, bool checkIsCarryable = false)
        {
            var carried = Get(world, pos, slot);

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

            if (checkIsCarryable && !carried.Block.IsCarryable(slot))
            {
                return(null);
            }

            world.BlockAccessor.SetBlock(0, pos);
            world.Api.ModLoader.GetModSystem <ModSystemBlockReinforcement>()?.ClearReinforcement(pos);
            world.BlockAccessor.TriggerNeighbourBlockUpdate(pos);
            return(carried);
        }
Пример #10
0
        /// <summary> Creates a <see cref="CarriedBlock"/> from the specified world
        ///           and position, but doesn't remove it. Returns null if unsuccessful. </summary>
        /// <example cref="ArgumentNullException"> Thrown if world or pos is null. </exception>
        public static CarriedBlock Get(IWorldAccessor world, BlockPos pos, CarrySlot slot)
        {
            if (world == null)
            {
                throw new ArgumentNullException(nameof(world));
            }
            if (pos == null)
            {
                throw new ArgumentNullException(nameof(pos));
            }

            var block = world.BlockAccessor.GetBlock(pos);

            if (block.Id == 0)
            {
                return(null);                           // Can't pick up air.
            }
            var stack = block.OnPickBlock(world, pos) ?? new ItemStack(block);

            ITreeAttribute blockEntityData = null;

            if (world.Side == EnumAppSide.Server)
            {
                var blockEntity = world.BlockAccessor.GetBlockEntity(pos);
                if (blockEntity != null)
                {
                    blockEntityData = new TreeAttribute();
                    blockEntity.ToTreeAttributes(blockEntityData);
                    blockEntityData = blockEntityData.Clone();
                    // We don't need to keep the position.
                    blockEntityData.RemoveAttribute("posx");
                    blockEntityData.RemoveAttribute("posy");
                    blockEntityData.RemoveAttribute("posz");
                    // And angle needs to be removed, or else it will
                    // override the angle set from block placement.
                    blockEntityData.RemoveAttribute("meshAngle");
                }
            }

            return(new CarriedBlock(slot, stack, blockEntityData));
        }
Пример #11
0
        /// <summary> Gets the <see cref="CarriedBlock"/> currently
        ///           carried by the specified entity, or null if none. </summary>
        /// <example cref="ArgumentNullException"> Thrown if entity is null. </exception>
        public static CarriedBlock Get(Entity entity, CarrySlot slot)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }

            var slotAttribute = entity.WatchedAttributes
                                .TryGet <ITreeAttribute>(ATTRIBUTE_ID, slot.ToString());

            if (slotAttribute == null)
            {
                return(null);
            }

            var stack = slotAttribute.GetItemstack("Stack");

            if (stack?.Class != EnumItemClass.Block)
            {
                return(null);
            }
            // The ItemStack returned by TreeAttribute.GetItemstack
            // may not have Block set, so we have to resolve it.
            if (stack.Block == null)
            {
                stack.ResolveBlockOrItem(entity.World);
                if (stack.Block == null)
                {
                    return(null);                                     // Can't resolve block?
                }
            }

            var blockEntityData = (entity.World.Side == EnumAppSide.Server)
                                ? entity.Attributes.TryGet <ITreeAttribute>(ATTRIBUTE_ID, slot.ToString(), "Data")
                                : null;

            return(new CarriedBlock(slot, stack, blockEntityData));
        }
Пример #12
0
 public PickUpMessage(BlockPos position, CarrySlot slot)
 {
     Position = position; Slot = slot;
 }
Пример #13
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));
        }
Пример #14
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);
Пример #15
0
 /// <summary> Returns whether the specified block can be carried in the specified slot.
 ///           Checks if <see cref="BlockBehaviorCarryable"/> is present and has slot enabled. </summary>
 public static bool IsCarryable(this Block block, CarrySlot slot)
 => (block.GetBehavior <BlockBehaviorCarryable>()?.Slots?[slot] != null);
 public SlotSettings this[CarrySlot slot]
 => _dict.TryGetValue(slot, out var settings) ? settings : null;
Пример #17
0
 /// <summary> Stores this <see cref="CarriedBlock"/> as the
 ///           specified entity's carried block in that slot. </summary>
 /// <example cref="ArgumentNullException"> Thrown if entity is null. </exception>
 public void Set(Entity entity, CarrySlot slot)
 => Set(entity, slot, ItemStack, BlockEntityData);
Пример #18
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));
        }