实现卓越物品接口物品传输
This commit is contained in:
parent
082a33dc50
commit
1f5841da89
3 changed files with 68 additions and 94 deletions
|
@ -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<Block, BlockState> pBuilder) {
|
||||
pBuilder.add(ENABLED);
|
||||
pBuilder.add(ENABLED).add(FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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<ItemStack> 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<ItemStack> getItems() {
|
||||
return this.items;
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue