Prepare for second implementation pass - give bags UUIDs, utilize the UUID system of other compatible bag mods (like /dank/null) and support pseudo-unique bags of other mods by name + mod convention. Add a Bag Renamer to freely rename any bag based item.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package com.trunksbomb.bagtabs;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.trunksbomb.bagtabs.item.BagNamerItem;
|
||||
import com.trunksbomb.bagtabs.item.BagItem;
|
||||
import com.trunksbomb.bagtabs.menu.BagNamerMenu;
|
||||
import com.trunksbomb.bagtabs.menu.BagMenu;
|
||||
import com.trunksbomb.bagtabs.network.BagTabsNetwork;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
@@ -38,13 +40,17 @@ public class BagTabs {
|
||||
.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY)
|
||||
.component(DataComponents.DYED_COLOR, new DyedItemColor(BagItem.DEFAULT_COLOR, true))
|
||||
));
|
||||
public static final DeferredItem<Item> BAG_NAMER = ITEMS.register("bag_namer", () -> new BagNamerItem(new Item.Properties().stacksTo(1)));
|
||||
public static final DeferredHolder<CreativeModeTab, CreativeModeTab> BAG_TAB = CREATIVE_MODE_TABS.register(
|
||||
"main",
|
||||
() -> CreativeModeTab.builder()
|
||||
.title(Component.translatable("itemGroup." + MODID))
|
||||
.withTabsBefore(CreativeModeTabs.TOOLS_AND_UTILITIES)
|
||||
.icon(() -> BAG.get().getDefaultInstance())
|
||||
.displayItems((parameters, output) -> BagItem.createCreativeStacks().forEach(output::accept))
|
||||
.displayItems((parameters, output) -> {
|
||||
BagItem.createCreativeStacks().forEach(output::accept);
|
||||
output.accept(BAG_NAMER.get());
|
||||
})
|
||||
.build()
|
||||
);
|
||||
|
||||
@@ -52,6 +58,10 @@ public class BagTabs {
|
||||
"bag",
|
||||
() -> IMenuTypeExtension.create(BagMenu::fromNetwork)
|
||||
);
|
||||
public static final DeferredHolder<MenuType<?>, MenuType<BagNamerMenu>> BAG_NAMER_MENU = MENUS.register(
|
||||
"bag_namer",
|
||||
() -> IMenuTypeExtension.create(BagNamerMenu::fromNetwork)
|
||||
);
|
||||
|
||||
public BagTabs(IEventBus modEventBus) {
|
||||
ITEMS.register(modEventBus);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.trunksbomb.bagtabs;
|
||||
|
||||
import com.trunksbomb.bagtabs.client.BagScreen;
|
||||
import com.trunksbomb.bagtabs.client.BagNamerScreen;
|
||||
import com.trunksbomb.bagtabs.client.BagTabOverlay;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.minecraft.client.color.item.ItemColor;
|
||||
@@ -25,6 +26,7 @@ public class BagTabsClient {
|
||||
|
||||
private static void registerScreens(RegisterMenuScreensEvent event) {
|
||||
event.register(BagTabs.BAG_MENU.get(), BagScreen::new);
|
||||
event.register(BagTabs.BAG_NAMER_MENU.get(), BagNamerScreen::new);
|
||||
}
|
||||
|
||||
private static void registerItemColors(RegisterColorHandlersEvent.Item event) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.trunksbomb.bagtabs.bag;
|
||||
|
||||
import com.trunksbomb.bagtabs.item.BagItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
@@ -16,6 +17,9 @@ public final class BagAccess {
|
||||
|
||||
for (int slot = 0; slot < inventory.getContainerSize(); slot++) {
|
||||
ItemStack stack = inventory.getItem(slot);
|
||||
if (stack.getItem() instanceof BagItem) {
|
||||
BagIdentityData.ensureBagId(stack);
|
||||
}
|
||||
BagCompat.BagHandler handler = BagCompat.findHandler(stack);
|
||||
if (handler != null) {
|
||||
bags.add(new BagEntry(slot, stack.copy(), handler));
|
||||
|
||||
@@ -5,12 +5,15 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
|
||||
public final class BagCompat {
|
||||
private static final List<BagHandler> HANDLERS = List.of(
|
||||
@@ -41,6 +44,30 @@ public final class BagCompat {
|
||||
return getActiveBagSlot(menu) >= 0;
|
||||
}
|
||||
|
||||
public static boolean canName(ItemStack stack) {
|
||||
return !stack.isEmpty() && (findHandler(stack) != null || looksLikeInventoryItem(stack));
|
||||
}
|
||||
|
||||
public static BagIdentity getIdentity(ItemStack stack) {
|
||||
if (!canName(stack)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (stack.getItem() instanceof InventoryBag) {
|
||||
return new BagIdentity("bagtabs:uuid:" + BagIdentityData.ensureBagId(stack), "uuid", true);
|
||||
}
|
||||
|
||||
Integer dankFrequency = getDankFrequency(stack);
|
||||
if (dankFrequency != null && dankFrequency >= 0) {
|
||||
return new BagIdentity("dankstorage:frequency:" + dankFrequency, "frequency", true);
|
||||
}
|
||||
|
||||
String namespace = BuiltInRegistries.ITEM.getKey(stack.getItem()).getNamespace();
|
||||
String displayName = stack.getHoverName().getString().trim().toLowerCase(Locale.ROOT);
|
||||
String normalizedName = displayName.replaceAll("\\s+", " ");
|
||||
return new BagIdentity(namespace + ":" + normalizedName, "name_mod", false);
|
||||
}
|
||||
|
||||
public static int getActiveBagSlot(AbstractContainerMenu menu) {
|
||||
if (menu instanceof BagMenu bagMenu) {
|
||||
return bagMenu.getBagSlot();
|
||||
@@ -114,6 +141,19 @@ public final class BagCompat {
|
||||
}
|
||||
}
|
||||
|
||||
private static Integer getDankFrequency(ItemStack stack) {
|
||||
if (!isInstance(DankStorageHandler.ITEM_CLASS, stack.getItem())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Object frequency = stack.getItem().getClass().getMethod("getFrequency", ItemStack.class).invoke(null, stack);
|
||||
return frequency instanceof Integer integer ? integer : null;
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TravelersBackpackHandler implements BagHandler {
|
||||
private static final String ITEM_CLASS = "com.tiviacz.travelersbackpack.items.TravelersBackpackItem";
|
||||
private static final String MENU_CLASS = "com.tiviacz.travelersbackpack.inventory.menu.AbstractBackpackMenu";
|
||||
@@ -442,6 +482,30 @@ public final class BagCompat {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean looksLikeInventoryItem(ItemStack stack) {
|
||||
if (stack.has(DataComponents.CONTAINER)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String itemPath = BuiltInRegistries.ITEM.getKey(stack.getItem()).getPath();
|
||||
String className = stack.getItem().getClass().getName().toLowerCase(Locale.ROOT);
|
||||
String lowerPath = itemPath.toLowerCase(Locale.ROOT);
|
||||
boolean nameHint = lowerPath.contains("bag")
|
||||
|| lowerPath.contains("backpack")
|
||||
|| lowerPath.contains("pouch")
|
||||
|| lowerPath.contains("satchel")
|
||||
|| lowerPath.contains("dank")
|
||||
|| lowerPath.contains("shulker")
|
||||
|| className.contains("bag")
|
||||
|| className.contains("backpack")
|
||||
|| className.contains("pouch")
|
||||
|| className.contains("satchel")
|
||||
|| className.contains("dank")
|
||||
|| className.contains("shulker");
|
||||
|
||||
return nameHint && stack.getMaxStackSize() == 1;
|
||||
}
|
||||
|
||||
private static Object invoke(Object target, String methodName) {
|
||||
try {
|
||||
Method method = target.getClass().getMethod(methodName);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.trunksbomb.bagtabs.bag;
|
||||
|
||||
public record BagIdentity(String key, String strategy, boolean stable) {
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.trunksbomb.bagtabs.bag;
|
||||
|
||||
import java.util.UUID;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
|
||||
public final class BagIdentityData {
|
||||
private static final String ROOT_KEY = "bagtabs";
|
||||
private static final String BAG_ID_KEY = "bag_id";
|
||||
|
||||
private BagIdentityData() {
|
||||
}
|
||||
|
||||
public static UUID getBagId(ItemStack stack) {
|
||||
CustomData customData = stack.get(DataComponents.CUSTOM_DATA);
|
||||
if (customData == null || !customData.contains(ROOT_KEY)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CompoundTag root = customData.copyTag().getCompound(ROOT_KEY);
|
||||
return root.hasUUID(BAG_ID_KEY) ? root.getUUID(BAG_ID_KEY) : null;
|
||||
}
|
||||
|
||||
public static UUID ensureBagId(ItemStack stack) {
|
||||
UUID existing = getBagId(stack);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
UUID created = UUID.randomUUID();
|
||||
CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> {
|
||||
CompoundTag root = tag.contains(ROOT_KEY, 10) ? tag.getCompound(ROOT_KEY) : new CompoundTag();
|
||||
root.putUUID(BAG_ID_KEY, created);
|
||||
tag.put(ROOT_KEY, root);
|
||||
});
|
||||
return created;
|
||||
}
|
||||
}
|
||||
100
src/main/java/com/trunksbomb/bagtabs/client/BagNamerScreen.java
Normal file
100
src/main/java/com/trunksbomb/bagtabs/client/BagNamerScreen.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package com.trunksbomb.bagtabs.client;
|
||||
|
||||
import com.trunksbomb.bagtabs.BagTabs;
|
||||
import com.trunksbomb.bagtabs.menu.BagNamerMenu;
|
||||
import com.trunksbomb.bagtabs.network.RenameBagPayload;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
public class BagNamerScreen extends AbstractContainerScreen<BagNamerMenu> {
|
||||
private static final ResourceLocation CONTAINER_BACKGROUND = BagTabs.id("textures/gui/bag_namer.png");
|
||||
private static final int TEXTURE_WIDTH = 176;
|
||||
private static final int TEXTURE_HEIGHT = 165;
|
||||
private EditBox nameBox;
|
||||
private Button renameButton;
|
||||
|
||||
public BagNamerScreen(BagNamerMenu menu, Inventory playerInventory, Component title) {
|
||||
super(menu, playerInventory, title);
|
||||
this.imageHeight = 165;
|
||||
this.inventoryLabelY = this.imageHeight - 94;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
this.nameBox = new EditBox(this.font, this.leftPos + 21, this.topPos + 15, 134, 16, BagTabs.translation("gui.bag_namer.name"));
|
||||
this.nameBox.setMaxLength(48);
|
||||
this.nameBox.setCanLoseFocus(true);
|
||||
this.nameBox.setHint(BagTabs.translation("gui.bag_namer.placeholder"));
|
||||
this.addRenderableWidget(this.nameBox);
|
||||
|
||||
this.renameButton = this.addRenderableWidget(Button.builder(BagTabs.translation("gui.bag_namer.rename"), button -> rename())
|
||||
.bounds(this.leftPos + 64, this.topPos + 44, 48, 20)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void containerTick() {
|
||||
super.containerTick();
|
||||
this.renameButton.active = this.menu.getSlot(0).hasItem() && !this.menu.getSlot(1).hasItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (this.nameBox.keyPressed(keyCode, scanCode, modifiers) || this.nameBox.canConsumeInput()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyCode == 257 || keyCode == 335) {
|
||||
rename();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char codePoint, int modifiers) {
|
||||
return this.nameBox.charTyped(codePoint, modifiers) || super.charTyped(codePoint, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (this.nameBox.mouseClicked(mouseX, mouseY, button)) {
|
||||
this.setFocused(this.nameBox);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
||||
super.render(guiGraphics, mouseX, mouseY, partialTick);
|
||||
this.renderTooltip(guiGraphics, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) {
|
||||
guiGraphics.drawString(this.font, this.playerInventoryTitle, this.inventoryLabelX, this.inventoryLabelY, 0x404040, false);
|
||||
guiGraphics.drawString(this.font, BagTabs.translation("gui.bag_namer.name"), 21, 5, 0x404040, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY) {
|
||||
int left = this.leftPos;
|
||||
int top = this.topPos;
|
||||
guiGraphics.blit(CONTAINER_BACKGROUND, left, top, 0, 0, this.imageWidth, this.imageHeight, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||
}
|
||||
|
||||
private void rename() {
|
||||
PacketDistributor.sendToServer(new RenameBagPayload(this.nameBox.getValue()));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.trunksbomb.bagtabs.item;
|
||||
|
||||
import com.trunksbomb.bagtabs.BagTabs;
|
||||
import com.trunksbomb.bagtabs.bag.BagContainer;
|
||||
import com.trunksbomb.bagtabs.bag.BagIdentityData;
|
||||
import com.trunksbomb.bagtabs.bag.InventoryBag;
|
||||
import com.trunksbomb.bagtabs.menu.BagMenu;
|
||||
import java.util.ArrayList;
|
||||
@@ -43,12 +44,14 @@ public class BagItem extends Item implements InventoryBag {
|
||||
public static ItemStack createColoredStack(int color) {
|
||||
ItemStack stack = BagTabs.BAG.get().getDefaultInstance();
|
||||
stack.set(DataComponents.DYED_COLOR, new DyedItemColor(color, true));
|
||||
BagIdentityData.ensureBagId(stack);
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) {
|
||||
ItemStack stack = player.getItemInHand(usedHand);
|
||||
BagIdentityData.ensureBagId(stack);
|
||||
if (!level.isClientSide && player instanceof ServerPlayer serverPlayer) {
|
||||
this.openFromInventory(serverPlayer, usedHand == InteractionHand.MAIN_HAND ? serverPlayer.getInventory().selected : Inventory.SLOT_OFFHAND);
|
||||
}
|
||||
@@ -63,6 +66,8 @@ public class BagItem extends Item implements InventoryBag {
|
||||
return;
|
||||
}
|
||||
|
||||
BagIdentityData.ensureBagId(stack);
|
||||
|
||||
Component title = stack.getHoverName();
|
||||
OptionalInt windowId = player.openMenu(
|
||||
new SimpleMenuProvider((containerId, playerInventory, ignoredPlayer) -> new BagMenu(
|
||||
|
||||
33
src/main/java/com/trunksbomb/bagtabs/item/BagNamerItem.java
Normal file
33
src/main/java/com/trunksbomb/bagtabs/item/BagNamerItem.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.trunksbomb.bagtabs.item;
|
||||
|
||||
import com.trunksbomb.bagtabs.BagTabs;
|
||||
import com.trunksbomb.bagtabs.menu.BagNamerMenu;
|
||||
import java.util.OptionalInt;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public class BagNamerItem extends Item {
|
||||
public BagNamerItem(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) {
|
||||
ItemStack stack = player.getItemInHand(usedHand);
|
||||
if (!level.isClientSide && player instanceof ServerPlayer serverPlayer) {
|
||||
OptionalInt ignored = serverPlayer.openMenu(new SimpleMenuProvider(
|
||||
(containerId, inventory, ignoredPlayer) -> new BagNamerMenu(containerId, inventory),
|
||||
Component.translatable("container." + BagTabs.MODID + ".bag_namer")
|
||||
));
|
||||
}
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(stack, level.isClientSide);
|
||||
}
|
||||
}
|
||||
136
src/main/java/com/trunksbomb/bagtabs/menu/BagNamerMenu.java
Normal file
136
src/main/java/com/trunksbomb/bagtabs/menu/BagNamerMenu.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package com.trunksbomb.bagtabs.menu;
|
||||
|
||||
import com.trunksbomb.bagtabs.BagTabs;
|
||||
import com.trunksbomb.bagtabs.bag.BagCompat;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public class BagNamerMenu extends AbstractContainerMenu {
|
||||
private static final int INPUT_SLOT = 0;
|
||||
private static final int OUTPUT_SLOT = 1;
|
||||
private static final int PLAYER_INV_START = 2;
|
||||
private static final int PLAYER_INV_END = 29;
|
||||
private static final int HOTBAR_START = 29;
|
||||
private static final int HOTBAR_END = 38;
|
||||
|
||||
private final SimpleContainer renameContainer;
|
||||
|
||||
public static BagNamerMenu fromNetwork(int containerId, Inventory playerInventory, RegistryFriendlyByteBuf extraData) {
|
||||
return new BagNamerMenu(containerId, playerInventory);
|
||||
}
|
||||
|
||||
public BagNamerMenu(int containerId, Inventory playerInventory) {
|
||||
this(containerId, playerInventory, new SimpleContainer(2));
|
||||
}
|
||||
|
||||
private BagNamerMenu(int containerId, Inventory playerInventory, SimpleContainer renameContainer) {
|
||||
super(BagTabs.BAG_NAMER_MENU.get(), containerId);
|
||||
checkContainerSize(renameContainer, 2);
|
||||
this.renameContainer = renameContainer;
|
||||
renameContainer.startOpen(playerInventory.player);
|
||||
|
||||
this.addSlot(new Slot(renameContainer, INPUT_SLOT, 44, 46) {
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return BagCompat.canName(stack);
|
||||
}
|
||||
});
|
||||
this.addSlot(new Slot(renameContainer, OUTPUT_SLOT, 116, 46) {
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
for (int row = 0; row < 3; row++) {
|
||||
for (int column = 0; column < 9; column++) {
|
||||
int slotIndex = column + row * 9 + 9;
|
||||
this.addSlot(new Slot(playerInventory, slotIndex, 8 + column * 18, 83 + row * 18));
|
||||
}
|
||||
}
|
||||
|
||||
for (int column = 0; column < 9; column++) {
|
||||
this.addSlot(new Slot(playerInventory, column, 8 + column * 18, 141));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean renameInput(String requestedName) {
|
||||
ItemStack input = this.renameContainer.getItem(INPUT_SLOT);
|
||||
ItemStack output = this.renameContainer.getItem(OUTPUT_SLOT);
|
||||
if (input.isEmpty() || !output.isEmpty() || !BagCompat.canName(input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemStack renamed = input.copy();
|
||||
String name = requestedName.trim();
|
||||
if (name.isEmpty()) {
|
||||
renamed.remove(DataComponents.CUSTOM_NAME);
|
||||
} else {
|
||||
renamed.set(DataComponents.CUSTOM_NAME, Component.literal(name));
|
||||
}
|
||||
|
||||
this.renameContainer.setItem(OUTPUT_SLOT, renamed);
|
||||
this.renameContainer.setItem(INPUT_SLOT, ItemStack.EMPTY);
|
||||
this.broadcastChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack quickMoveStack(Player player, int index) {
|
||||
Slot slot = this.slots.get(index);
|
||||
if (slot == null || !slot.hasItem()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
ItemStack stack = slot.getItem();
|
||||
ItemStack copied = stack.copy();
|
||||
|
||||
if (index == OUTPUT_SLOT) {
|
||||
if (!this.moveItemStackTo(stack, PLAYER_INV_START, this.slots.size(), true)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
slot.onQuickCraft(stack, copied);
|
||||
} else if (index == INPUT_SLOT) {
|
||||
if (!this.moveItemStackTo(stack, PLAYER_INV_START, this.slots.size(), true)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else if (BagCompat.canName(stack)) {
|
||||
if (!this.moveItemStackTo(stack, INPUT_SLOT, INPUT_SLOT + 1, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else if (index < HOTBAR_START) {
|
||||
if (!this.moveItemStackTo(stack, HOTBAR_START, HOTBAR_END, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else if (!this.moveItemStackTo(stack, PLAYER_INV_START, HOTBAR_START, false)) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
slot.setByPlayer(ItemStack.EMPTY);
|
||||
} else {
|
||||
slot.setChanged();
|
||||
}
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Player player) {
|
||||
super.removed(player);
|
||||
this.clearContainer(player, this.renameContainer);
|
||||
this.renameContainer.stopOpen(player);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ public final class BagTabsNetwork {
|
||||
registrar.playToServer(OpenBagPayload.TYPE, OpenBagPayload.STREAM_CODEC, OpenBagPayload::handle);
|
||||
registrar.playToServer(InsertIntoBagPayload.TYPE, InsertIntoBagPayload.STREAM_CODEC, InsertIntoBagPayload::handle);
|
||||
registrar.playToServer(QueryInsertTargetsPayload.TYPE, QueryInsertTargetsPayload.STREAM_CODEC, QueryInsertTargetsPayload::handle);
|
||||
registrar.playToServer(RenameBagPayload.TYPE, RenameBagPayload.STREAM_CODEC, RenameBagPayload::handle);
|
||||
registrar.playToClient(InsertTargetsPayload.TYPE, InsertTargetsPayload.STREAM_CODEC, InsertTargetsPayload::handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.trunksbomb.bagtabs.network;
|
||||
|
||||
import com.trunksbomb.bagtabs.BagTabs;
|
||||
import com.trunksbomb.bagtabs.menu.BagNamerMenu;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
|
||||
public record RenameBagPayload(String name) implements CustomPacketPayload {
|
||||
public static final Type<RenameBagPayload> TYPE = new Type<>(BagTabs.id("rename_bag"));
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, RenameBagPayload> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.stringUtf8(48),
|
||||
RenameBagPayload::name,
|
||||
RenameBagPayload::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public Type<RenameBagPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public static void handle(RenameBagPayload payload, IPayloadContext context) {
|
||||
if (!(context.player() instanceof ServerPlayer serverPlayer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (serverPlayer.containerMenu instanceof BagNamerMenu bagNamerMenu) {
|
||||
bagNamerMenu.renameInput(payload.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"item.bagtabs.bag": "Traveler's Bag",
|
||||
"item.bagtabs.bag_namer": "Bag Namer",
|
||||
"itemGroup.bagtabs": "Bag Tabs",
|
||||
"container.bagtabs.bag": "Bag",
|
||||
"bagtabs.tooltip.click_to_open": "Open from your inventory tabs"
|
||||
"container.bagtabs.bag_namer": "Bag Namer",
|
||||
"bagtabs.tooltip.click_to_open": "Open from your inventory tabs",
|
||||
"bagtabs.gui.bag_namer.name": "New Name",
|
||||
"bagtabs.gui.bag_namer.placeholder": "Leave blank to clear",
|
||||
"bagtabs.gui.bag_namer.rename": "Rename"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "bagtabs:item/bag_namer"
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/assets/bagtabs/textures/gui/bag_namer.png
Normal file
BIN
src/main/resources/assets/bagtabs/textures/gui/bag_namer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 790 B |
BIN
src/main/resources/assets/bagtabs/textures/item/bag_namer.png
Normal file
BIN
src/main/resources/assets/bagtabs/textures/item/bag_namer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 454 B |
28
src/main/resources/data/bagtabs/recipes/bag_namer.json
Normal file
28
src/main/resources/data/bagtabs/recipes/bag_namer.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
" PI",
|
||||
" NB",
|
||||
" G"
|
||||
],
|
||||
"key": {
|
||||
"P": {
|
||||
"item": "minecraft:paper"
|
||||
},
|
||||
"I": {
|
||||
"item": "minecraft:ink_sac"
|
||||
},
|
||||
"N": {
|
||||
"item": "minecraft:name_tag"
|
||||
},
|
||||
"B": {
|
||||
"item": "bagtabs:bag"
|
||||
},
|
||||
"G": {
|
||||
"item": "minecraft:gold_nugget"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"id": "bagtabs:bag_namer"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user