Добрый день. Недавно решил сделать блок с Gui, и все было относительно хорошо, как вдруг я заметил кое-какую ошибку. Проблема заключается в том, что когда я закрываю инвентарь блока и открываю инвентарь игрока, предметы в инвентаре становятся невидимыми. Также я заметил ошибку в консоли(В разделе "Краш-лог"). Коды классов блока:
Cauldron(Сам блок):
public class Cauldron extends BlockWithEntity implements BlockEntityProvider {
public Cauldron(Settings settings) {
super(settings);
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if (state.getBlock() != newState.getBlock()) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof CauldronBlockEntity) {
ItemScatterer.spawn(world, pos, (CauldronBlockEntity)blockEntity);
world.updateComparators(pos,this);
}
super.onStateReplaced(state, world, pos, newState, moved);
}
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos,
PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!world.isClient) {
NamedScreenHandlerFactory screenHandlerFactory = state.createScreenHandlerFactory(world, pos);
if (screenHandlerFactory != null) {
player.openHandledScreen(screenHandlerFactory);
}
}
return ActionResult.SUCCESS;
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new CauldronBlockEntity(pos, state);
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return checkType(type, RealismBlockEntities.CAULDRON, CauldronBlockEntity::tick);
}
}
CauldronBlockEntity:
public class CauldronBlockEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory {
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(3, ItemStack.EMPTY);
protected final PropertyDelegate propertyDelegate;
private int progress = 0;
private int maxProgress = 100;
public CauldronBlockEntity(BlockPos pos, BlockState state) {
super(RealismBlockEntities.CAULDRON, pos, state);
this.propertyDelegate = new PropertyDelegate() {
public int get(int index) {
switch (index) {
case 0: return CauldronBlockEntity.this.progress;
case 1: return CauldronBlockEntity.this.maxProgress;
default: return 0;
}
}
public void set(int index, int value) {
switch(index) {
case 0: CauldronBlockEntity.this.progress = value; break;
case 1: CauldronBlockEntity.this.maxProgress = value; break;
}
}
public int size() {
return 2;
}
};
}
@Override
public DefaultedList<ItemStack> getItems() {
return this.inventory;
}
@Override
public Text getDisplayName() {
return Text.translatable("title.realism.cauldron");
}
@Nullable
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
return new CauldronScreenHandler(syncId, inv, this, this.propertyDelegate);
}
@Override
protected void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
Inventories.writeNbt(nbt, inventory);
nbt.putInt("cauldron.progress", progress);
}
@Override
public void readNbt(NbtCompound nbt) {
Inventories.readNbt(nbt, inventory);
super.readNbt(nbt);
progress = nbt.getInt("cauldron.progress");
}
private void resetProgress() {
this.progress = 0;
}
public static void tick(World world, BlockPos blockPos, BlockState state, CauldronBlockEntity entity) {
if(world.isClient()) {
return;
}
if(hasDesolationRecipe(entity)) {
markDirty(world, blockPos, state);
craftItem(entity);
}
}
private static void craftItem(CauldronBlockEntity entity) {
SimpleInventory inventory = new SimpleInventory(entity.size());
for (int i = 0; i < entity.size(); i++) {
inventory.setStack(i, entity.getStack(i));
}
Optional<DesolationRecipe> recipe = entity.getWorld().getRecipeManager()
.getFirstMatch(DesolationRecipe.Type.INSTANCE, inventory, entity.getWorld());
if(hasDesolationRecipe(entity)) {
entity.removeStack(1, 1);
entity.setStack(2, new ItemStack(recipe.get().getOutput().getItem(),
entity.getStack(2).getCount() + 1));
}
}
private static boolean hasDesolationRecipe(CauldronBlockEntity entity) {
SimpleInventory inventory = new SimpleInventory(entity.size());
for (int i = 0; i < entity.size(); i++) {
inventory.setStack(i, entity.getStack(i));
}
Optional<DesolationRecipe> match = entity.getWorld().getRecipeManager()
.getFirstMatch(DesolationRecipe.Type.INSTANCE, inventory, entity.getWorld());
return match.isPresent() && canInsertAmountIntoOutputSlot(inventory)
&& canInsertItemIntoOutputSlot(inventory, match.get().getOutput().getItem());
}
private static boolean canInsertItemIntoOutputSlot(SimpleInventory inventory, Item output) {
return inventory.getStack(2).getItem() == output || inventory.getStack(2).isEmpty();
}
private static boolean canInsertAmountIntoOutputSlot(SimpleInventory inventory) {
return inventory.getStack(2).getMaxCount() > inventory.getStack(2).getCount();
}
}
CauldronScreenHandler:
public class CauldronScreenHandler extends ScreenHandler {
private final Inventory inventory;
private final PropertyDelegate propertyDelegate;
public CauldronScreenHandler(int syncId, PlayerInventory inventory) {
this(syncId, inventory, new SimpleInventory(3), new ArrayPropertyDelegate(2));
}
public CauldronScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory, PropertyDelegate delegate) {
super(RealismScreenHandlers.CAULDRON_SCREEN_HANDLER, syncId);
checkSize(inventory, 3);
this.inventory = inventory;
inventory.onOpen(playerInventory.player);
this.propertyDelegate = delegate;
this.addSlot(new Slot(inventory, 0, 12, 15));
this.addSlot(new Slot(inventory, 1, 38, 15));
this.addSlot(new Slot(inventory, 2, 38, 51));
this.addSlot(new Slot(inventory, 3, 138, 51));
this.addSlot(new Slot(inventory, 4, 138, 15));
addPlayerInventory(playerInventory);
addPlayerHotbar(playerInventory);
addProperties(delegate);
}
public boolean isCrafting() {
return propertyDelegate.get(0) > 0;
}
public int getScaledProgress() {
int progress = this.propertyDelegate.get(0);
int maxProgress = this.propertyDelegate.get(1);
int progressArrowSize = 24;
return maxProgress != 0 && progress != 0 ? progress * progressArrowSize / maxProgress : 0;
}
@Override
public ItemStack quickMove(PlayerEntity player, int invSlot) {
ItemStack newStack = ItemStack.EMPTY;
Slot slot = this.slots.get(invSlot);
if (slot != null && slot.hasStack()) {
ItemStack originalStack = slot.getStack();
newStack = originalStack.copy();
if (invSlot < this.inventory.size()) {
if (!this.insertItem(originalStack, this.inventory.size(), this.slots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (!this.insertItem(originalStack, 0, this.inventory.size(), false)) {
return ItemStack.EMPTY;
}
if (originalStack.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
} else {
slot.markDirty();
}
}
return newStack;
}
@Override
public boolean canUse(PlayerEntity player) {
return this.inventory.canPlayerUse(player);
}
private void addPlayerInventory(PlayerInventory playerInventory) {
for (int i = 0; i < 3; ++i) {
for (int l = 0; l < 9; ++l) {
this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 86 + i * 18));
}
}
}
private void addPlayerHotbar(PlayerInventory playerInventory) {
for (int i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 144));
}
}
}
DesolationRecipe:
public class DesolationRecipe implements Recipe<SimpleInventory> {
private final Identifier id;
private final ItemStack output;
private final DefaultedList<Ingredient> recipeItems;
public DesolationRecipe(Identifier id, ItemStack output, DefaultedList<Ingredient> recipeItems) {
this.id = id;
this.output = output;
this.recipeItems = recipeItems;
}
@Override
public boolean matches(SimpleInventory inventory, World world) {
if(world.isClient) return false;
return recipeItems.get(0).test(inventory.getStack(1));
}
@Override
public ItemStack craft(SimpleInventory inventory) {
return output;
}
@Override
public boolean fits(int width, int height) {
return true;
}
@Override
public ItemStack getOutput() {
return output.copy();
}
@Override
public Identifier getId() {
return id;
}
@Override
public RecipeSerializer<?> getSerializer() {
return Serializer.INSTANCE;
}
@Override
public RecipeType<?> getType() {
return Type.INSTANCE;
}
public static class Serializer implements RecipeSerializer<DesolationRecipe>{
public static final Serializer INSTANCE = new Serializer();
public static final String ID = "desolation";
@Override
public DesolationRecipe read(Identifier id, JsonObject json) {
ItemStack output = ShapedRecipe.outputFromJson(JsonHelper.getObject(json, "output"));
JsonArray ingredients = JsonHelper.getArray(json, "ingredients");
DefaultedList<Ingredient> inputs = DefaultedList.ofSize(1, Ingredient.EMPTY);
for (int i = 0; i < inputs.size(); i++) {
inputs.set(i, Ingredient.fromJson(ingredients.get(i)));
}
return new DesolationRecipe(id, output, inputs);
}
@Override
public DesolationRecipe read(Identifier id, PacketByteBuf buf) {
DefaultedList<Ingredient> inputs = DefaultedList.ofSize(buf.readInt(), Ingredient.EMPTY);
for (int i = 0; i < inputs.size(); i++) {
inputs.set(i, Ingredient.fromPacket(buf));
}
ItemStack output = buf.readItemStack();
return new DesolationRecipe(id, output, inputs);
}
@Override
public void write(PacketByteBuf buf, DesolationRecipe recipe) {
buf.writeInt(recipe.getIngredients().size());
for (Ingredient ing : recipe.getIngredients()) {
ing.write(buf);
}
buf.writeItemStack(recipe.getOutput());
}
}
public static class Type implements RecipeType<DesolationRecipe> {
private Type() { }
public static final Type INSTANCE = new Type();
public static final String ID = "desolation";
}
}
- Краш-лог
-
[15:58:57] [Server thread/ERROR] (Minecraft) Failed to handle packet net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket@13efe51d, suppressing error
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at java.util.Arrays$ArrayList.get(Arrays.java:4165) ~[?:?]
at net.minecraft.util.collection.DefaultedList.get(DefaultedList.java:47) ~[[email protected]:?]
at net.fabricmc.realism.block.entity.ImplementedInventory.getStack(ImplementedInventory.java:129) ~[main/:?]
at net.minecraft.screen.slot.Slot.getStack(Slot.java:53) ~[[email protected]:?]
at net.minecraft.screen.ScreenHandler.sendContentUpdates(ScreenHandler.java:174) ~[[email protected]:?]
at net.minecraft.screen.ScreenHandler.addListener(ScreenHandler.java:139) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayerEntity.onScreenHandlerOpened(ServerPlayerEntity.java:424) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayerEntity.openHandledScreen(ServerPlayerEntity.java:1068) ~[[email protected]:?]
at net.fabricmc.realism.block.Cauldron.onUse(Cauldron.java:44) ~[main/:?]
at net.minecraft.block.AbstractBlock$AbstractBlockState.onUse(AbstractBlock.java:995) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayerInteractionManager.interactBlock(ServerPlayerInteractionManager.java:342) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayNetworkHandler.onPlayerInteractBlock(ServerPlayNetworkHandler.java:1146) ~[[email protected]:?]
at net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket.apply(PlayerInteractBlockC2SPacket.java:34) ~[[email protected]:?]
at net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket.apply(PlayerInteractBlockC2SPacket.java:8) ~[[email protected]:?]
at net.minecraft.network.NetworkThreadUtils.method_11072(NetworkThreadUtils.java:22) ~[[email protected]:?]
at net.minecraft.server.ServerTask.run(ServerTask.java:18) ~[[email protected]:?]
at net.minecraft.util.thread.ThreadExecutor.executeTask(ThreadExecutor.java:156) ~[[email protected]:?]
at net.minecraft.util.thread.ReentrantThreadExecutor.executeTask(ReentrantThreadExecutor.java:23) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:787) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:166) ~[[email protected]:?]
at net.minecraft.util.thread.ThreadExecutor.runTask(ThreadExecutor.java:130) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runOneTask(MinecraftServer.java:769) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runTask(MinecraftServer.java:763) ~[[email protected]:?]
at net.minecraft.util.thread.ThreadExecutor.runTasks(ThreadExecutor.java:115) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runTasksTillTickEnd(MinecraftServer.java:747) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:680) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:264) ~[[email protected]:?]
at java.lang.Thread.run(Thread.java:833) ~[?:?]
Краш-лог:
[15:58:57] [Server thread/ERROR] (Minecraft) Failed to handle packet net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket@13efe51d, suppressing error
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at java.util.Arrays$ArrayList.get(Arrays.java:4165) ~[?:?]
at net.minecraft.util.collection.DefaultedList.get(DefaultedList.java:47) ~[[email protected]:?]
at net.fabricmc.realism.block.entity.ImplementedInventory.getStack(ImplementedInventory.java:129) ~[main/:?]
at net.minecraft.screen.slot.Slot.getStack(Slot.java:53) ~[[email protected]:?]
at net.minecraft.screen.ScreenHandler.sendContentUpdates(ScreenHandler.java:174) ~[[email protected]:?]
at net.minecraft.screen.ScreenHandler.addListener(ScreenHandler.java:139) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayerEntity.onScreenHandlerOpened(ServerPlayerEntity.java:424) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayerEntity.openHandledScreen(ServerPlayerEntity.java:1068) ~[[email protected]:?]
at net.fabricmc.realism.block.Cauldron.onUse(Cauldron.java:44) ~[main/:?]
at net.minecraft.block.AbstractBlock$AbstractBlockState.onUse(AbstractBlock.java:995) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayerInteractionManager.interactBlock(ServerPlayerInteractionManager.java:342) ~[[email protected]:?]
at net.minecraft.server.network.ServerPlayNetworkHandler.onPlayerInteractBlock(ServerPlayNetworkHandler.java:1146) ~[[email protected]:?]
at net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket.apply(PlayerInteractBlockC2SPacket.java:34) ~[[email protected]:?]
at net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket.apply(PlayerInteractBlockC2SPacket.java:8) ~[[email protected]:?]
at net.minecraft.network.NetworkThreadUtils.method_11072(NetworkThreadUtils.java:22) ~[[email protected]:?]
at net.minecraft.server.ServerTask.run(ServerTask.java:18) ~[[email protected]:?]
at net.minecraft.util.thread.ThreadExecutor.executeTask(ThreadExecutor.java:156) ~[[email protected]:?]
at net.minecraft.util.thread.ReentrantThreadExecutor.executeTask(ReentrantThreadExecutor.java:23) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:787) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:166) ~[[email protected]:?]
at net.minecraft.util.thread.ThreadExecutor.runTask(ThreadExecutor.java:130) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runOneTask(MinecraftServer.java:769) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runTask(MinecraftServer.java:763) ~[[email protected]:?]
at net.minecraft.util.thread.ThreadExecutor.runTasks(ThreadExecutor.java:115) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runTasksTillTickEnd(MinecraftServer.java:747) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:680) ~[[email protected]:?]
at net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:264) ~[[email protected]:?]
at java.lang.Thread.run(Thread.java:833) ~[?:?]