From 2e43b831af08beaed320f74cd9a1e537397135d3 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Wed, 20 Nov 2024 19:21:03 +0100 Subject: Add item sharing --- .../funnyteleporters/ColouredChestBlockEntity.java | 25 +++---- .../nea/funnyteleporters/ColouredChestState.java | 83 ++++++++++++++++++++++ .../moe/nea/funnyteleporters/FunnyRegistry.java | 5 +- 3 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 src/main/java/moe/nea/funnyteleporters/ColouredChestState.java diff --git a/src/main/java/moe/nea/funnyteleporters/ColouredChestBlockEntity.java b/src/main/java/moe/nea/funnyteleporters/ColouredChestBlockEntity.java index ba09c5e..9270717 100644 --- a/src/main/java/moe/nea/funnyteleporters/ColouredChestBlockEntity.java +++ b/src/main/java/moe/nea/funnyteleporters/ColouredChestBlockEntity.java @@ -14,6 +14,7 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtOps; import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.DyeColor; import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.math.BlockPos; @@ -21,8 +22,6 @@ import net.minecraft.util.math.BlockPos; import java.util.List; public class ColouredChestBlockEntity extends BlockEntity implements Inventory { - private DefaultedList inventory = DefaultedList.ofSize(size(), ItemStack.EMPTY); - public record ExtraData( List frequency ) { @@ -42,7 +41,6 @@ public class ColouredChestBlockEntity extends BlockEntity implements Inventory { @Override protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { super.writeNbt(nbt, registryLookup); - Inventories.writeNbt(nbt, inventory, registryLookup); var result = ExtraData.CODEC.encodeStart(NbtOps.INSTANCE, extra); if (result.hasResultOrPartial()) { nbt.put("extra", result.getPartialOrThrow()); @@ -51,13 +49,18 @@ public class ColouredChestBlockEntity extends BlockEntity implements Inventory { ExtraData extra = new ExtraData(List.of(DyeColor.BLUE, DyeColor.BLUE, DyeColor.BLUE)); + public DefaultedList getInventory() { + assert world instanceof ServerWorld; + return ColouredChestState.getServerState(world.getServer()).getDelegate(extra.frequency()); + } + public int size() { - return 27; + return getInventory().size(); } @Override public boolean isEmpty() { - for (ItemStack itemStack : inventory) { + for (ItemStack itemStack : getInventory()) { if (!itemStack.isEmpty()) return false; } return true; @@ -66,13 +69,13 @@ public class ColouredChestBlockEntity extends BlockEntity implements Inventory { @Override public ItemStack getStack(int slot) { if (0 <= slot && slot < size()) - return inventory.get(slot); + return getInventory().get(slot); return ItemStack.EMPTY; } @Override public ItemStack removeStack(int slot, int amount) { - ItemStack itemStack = Inventories.splitStack(this.inventory, slot, amount); + ItemStack itemStack = Inventories.splitStack(this.getInventory(), slot, amount); if (!itemStack.isEmpty()) { markDirty(); } @@ -83,14 +86,14 @@ public class ColouredChestBlockEntity extends BlockEntity implements Inventory { @Override public ItemStack removeStack(int slot) { markDirty(); - return Inventories.removeStack(inventory, slot); + return Inventories.removeStack(getInventory(), slot); } @Override public void setStack(int slot, ItemStack stack) { if (0 <= slot && slot < size()) { markDirty(); - inventory.set(slot, stack); + getInventory().set(slot, stack); } } @@ -102,8 +105,6 @@ public class ColouredChestBlockEntity extends BlockEntity implements Inventory { @Override protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { super.readNbt(nbt, registryLookup); - inventory = DefaultedList.ofSize(size(), ItemStack.EMPTY); - Inventories.readNbt(nbt, inventory, registryLookup); if (nbt.contains("extra")) { var extra = ExtraData.CODEC.decode(NbtOps.INSTANCE, nbt.get("extra")); if (extra.hasResultOrPartial()) { @@ -115,7 +116,7 @@ public class ColouredChestBlockEntity extends BlockEntity implements Inventory { @Override public void clear() { markDirty(); - inventory.clear(); + getInventory().clear(); } public void openScreen(ServerPlayerEntity player) { diff --git a/src/main/java/moe/nea/funnyteleporters/ColouredChestState.java b/src/main/java/moe/nea/funnyteleporters/ColouredChestState.java new file mode 100644 index 0000000..9e18b16 --- /dev/null +++ b/src/main/java/moe/nea/funnyteleporters/ColouredChestState.java @@ -0,0 +1,83 @@ +package moe.nea.funnyteleporters; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.inventory.Inventories; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.DyeColor; +import net.minecraft.util.Identifier; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.util.dynamic.Codecs; +import net.minecraft.world.PersistentState; +import net.minecraft.world.World; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.StringJoiner; + +import static moe.nea.funnyteleporters.FunnyRegistry.MODID; + +public class ColouredChestState extends PersistentState { + + public Map, DefaultedList> inventories = new HashMap<>(); + + private static String joinDyeIndex(List dyes) { + StringJoiner j = new StringJoiner(";"); + dyes.forEach(it -> j.add(it.getName())); + return j.toString(); + } + + private static List splitDyeIndex(String string) { + List dyes = new ArrayList<>(3); + for (String s : string.split(";")) { + dyes.add(DyeColor.byName(s, DyeColor.BLACK)); + } + return Collections.unmodifiableList(dyes); + } + + public static final String ColouredChestInventories = "ColouredChestInventories"; + + @Override + public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + var compound = new NbtCompound(); + inventories.forEach((dyeColors, itemStacks) -> + compound.put(joinDyeIndex(dyeColors), Inventories.writeNbt(new NbtCompound(), itemStacks, registryLookup)) + ); + nbt.put(ColouredChestInventories, compound); + return nbt; + } + + public static ColouredChestState createFromNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { + var state = new ColouredChestState(); + var compound = nbt.getCompound(ColouredChestInventories); + compound.getKeys().forEach(key -> { + var list = DefaultedList.ofSize(27, ItemStack.EMPTY); + Inventories.readNbt(compound.getCompound(key), list, registryLookup); + state.inventories.put(splitDyeIndex(key), list); + } + ); + return state; + } + + public DefaultedList getDelegate(List dyeColors) { + return inventories.computeIfAbsent(dyeColors, ignored -> DefaultedList.ofSize(27, ItemStack.EMPTY)); + } + + public static Type TYPE = new Type<>(ColouredChestState::new, ColouredChestState::createFromNbt, null); + + public static Identifier identifier = Identifier.of(MODID, "coloured_chests"); + + public static ColouredChestState getServerState(MinecraftServer server) { + var persistentStateWorld = Objects.requireNonNull(server.getWorld(World.OVERWORLD)).getPersistentStateManager(); // Force all data saving to be done in the overworld + var state = persistentStateWorld.getOrCreate(TYPE, identifier.toString()); + state.markDirty(); // Always save + return state; + } +} diff --git a/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java b/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java index 0297425..87f2c4f 100644 --- a/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java +++ b/src/main/java/moe/nea/funnyteleporters/FunnyRegistry.java @@ -11,19 +11,20 @@ import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; public class FunnyRegistry { + public static final String MODID = "funny_teleporters"; public static Block COLOURED_CHEST = registerBlock("coloured_chest", new ColouredChestBlock(AbstractBlock.Settings.create())); public static BlockEntityType COLOURED_CHEST_ENTITY = registerBlockEntity("coloured_chest", BlockEntityType.Builder.create(ColouredChestBlockEntity::new, COLOURED_CHEST)); private static BlockEntityType registerBlockEntity(String name, BlockEntityType.Builder builder, Block... blocks) { return Registry.register(Registries.BLOCK_ENTITY_TYPE, - Identifier.of("funny_teleporters", name), + Identifier.of(MODID, name), builder.build() ); } private static T registerBlock(String name, T block) { - var id = Identifier.of("funny_teleporters", name); + var id = Identifier.of(MODID, name); Registry.register(Registries.ITEM, id, new BlockItem(block, new Item.Settings())); return Registry.register(Registries.BLOCK, id, block); } -- cgit