Skip to content

Commit

Permalink
fix: various backpack related issues
Browse files Browse the repository at this point in the history
- client not opening backpack gui
- server crashing when client tries to open
- backpack slot blacklist not being enforced
- inventory not saving properly
  • Loading branch information
MrTJP committed Feb 1, 2023
1 parent f57712e commit f81022f
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ public class BackpackScreen extends RedUIContainerScreen<BackpackContainer> {
public static final ResourceLocation BACKGROUND = new ResourceLocation(MOD_ID, "textures/gui/backpack.png");

public BackpackScreen(BackpackContainer container, PlayerInventory playerInventory, ITextComponent title) {
super(176, 68, container, playerInventory, title);
super(176, 168, container, playerInventory, title);

inventoryLabelX = 8;
inventoryLabelY = 75;

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@

import mrtjp.projectred.exploration.gui.screen.inventory.BackpackScreen;
import net.minecraft.client.gui.ScreenManager;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

import static mrtjp.projectred.exploration.init.ExplorationReferences.BACKPACK_CONTAINER;

public class ExplorationClientInit {

public static void init() {
final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();

modEventBus.addListener(ExplorationClientInit::clientSetup);
}

private static void clientSetup(final FMLClientSetupEvent event) {

// Register screens
ScreenManager.register(BACKPACK_CONTAINER, BackpackScreen::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ public void saveInventoryToMainHand(PlayerInventory playerInventory) {
BackpackItem.saveBackpackInventory(backpack, inventoryTag);
}
}

@Override
public boolean canPlaceItem(int slot, ItemStack stack) {
return BackpackItem.isItemAllowedInBackpack(stack);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;

import static mrtjp.projectred.exploration.init.ExplorationReferences.BACKPACK_CONTAINER;
Expand All @@ -26,31 +27,41 @@ public BackpackContainer(int windowId, PlayerInventory playerInventory) {

this.playerInventory = playerInventory;

InventoryLib.addPlayerInventory(playerInventory, 8, 86, this::addSlot);
InventoryLib.addInventory(inventory, 0, 8, 18, 9, 3, this::addSlot);
InventoryLib.addPlayerInventory(playerInventory, 8, 86, BackpackPlayerSlot::new, this::addSlot);
InventoryLib.addInventory(inventory, 0, 8, 18, 9, 3, BackpackSlot::new, this::addSlot);

inventory.addListener(this::onBackpackInventoryChanged);
inventory.loadInventoryFromMainHand(playerInventory);
}

@Override
public ItemStack clicked(int slotId, int dragType, ClickType clickType, PlayerEntity player) {
return super.clicked(slotId, dragType, clickType, player);
}
// Required because vanilla's shyte handling of number hotbar quick swap.
// Apparently it only asks the target slot (the one hovered over) if it can accept the item, but it does not ask the
// hotbar slot (corresponding to number pressed) if it can take the stack (which would be denied by the custom slot class's canTakeStack implemented above).
// Additionally, if the target slot is empty, it calls that empty slot's canTakeStack. This is almost certainly
// a bug. canTakeStack should be called on BOTH slots, and isItemValid should be called on BOTH slots with the other slots contents.

@Override
public void slotsChanged(IInventory inventory) {
super.slotsChanged(inventory);
//TODO save bag on server
// Note: Not reliable, not always called
if (isHotbar(slotId)) {
int hotbarIndex = slotId - 27;
if (hotbarIndex == player.inventory.selected) {
return ItemStack.EMPTY;
}
}

if (clickType == ClickType.SWAP) {
if (dragType == player.inventory.selected) {
return ItemStack.EMPTY;
}
}

return super.clicked(slotId, dragType, clickType, player);
}

@Override
public void removed(PlayerEntity player) {
super.removed(player);
if (!player.level.isClientSide) {
inventory.saveInventoryToMainHand(playerInventory);
}
inventory.saveInventoryToMainHand(playerInventory);
}

@Override
Expand All @@ -60,6 +71,87 @@ public boolean stillValid(PlayerEntity player) {
}

protected void onBackpackInventoryChanged(IInventory backpackInventory) {
//TODO save bag on server
// Note: no need to save here. Inventory is saved on container close
}

@Override
public ItemStack quickMoveStack(PlayerEntity player, int slotIndex) {
Slot slot = slots.get(slotIndex);
if (slot == null || !slot.hasItem()) return ItemStack.EMPTY;

ItemStack stack = slot.getItem();
ItemStack originalStack = stack.copy();

if (isBag(slotIndex)) {
if (!moveToEntireInventory(stack, true)) return ItemStack.EMPTY;
} else {
if (!moveToBag(stack, false)) return ItemStack.EMPTY;
}

if (stack.isEmpty()) {
slot.set(ItemStack.EMPTY);
} else {
slot.setChanged();
}

if (stack.getCount() == originalStack.getCount()) {
return ItemStack.EMPTY;
}

slot.onTake(player, stack);
return originalStack;
}

//@formatter:off
private boolean isPlayerInventory(int slotIndex) {
return slotIndex >= 0 && slotIndex < 27;
}
private boolean isHotbar(int slotIndex) {
return slotIndex >= 27 && slotIndex < 36;
}
private boolean isBag(int slotIndex) {
return slotIndex >= 36 && slotIndex < 63;
}

private boolean moveToPlayerInventory(ItemStack stack, boolean reverse) {
return moveItemStackTo(stack, 0, 27, reverse);
}
private boolean moveToHotbar(ItemStack stack, boolean reverse) {
return moveItemStackTo(stack, 27, 36, reverse);
}
private boolean moveToEntireInventory(ItemStack stack, boolean reverse) {
return moveItemStackTo(stack, 0, 36, reverse);
}
private boolean moveToBag(ItemStack stack, boolean reverse) {
return moveItemStackTo(stack, 36, 63, reverse);
}
//@formatter:on

/**
* Slot for the actual player inventory. Disables picking up backpack from hotbar.
*/
private static class BackpackPlayerSlot extends Slot {
public BackpackPlayerSlot(IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
}
@Override
public boolean mayPickup(PlayerEntity player) {
// Dont allow pickup if this is the slot containing the selected backpack
return getSlotIndex() != player.inventory.selected;
}
}

/**
* Slot for the backpack contents inventory. Enforces the backpack blacklist.
*/
private static class BackpackSlot extends Slot {
public BackpackSlot(IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
}

@Override
public boolean mayPlace(ItemStack stack) {
return BackpackItem.isItemAllowedInBackpack(stack);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import codechicken.lib.util.ServerUtils;
import mrtjp.projectred.ProjectRedExploration;
import mrtjp.projectred.core.inventory.BaseInventory;
import mrtjp.projectred.exploration.init.ExplorationTags;
import mrtjp.projectred.exploration.inventory.container.BackpackContainer;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
Expand All @@ -17,6 +18,9 @@
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;

import javax.annotation.Nullable;
Expand Down Expand Up @@ -58,12 +62,13 @@ public ActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand)
private void openGui(ServerPlayerEntity player) {
ServerUtils.openContainer(player,
new SimpleNamedContainerProvider((windowId, playerInventory, playerEntity) -> new BackpackContainer(windowId, playerInventory),
getDescription()));
new TranslationTextComponent(this.getDescriptionId())));
}

@Override
public void appendHoverText(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
super.appendHoverText(stack, world, tooltip, flag);
int itemCount = getBackpackItemCount(stack);
tooltip.add(new StringTextComponent(itemCount + " / 27").withStyle(TextFormatting.GRAY));
}

public DyeColor getDyeColor() {
Expand Down Expand Up @@ -101,4 +106,8 @@ public static void deleteBackpackInventory(ItemStack stack) {
stack.getTag().remove(TAG_INVENTORY);
}
}

public static boolean isItemAllowedInBackpack(ItemStack stack) {
return !ExplorationTags.BACKPACKS_DISALLOWED_TAG.contains(stack.getItem());
}
}

0 comments on commit f81022f

Please sign in to comment.