Skip to content

Commit

Permalink
More progress
Browse files Browse the repository at this point in the history
ReclipseTheOne committed Nov 13, 2024
1 parent 8eac042 commit 2455b89
Showing 12 changed files with 407 additions and 26 deletions.
21 changes: 21 additions & 0 deletions src/main/java/com/portingdeadmods/bagz/api/BagzCapabilities.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.portingdeadmods.bagz.api;

import com.portingdeadmods.bagz.Bagz;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.neoforged.neoforge.capabilities.CapabilityRegistry;
import net.neoforged.neoforge.capabilities.EntityCapability;

public class BagzCapabilities {
public static final EntityCapability<IPersonalBagProvider, Void> PERS_BAG_CAPABILITY = EntityCapability.create(
ResourceLocation.fromNamespaceAndPath(Bagz.MODID, "personal_bag_capability"),
IPersonalBagProvider.class,
Void.class
);

public static final EntityCapability<IBagProvider, Void> BAG_CAPABILITY = EntityCapability.create(
ResourceLocation.fromNamespaceAndPath(Bagz.MODID, "bag_capability"),
IBagProvider.class,
Void.class
);
}
29 changes: 29 additions & 0 deletions src/main/java/com/portingdeadmods/bagz/api/IBagProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.portingdeadmods.bagz.api;

import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.DyeColor;
import net.neoforged.neoforge.common.util.INBTSerializable;
import net.neoforged.neoforge.items.IItemHandler;
import org.jetbrains.annotations.NotNull;

public interface IBagProvider extends INBTSerializable<CompoundTag> {
/**
* Note: modifying this clientside is not advised
*
* @param color The bag color to acquire
*
* @return The inventory representing this bag
*/
@NotNull
IItemHandler getBag(@NotNull DyeColor color);

/**
* Syncs the bag inventory associated with this color to the player provided (usually the owner of this capability instance)
*
* @param color The bag color to sync. If null, syncs every color.
* @param player The player to sync the bags to.
*/
void sync(DyeColor color, @NotNull ServerPlayer player);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.portingdeadmods.bagz.api;

import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.DyeColor;
import net.neoforged.neoforge.common.util.INBTSerializable;
import net.neoforged.neoforge.items.IItemHandler;
import org.jetbrains.annotations.NotNull;

public interface IPersonalBagProvider extends INBTSerializable<CompoundTag> {
@NotNull IItemHandler getBag(@NotNull int color);

/**
* Note: modifying this clientside is not advised
*
* @param color The bag color (hex code) to acquire
*
* @return The inventory representing this alchemical bag
*/
@NotNull
IItemHandler getBag(@NotNull Integer color);

/**
* Syncs the bag inventory associated with this color to the player provided (usually the owner of this capability instance)
*
* @param color The bag color to sync. If null, syncs every color.
* @param player The player to sync the bags to.
*/
void sync(int color, @NotNull ServerPlayer player);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.portingdeadmods.bagz.content.items;

import com.portingdeadmods.bagz.api.BagzCapabilities;
import com.portingdeadmods.bagz.api.IBagProvider;
import com.portingdeadmods.bagz.networking.SyncBagzPayload;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.DyeColor;
import net.neoforged.neoforge.capabilities.EntityCapability;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.ItemStackHandler;
import net.neoforged.neoforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnknownNullability;

import java.util.EnumMap;
import java.util.Map;

public final class BagImplementation {

public static IBagProvider getDefault() {
return new DefaultImpl();
}

public static class DefaultImpl implements IBagProvider {

private final Map<DyeColor, ItemStackHandler> inventories = new EnumMap<>(DyeColor.class);

@Override
public @NotNull IItemHandler getBag(@NotNull DyeColor color) {
if (!inventories.containsKey(color)) {
inventories.put(color, new ItemStackHandler(9 * 15));
}
return inventories.get(color);
}

@Override
public void sync(DyeColor color, @NotNull ServerPlayer player) {
PacketDistributor.sendToPlayer(player, new SyncBagzPayload(writeNBT(player.level().registryAccess(), color)));
}

public CompoundTag writeNBT(HolderLookup.Provider provider, DyeColor color) {
CompoundTag ret = new CompoundTag();
DyeColor[] colors = color == null ? DyeColor.values() : new DyeColor[]{color};
for (DyeColor c : colors) {
if (inventories.containsKey(c)) {
ret.put(c.getSerializedName(), inventories.get(c).serializeNBT(provider));
}
}
return ret;
}


@Override
public @UnknownNullability CompoundTag serializeNBT(HolderLookup.Provider provider) {
return writeNBT(provider, null);
}

@Override
public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
for (DyeColor e : DyeColor.values()) {
if (nbt.contains(e.getSerializedName())) {
ItemStackHandler inv = new ItemStackHandler(104);
inv.deserializeNBT(provider, nbt.getCompound(e.getSerializedName()));
inventories.put(e, inv);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -13,22 +13,24 @@
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.DyeColor;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;


public class BagItem extends Item implements MenuProvider {
public final String color;
public final DyeColor color;

public final BagContainer bagContainer;

public BagItem(String color) {
public BagItem(DyeColor color) {
super(new Properties()
.stacksTo(1)
);
this.color = color;
this.bagContainer = new BagContainer(color);
this.bagContainer = new BagContainer(color.getName());
}

@Override
@@ -40,13 +42,13 @@ public InteractionResultHolder<ItemStack> use(Level level, Player player, Intera

@Override
public Component getDisplayName() {
return Component.translatable(String.format("item.bagz.bag_%S", color));
return Component.translatable(String.format("item.bagz.bag_%S", color.getName()));
}

@Nullable
@Override
public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) {
switch(color) {
switch(color.getName()) {
case "red":
return new SimpleMenuProvider((id, inv, player1) -> new BagMenuColored.BagMenuRed(id, inv, bagContainer), getDisplayName()).createMenu(containerId, playerInventory, player);
case "green":
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.portingdeadmods.bagz.content.items;

import com.portingdeadmods.bagz.api.IPersonalBagProvider;
import com.portingdeadmods.bagz.networking.SyncBagzPayload;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.DyeColor;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.ItemStackHandler;
import net.neoforged.neoforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnknownNullability;

import java.util.HashMap;
import java.util.Map;

public final class PersonalBagImplementation {

public static IPersonalBagProvider getDefault() {
return new DefaultImpl();
}

public static class DefaultImpl implements IPersonalBagProvider {

private final Map<Integer, ItemStackHandler> inventories = new HashMap<Integer, ItemStackHandler>();

@Override
public @NotNull IItemHandler getBag(@NotNull int color) {
if (!inventories.containsKey(color)) {
inventories.put(color, new ItemStackHandler(9 * 15));
}
return inventories.get(color);
}

@Override
public void sync(int color, @NotNull ServerPlayer player) {
PacketDistributor.sendToPlayer(player, new SyncBagzPayload(writeNBT(player.level().registryAccess(), color)));
}

public CompoundTag writeNBT(HolderLookup.Provider provider, Integer color) {
CompoundTag ret = new CompoundTag();
DyeColor[] colors = color == null ? DyeColor.values() : new DyeColor[]{color};
for (DyeColor c : colors) {
if (inventories.containsKey(c)) {
ret.put(c.getSerializedName(), inventories.get(c).serializeNBT(provider));
}
}
return ret;
}


@Override
public @UnknownNullability CompoundTag serializeNBT(HolderLookup.Provider provider) {
return writeNBT(provider, null);
}

@Override
public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
for (DyeColor e : DyeColor.values()) {
if (nbt.contains(e.getSerializedName())) {
ItemStackHandler inv = new ItemStackHandler(104);
inv.deserializeNBT(provider, nbt.getCompound(e.getSerializedName()));
inventories.put(e, inv);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -26,9 +26,9 @@ public class PersonalBagItem extends Item implements MenuProvider {

public PersonalBagItem() {
super(new Properties()
.component(DataComponents.RED, (byte) 255)
.component(DataComponents.GREEN, (byte) 255)
.component(DataComponents.BLUE, (byte) 255)
.component(DataComponents.RED, (byte) 15)
.component(DataComponents.GREEN, (byte) 15)
.component(DataComponents.BLUE, (byte) 15)
.stacksTo(1)
);
}
@@ -43,10 +43,10 @@ public InteractionResultHolder<ItemStack> use(Level level, Player player, Intera
Byte blue = dataComponents.get(DataComponents.BLUE.get());

if (red != null && green != null && blue != null) {
color = (red << 16) | (green << 8) | blue;
color = (red << 8) | (green << 4) | blue;
} else {
Bagz.LOGGER.error("Color data not found in personal bag, defaulting to white frequency");
color = 0xFFFFFF;
color = 0xFFF;
}

bagContainer = new BagContainer(Integer.toHexString(color));
@@ -62,6 +62,11 @@ public InteractionResultHolder<ItemStack> use(Level level, Player player, Intera
}
}

// 12 bit color code
public Integer getColor() {
return color;
}

@Override
public Component getDisplayName() {
return Component.translatable("item.bagz.personal_bag");
15 changes: 15 additions & 0 deletions src/main/java/com/portingdeadmods/bagz/content/menus/BagSlot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.portingdeadmods.bagz.content.menus;

import net.minecraft.world.Container;
import net.minecraft.world.inventory.Slot;

public class BagSlot extends Slot {
public BagSlot(Container container, int index, int x, int y) {
super(container, index, x, y);
}

@Override
public boolean setChanged(ItemStack stack) {
return false;
}
}
72 changes: 72 additions & 0 deletions src/main/java/com/portingdeadmods/bagz/data/DataAttachments.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.portingdeadmods.bagz.data;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.portingdeadmods.bagz.Bagz;
import net.minecraft.client.Minecraft;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.items.ItemStackHandler;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;

import java.util.*;
import java.util.function.Supplier;

public class DataAttachments {

public static final DeferredRegister<AttachmentType<?>> ATTACHMENTS = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, Bagz.MODID);

// TODO: Codecs
public static final Codec<DyeColor> DYE_COLOR_CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.INT.fieldOf("color").forGetter(DyeColor::getId)
).apply(instance, DyeColor::byId));
public static final Codec<ItemStackHandler> ITEM_STACK_HANDLER_CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.INT.fieldOf("size").forGetter(ItemStackHandler::getSlots),
Codec.list(CompoundTag.CODEC).fieldOf("items").forGetter(handler -> {
List<CompoundTag> tags = new ArrayList<>();
for (int i = 0; i < handler.getSlots(); i++) {
ItemStack stack = handler.getStackInSlot(i);
if (!stack.isEmpty()) {
CompoundTag tag = new CompoundTag();
tag.putInt("Slot", i);
stack.save(Minecraft.getInstance().level.registryAccess(), tag);
tags.add(tag);
}
}
return tags;
})
).apply(instance, (size, items) -> {
ItemStackHandler handler = new ItemStackHandler(size);
for (CompoundTag tag : items) {
int slot = tag.getInt("Slot");
if (slot >= 0 && slot < size) {
ItemStack stack = ItemStack.parseOptional(Minecraft.getInstance().level.registryAccess(), tag);
handler.setStackInSlot(slot, stack);
}
}
return handler;
}));

public static final Codec<Map<DyeColor, ItemStackHandler>> BAG_INVENTORY_MAP_CODEC =
Codec.unboundedMap(DYE_COLOR_CODEC, ITEM_STACK_HANDLER_CODEC);

public static final Codec<Map<Integer, ItemStackHandler>> PERSONAL_BAG_INVENTORY_MAP_CODEC =
Codec.unboundedMap(Codec.INT, ITEM_STACK_HANDLER_CODEC);


public static final Supplier<AttachmentType<Map<DyeColor, ItemStackHandler>>> BAG_ATTACHMENT = ATTACHMENTS.register(
"bag_attachment", () -> AttachmentType.<Map<DyeColor, ItemStackHandler>> builder(Collections::emptyMap)
.serialize(BAG_INVENTORY_MAP_CODEC).copyOnDeath().build()
);

public static final Supplier<AttachmentType<Map<Integer, ItemStackHandler>>> PERSONAL_BAG_ATTACHMENT = ATTACHMENTS.register(
"personal_bag_attachment", () -> AttachmentType.<Map<Integer, ItemStackHandler>> builder(Collections::emptyMap)
.serialize(PERSONAL_BAG_INVENTORY_MAP_CODEC).copyOnDeath().build()
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.portingdeadmods.bagz.networking;

import com.portingdeadmods.bagz.Bagz;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;


@EventBusSubscriber(modid = Bagz.MODID, bus = EventBusSubscriber.Bus.MOD)
public class NetworkEvents {
@SubscribeEvent
public static void registerPayloads(final RegisterPayloadHandlersEvent event) {
final PayloadRegistrar registrar = event.registrar(Bagz.MODID);
registrar.playToClient(
SyncBagzPayload.TYPE,
SyncBagzPayload.STREAM_CODEC,
SyncBagzPayload::syncBagzAction
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.portingdeadmods.bagz.networking;

import com.portingdeadmods.bagz.Bagz;
import com.portingdeadmods.bagz.api.BagzCapabilities;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
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.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.network.handling.IPayloadContext;

public record SyncBagzPayload (CompoundTag nbt) implements CustomPacketPayload {
public static final Type<SyncBagzPayload> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(Bagz.MODID, "sync_bagz_payload"));

public static final StreamCodec<RegistryFriendlyByteBuf, SyncBagzPayload> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.COMPOUND_TAG,
SyncBagzPayload::nbt,
SyncBagzPayload::new
);

@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}

public static void syncBagzAction(SyncBagzPayload payload, IPayloadContext context) {
context.enqueueWork(() -> {
Player player = context.player();
Level level = player.level();
RegistryAccess registryAccess = level.registryAccess();

if (player.getCapability(BagzCapabilities.BAG_CAPABILITY) != null) {
player.getCapability(BagzCapabilities.BAG_CAPABILITY).deserializeNBT(registryAccess, payload.nbt);
}
});
}
}
33 changes: 17 additions & 16 deletions src/main/java/com/portingdeadmods/bagz/registries/BagzItems.java
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
import com.portingdeadmods.bagz.content.items.PersonalBagItem;
import com.portingdeadmods.bagz.content.items.SocketedEnderEyeItem;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.neoforged.neoforge.registries.DeferredItem;
@@ -20,22 +21,22 @@ public class BagzItems {
public static final List<ItemLike> CREATIVE_TAB_ITEMS = new ArrayList<>();
public static final List<Supplier<BlockItem>> BLOCK_ITEMS = new ArrayList<>();

public static final DeferredItem<BagItem> BAG_RED = registerItem("bag_red", () -> new BagItem("red"));
public static final DeferredItem<BagItem> BAG_GREEN = registerItem("bag_green", () -> new BagItem("green"));
public static final DeferredItem<BagItem> BAG_BLUE = registerItem("bag_blue", () -> new BagItem("blue"));
public static final DeferredItem<BagItem> BAG_YELLOW = registerItem("bag_yellow", () -> new BagItem("yellow"));
public static final DeferredItem<BagItem> BAG_PURPLE = registerItem("bag_purple", () -> new BagItem("purple"));
public static final DeferredItem<BagItem> BAG_ORANGE = registerItem("bag_orange", () -> new BagItem("orange"));
public static final DeferredItem<BagItem> BAG_BLACK = registerItem("bag_black", () -> new BagItem("black"));
public static final DeferredItem<BagItem> BAG_WHITE = registerItem("bag_white", () -> new BagItem("white"));
public static final DeferredItem<BagItem> BAG_PINK = registerItem("bag_pink", () -> new BagItem("pink"));
public static final DeferredItem<BagItem> BAG_BROWN = registerItem("bag_brown", () -> new BagItem("brown"));
public static final DeferredItem<BagItem> BAG_GRAY = registerItem("bag_gray", () -> new BagItem("gray"));
public static final DeferredItem<BagItem> BAG_LIGHT_GRAY = registerItem("bag_light_gray", () -> new BagItem("light_gray"));
public static final DeferredItem<BagItem> BAG_CYAN = registerItem("bag_cyan", () -> new BagItem("cyan"));
public static final DeferredItem<BagItem> BAG_LIGHT_BLUE = registerItem("bag_light_blue", () -> new BagItem("light_blue"));
public static final DeferredItem<BagItem> BAG_MAGENTA = registerItem("bag_magenta", () -> new BagItem("magenta"));
public static final DeferredItem<BagItem> BAG_LIME = registerItem("bag_lime", () -> new BagItem("lime"));
public static final DeferredItem<BagItem> BAG_RED = registerItem("bag_red", () -> new BagItem(DyeColor.RED));
public static final DeferredItem<BagItem> BAG_GREEN = registerItem("bag_green", () -> new BagItem(DyeColor.GREEN));
public static final DeferredItem<BagItem> BAG_BLUE = registerItem("bag_blue", () -> new BagItem(DyeColor.BLUE));
public static final DeferredItem<BagItem> BAG_YELLOW = registerItem("bag_yellow", () -> new BagItem(DyeColor.YELLOW));
public static final DeferredItem<BagItem> BAG_PURPLE = registerItem("bag_purple", () -> new BagItem(DyeColor.PURPLE));
public static final DeferredItem<BagItem> BAG_ORANGE = registerItem("bag_orange", () -> new BagItem(DyeColor.ORANGE));
public static final DeferredItem<BagItem> BAG_BLACK = registerItem("bag_black", () -> new BagItem(DyeColor.BLACK));
public static final DeferredItem<BagItem> BAG_WHITE = registerItem("bag_white", () -> new BagItem(DyeColor.WHITE));
public static final DeferredItem<BagItem> BAG_PINK = registerItem("bag_pink", () -> new BagItem(DyeColor.PINK));
public static final DeferredItem<BagItem> BAG_BROWN = registerItem("bag_brown", () -> new BagItem(DyeColor.BROWN));
public static final DeferredItem<BagItem> BAG_GRAY = registerItem("bag_gray", () -> new BagItem(DyeColor.GRAY));
public static final DeferredItem<BagItem> BAG_LIGHT_GRAY = registerItem("bag_light_gray", () -> new BagItem(DyeColor.LIGHT_GRAY));
public static final DeferredItem<BagItem> BAG_CYAN = registerItem("bag_cyan", () -> new BagItem(DyeColor.CYAN));
public static final DeferredItem<BagItem> BAG_LIGHT_BLUE = registerItem("bag_light_blue", () -> new BagItem(DyeColor.LIGHT_BLUE));
public static final DeferredItem<BagItem> BAG_MAGENTA = registerItem("bag_magenta", () -> new BagItem(DyeColor.MAGENTA));
public static final DeferredItem<BagItem> BAG_LIME = registerItem("bag_lime", () -> new BagItem(DyeColor.LIME));

public static final DeferredItem<PersonalBagItem> PERSONAL_BAG = registerItem("personal_bag", PersonalBagItem::new);

0 comments on commit 2455b89

Please sign in to comment.