diff --git a/src/main/java/com/atsuishio/superbwarfare/block/SuperbItemInterfaceBlock.java b/src/main/java/com/atsuishio/superbwarfare/block/SuperbItemInterfaceBlock.java index 48c80469c..5764a6b38 100644 --- a/src/main/java/com/atsuishio/superbwarfare/block/SuperbItemInterfaceBlock.java +++ b/src/main/java/com/atsuishio/superbwarfare/block/SuperbItemInterfaceBlock.java @@ -4,10 +4,12 @@ import com.atsuishio.superbwarfare.block.entity.SuperbItemInterfaceBlockEntity; import com.atsuishio.superbwarfare.init.ModBlockEntities; import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.world.Containers; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.Block; @@ -21,6 +23,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.material.MapColor; import net.minecraft.world.level.pathfinder.PathComputationType; import net.minecraft.world.phys.BlockHitResult; @@ -33,13 +36,17 @@ public class SuperbItemInterfaceBlock extends BaseEntityBlock { public static final BooleanProperty ENABLED = BlockStateProperties.ENABLED; + public static final DirectionProperty FACING = DirectionProperty.create("facing"); + public SuperbItemInterfaceBlock() { this(BlockBehaviour.Properties.of().mapColor(MapColor.STONE).requiresCorrectToolForDrops().strength(3.0F, 4.8F).sound(SoundType.METAL)); } public SuperbItemInterfaceBlock(BlockBehaviour.Properties properties) { super(properties); + this.registerDefaultState(this.stateDefinition.any().setValue(ENABLED, true)); + this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.DOWN)); } @Nullable @@ -55,15 +62,14 @@ public class SuperbItemInterfaceBlock extends BaseEntityBlock { return pLevel.isClientSide ? null : createTickerHelper(pBlockEntityType, ModBlockEntities.SUPERB_ITEM_INTERFACE.get(), SuperbItemInterfaceBlockEntity::serverTick); } -// @Override -// public void setPlacedBy(@NotNull Level pLevel, @NotNull BlockPos pPos, @NotNull BlockState pState, LivingEntity pPlacer, ItemStack pStack) { -// if (pStack.get(DataComponents.CUSTOM_NAME) != null) { -// BlockEntity blockentity = pLevel.getBlockEntity(pPos); -// if (blockentity instanceof SuperbItemInterfaceBlockEntity entity) { -// entity.setCustomName(pStack.getHoverName()); -// } -// } -// } + @Nullable + @Override + public BlockState getStateForPlacement(@NotNull BlockPlaceContext context) { + Direction direction = context.getClickedFace().getOpposite(); + return this.defaultBlockState() + .setValue(FACING, direction) + .setValue(ENABLED, true); + } @Override public void onPlace(BlockState pState, @NotNull Level pLevel, @NotNull BlockPos pPos, BlockState pOldState, boolean pIsMoving) { @@ -137,7 +143,7 @@ public class SuperbItemInterfaceBlock extends BaseEntityBlock { @Override protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { - pBuilder.add(ENABLED); + pBuilder.add(ENABLED).add(FACING); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/block/entity/SuperbItemInterfaceBlockEntity.java b/src/main/java/com/atsuishio/superbwarfare/block/entity/SuperbItemInterfaceBlockEntity.java index 9a2df6376..3a1a0cb52 100644 --- a/src/main/java/com/atsuishio/superbwarfare/block/entity/SuperbItemInterfaceBlockEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/block/entity/SuperbItemInterfaceBlockEntity.java @@ -1,5 +1,6 @@ package com.atsuishio.superbwarfare.block.entity; +import com.atsuishio.superbwarfare.block.SuperbItemInterfaceBlock; import com.atsuishio.superbwarfare.init.ModBlockEntities; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -9,110 +10,80 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.world.Container; import net.minecraft.world.ContainerHelper; -import net.minecraft.world.WorldlyContainer; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.HopperBlock; import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.neoforged.neoforge.capabilities.Capabilities; import org.jetbrains.annotations.NotNull; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.function.BooleanSupplier; -import java.util.stream.IntStream; public class SuperbItemInterfaceBlockEntity extends BaseContainerBlockEntity { - public static final int MOVE_ITEM_SPEED = 64; + public static final int TRANSFER_COOLDOWN = 20; public static final int CONTAINER_SIZE = 5; private NonNullList items = NonNullList.withSize(CONTAINER_SIZE, ItemStack.EMPTY); private int cooldownTime = -1; - private long tickedGameTime; + + private Direction facing; public SuperbItemInterfaceBlockEntity(BlockPos pPos, BlockState pBlockState) { super(ModBlockEntities.SUPERB_ITEM_INTERFACE.get(), pPos, pBlockState); + + this.facing = pBlockState.getValue(SuperbItemInterfaceBlock.FACING); } public static void serverTick(Level level, BlockPos pos, BlockState state, SuperbItemInterfaceBlockEntity blockEntity) { --blockEntity.cooldownTime; - blockEntity.tickedGameTime = level.getGameTime(); - if (!blockEntity.isOnCooldown()) { - blockEntity.setCooldown(0); -// tryMoveItems(level, pos, state, blockEntity, () -> suckInItems(level, blockEntity)); - } - } + if (blockEntity.isOnCooldown()) return; + blockEntity.setCooldown(TRANSFER_COOLDOWN); - private static boolean tryMoveItems(Level pLevel, BlockPos pPos, BlockState pState, SuperbItemInterfaceBlockEntity pBlockEntity, BooleanSupplier pValidator) { - if (!pLevel.isClientSide) { - if (!pBlockEntity.isOnCooldown() && pState.getValue(HopperBlock.ENABLED)) { - boolean flag = false; - if (!pBlockEntity.isEmpty()) { - flag = ejectItems(pLevel, pPos, pState, pBlockEntity); - } + if (blockEntity.isEmpty()) return; - if (!pBlockEntity.inventoryFull()) { - flag |= pValidator.getAsBoolean(); - } + // find entities + var x = pos.getX() + blockEntity.facing.getStepX(); + var y = pos.getY() + blockEntity.facing.getStepY(); + var z = pos.getZ() + blockEntity.facing.getStepZ(); - if (flag) { - pBlockEntity.setCooldown(8); - setChanged(pLevel, pPos, pState); - return true; - } - } + var list = level.getEntities( + (Entity) null, + new AABB(x - 0.5, y - 0.5, z - 0.5, x + 0.5, y + 0.5, z + 0.5), + entity -> entity.getCapability(Capabilities.ItemHandler.ENTITY, null) != null + ); + if (list.isEmpty()) return; + var target = list.get(level.random.nextInt(list.size())); - } - return false; - } + // item transfer - private static boolean ejectItems(Level pLevel, BlockPos pPos, BlockState pState, SuperbItemInterfaceBlockEntity pSourceContainer) { -// if (net.minecraftforge.items.VanillaInventoryCodeHooks.insertHook(pSourceContainer)) return true; -// Container container = getAttachedContainer(pLevel, pPos, pState); -// if (container == null) { -// return false; -// } else { - // TODO 替换成开启吸物品的directions -// Direction direction = pState.getValue(HopperBlock.FACING).getOpposite(); -// if (!isFullContainer(container, direction)) { -// for (int i = 0; i < pSourceContainer.getContainerSize(); ++i) { -// if (!pSourceContainer.getItem(i).isEmpty()) { -// ItemStack itemstack = pSourceContainer.getItem(i).copy(); -// ItemStack itemstack1 = addItem(pSourceContainer, container, pSourceContainer.removeItem(i, 1), direction); -// if (itemstack1.isEmpty()) { -// container.setChanged(); -// return true; -// } -// -// pSourceContainer.setItem(i, itemstack); -// } -// } -// } - return false; -// } - } - - private static IntStream getSlots(Container pContainer, Direction pDirection) { - return pContainer instanceof WorldlyContainer ? IntStream.of(((WorldlyContainer) pContainer).getSlotsForFace(pDirection)) : IntStream.range(0, pContainer.getContainerSize()); - } - - private static boolean isFullContainer(Container pContainer, Direction pDirection) { - return getSlots(pContainer, pDirection).allMatch((p_59379_) -> { - ItemStack itemstack = pContainer.getItem(p_59379_); - return itemstack.getCount() >= itemstack.getMaxStackSize(); - }); - } - - private boolean inventoryFull() { - for (ItemStack itemstack : this.items) { - if (itemstack.isEmpty() || itemstack.getCount() != itemstack.getMaxStackSize()) { - return false; + var index = -1; + for (int i = 0; i < blockEntity.items.size(); i++) { + var stack = blockEntity.items.get(i); + if (!stack.isEmpty()) { + index = i; + break; } } - return true; + if (index == -1) return; + + var stack = blockEntity.items.get(index); + var itemHandler = target.getCapability(Capabilities.ItemHandler.ENTITY, null); + assert itemHandler != null; + + for (int i = 0; i < itemHandler.getSlots(); i++) { + if (stack.isEmpty()) break; + + stack = itemHandler.insertItem(i, stack, false); + } + + blockEntity.items.set(index, stack); + blockEntity.setChanged(); } @Override @@ -139,6 +110,7 @@ public class SuperbItemInterfaceBlockEntity extends BaseContainerBlockEntity { return Component.translatable("container.superbwarfare.superb_item_interface"); } + // TODO 实现菜单 @Override protected @NotNull AbstractContainerMenu createMenu(int pContainerId, @NotNull Inventory pInventory) { return null; @@ -151,13 +123,7 @@ public class SuperbItemInterfaceBlockEntity extends BaseContainerBlockEntity { @Override public boolean isEmpty() { - for (ItemStack itemstack : this.items) { - if (!itemstack.isEmpty()) { - return false; - } - } - - return true; + return this.items.stream().allMatch(ItemStack::isEmpty); } @Override @@ -201,10 +167,6 @@ public class SuperbItemInterfaceBlockEntity extends BaseContainerBlockEntity { return this.cooldownTime > 0; } - public long getLastUpdateTime() { - return this.tickedGameTime; - } - @Override protected @NotNull NonNullList getItems() { return this.items; diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModCapabilities.java b/src/main/java/com/atsuishio/superbwarfare/init/ModCapabilities.java index b2122088b..136d2329e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModCapabilities.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModCapabilities.java @@ -102,5 +102,11 @@ public class ModCapabilities { (obj, ctx) -> obj.getEnergyStorage() ); + // 卓越物品接口 + event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, + ModBlockEntities.SUPERB_ITEM_INTERFACE.get(), + (object, context) -> new InvWrapper(object) + ); + } }