/// <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); }
/// <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()); }
public SwapSlotsMessage(CarrySlot first, CarrySlot second) { if (first == second) { throw new ArgumentException("Slots can't be the same"); } First = first; Second = second; }
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; }
public CarriedBlock(CarrySlot slot, ItemStack stack, ITreeAttribute blockEntityData) { if (stack == null) { throw new ArgumentNullException(nameof(stack)); } Slot = slot; ItemStack = stack; BlockEntityData = blockEntityData; }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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)); }
/// <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)); }
public PickUpMessage(BlockPos position, CarrySlot slot) { Position = position; Slot = slot; }
/// <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)); }
/// <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);
/// <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;
/// <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);
/// <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)); }