From fc5b5470b8bd48acd5e8e67a247fdced2825cb49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Ryb=C3=A1rsky?= Date: Sun, 20 Jul 2025 21:56:40 +0200 Subject: [PATCH] Update to 1.21.8 Start adding the display block(@sternschnaube) - still needs work Add the shift to move to last and first page(@sternschnaube) --- build.gradle | 2 +- gradle.properties | 16 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../brn/serverstorage/ServerStorage.java | 13 +- .../blockentities/DisplayBlockEntity.java | 92 +++++++++ .../HardDriveContainerBlockEntity.java | 20 +- .../InventoryInterfaceBlockEntity.java | 28 +-- .../RadioInterfaceBlockEntity.java | 47 ++--- .../StorageInterfaceBlockEntity.java | 28 +-- .../serverstorage/blocks/DisplayBlock.java | 175 ++++++++++++++++++ .../blocks/RadioInterfaceBlock.java | 2 +- .../items/WirelessTerminalItem.java | 4 +- .../lib/GenericPlayerListGui.java | 7 +- .../brn/serverstorage/lib/ItemGroups.java | 1 + .../brn/serverstorage/lib/PagedGui.java | 20 +- .../brn/serverstorage/lib/Session.java | 13 ++ .../screens/DisplayBlockMangementScreen.java | 42 +++++ .../serverstorage/screens/StorageScreen.java | 4 +- .../serverstorage/items/display_block.json | 6 + .../assets/serverstorage/lang/en_us.json | 6 + .../models/block/display_block.json | 12 ++ .../models/item/display_block.json | 3 + .../textures/block/display_front.png | Bin 0 -> 358 bytes .../advancement/cpu_unlocks.json | 3 +- .../loot_table/blocks/display_block.json | 19 ++ .../serverstorage/recipe/display_block.json | 21 +++ 26 files changed, 492 insertions(+), 94 deletions(-) create mode 100644 src/main/java/systems/brn/serverstorage/blockentities/DisplayBlockEntity.java create mode 100644 src/main/java/systems/brn/serverstorage/blocks/DisplayBlock.java create mode 100644 src/main/java/systems/brn/serverstorage/screens/DisplayBlockMangementScreen.java create mode 100644 src/main/resources/assets/serverstorage/items/display_block.json create mode 100644 src/main/resources/assets/serverstorage/models/block/display_block.json create mode 100644 src/main/resources/assets/serverstorage/models/item/display_block.json create mode 100644 src/main/resources/assets/serverstorage/textures/block/display_front.png create mode 100644 src/main/resources/data/serverstorage/loot_table/blocks/display_block.json create mode 100644 src/main/resources/data/serverstorage/recipe/display_block.json diff --git a/build.gradle b/build.gradle index 8b81917..6cc2a5d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.10-SNAPSHOT' + id 'fabric-loom' version '1.11-SNAPSHOT' id 'maven-publish' } diff --git a/gradle.properties b/gradle.properties index c481650..139ca5a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,19 +3,19 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html -minecraft_version=1.21.5 -yarn_mappings=1.21.5+build.1 -loader_version=0.16.13 +minecraft_version=1.21.8 +yarn_mappings=1.21.8+build.1 +loader_version=0.16.14 # Fabric API -fabric_version=0.120.0+1.21.5 +fabric_version=0.129.0+1.21.8 # Mod Properties -mod_version=3.3.6 +mod_version=3.3.7 maven_group=systems.brn archives_base_name=Serverstorage # Dependencies -polymer_version=0.12.3+1.21.5 -server_translations_api_version=2.5.0+1.21.5-rc1 -servergui_version=1.9.0+1.21.5 \ No newline at end of file +polymer_version=0.13.7+1.21.8 +server_translations_api_version=2.5.1+1.21.5 +servergui_version=1.10.2+1.21.8 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cea7a79..ca025c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/systems/brn/serverstorage/ServerStorage.java b/src/main/java/systems/brn/serverstorage/ServerStorage.java index 7cb477a..c065560 100644 --- a/src/main/java/systems/brn/serverstorage/ServerStorage.java +++ b/src/main/java/systems/brn/serverstorage/ServerStorage.java @@ -10,10 +10,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemGroups; import net.minecraft.util.Identifier; import net.minecraft.world.GameRules; -import systems.brn.serverstorage.blockentities.HardDriveContainerBlockEntity; -import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity; -import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; -import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity; +import systems.brn.serverstorage.blockentities.*; import systems.brn.serverstorage.blocks.*; import systems.brn.serverstorage.items.HardDriveItem; import systems.brn.serverstorage.items.SimpleBlockItem; @@ -38,6 +35,10 @@ public class ServerStorage implements ModInitializer { public static final String WIRELESS_TERMINAL_ID = "wireless_terminal"; + public static final String DISPLAY_BLOCK_MODEL_ID = "display_block"; + public static DisplayBlock DISPLAY_BLOCK; + public static BlockEntityType DISPLAY_BLOCK_ENTITY; + public static final String BUS_CONNECTOR_MODEL_ID = "bus_connector"; public static BusConnectorBlock BUS_CONNECTOR_BLOCK; @@ -99,6 +100,9 @@ public class ServerStorage implements ModInitializer { RadioInterfaceBlock.register(); SimpleBlockItem.register(RADIO_INTERFACE_BLOCK); + DisplayBlock.register(); + SimpleBlockItem.register(DISPLAY_BLOCK); + MATERIALS = SimpleItem.register("material", materialList, false, ItemGroups.INGREDIENTS); MODULES = SimpleItem.register("module", moduleList, false, ItemGroups.INGREDIENTS); @@ -111,6 +115,7 @@ public class ServerStorage implements ModInitializer { WIRELESS_TERMINAL = WirelessTerminalItem.register(); + UseItemCallback.EVENT.register(EventHandler::onItemUse); systems.brn.serverstorage.lib.ItemGroups.register(); diff --git a/src/main/java/systems/brn/serverstorage/blockentities/DisplayBlockEntity.java b/src/main/java/systems/brn/serverstorage/blockentities/DisplayBlockEntity.java new file mode 100644 index 0000000..f7eed92 --- /dev/null +++ b/src/main/java/systems/brn/serverstorage/blockentities/DisplayBlockEntity.java @@ -0,0 +1,92 @@ +package systems.brn.serverstorage.blockentities; + +import eu.pb4.polymer.virtualentity.api.ElementHolder; +import eu.pb4.polymer.virtualentity.api.attachment.ChunkAttachment; +import eu.pb4.polymer.virtualentity.api.elements.ItemDisplayElement; +import eu.pb4.polymer.virtualentity.api.elements.TextDisplayElement; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.storage.ReadView; +import net.minecraft.storage.WriteView; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.joml.Vector3f; +import systems.brn.serverstorage.lib.SortMode; +import systems.brn.serverstorage.lib.StorageNetwork; + +import static systems.brn.serverstorage.ServerStorage.DISPLAY_BLOCK_ENTITY; +import static systems.brn.serverstorage.blocks.DisplayBlock.FACING; + +public class DisplayBlockEntity extends BlockEntity { + public ItemStack targetItem; + public int itemCount; + public StorageNetwork network; + + private final ElementHolder holder = new ElementHolder(); + public final ItemDisplayElement itemElement = new ItemDisplayElement(); + public final TextDisplayElement textDisplayElement = new TextDisplayElement(); + + private boolean attached = false; + + public void reindexDrives() { + if (this.network != null) { + this.network.searchString = "*"; + this.network.reindexNetwork(); + } else { + this.network = new StorageNetwork(world, this.pos, SortMode.NUMERICALLY_REVERSE, "*", false); + } + } + + public DisplayBlockEntity(BlockPos pos, BlockState state) { + super(DISPLAY_BLOCK_ENTITY, pos, state); + targetItem = ItemStack.EMPTY; + itemCount = 1; + itemElement.setItem(targetItem); + textDisplayElement.setText(Text.of(String.valueOf(itemCount))); + // You can offset to make it float in front of the block + Vector3f vec = new Vector3f(0.5f, 0.5f, 0.5f); // mutable + + itemElement.setOffset(state.get(FACING).getDoubleVector().multiply(0.5)); // adjust Z based on block face + // assign to const interface + itemElement.setScale(vec); // Optional + holder.addElement(itemElement); + } + + @Override + protected void readData(ReadView view) { + super.readData(view); + this.targetItem = view.read("TargetItem", ItemStack.CODEC).orElse(ItemStack.EMPTY); + this.itemCount = view.getInt("TargetItemCount", 0); + reindexDrives(); + itemCount = network.itemStackMap.getOrDefault(targetItem, 0); + itemElement.setItem(targetItem); + textDisplayElement.setText(Text.of(String.valueOf(itemCount))); + } + + @Override + public void markRemoved() { + textDisplayElement.setText(Text.of("")); + itemElement.setItem(Items.AIR.getDefaultStack()); + super.markRemoved(); + } + + @Override + protected void writeData(WriteView view) { + super.writeData(view); + view.put("TargetItem", ItemStack.CODEC, targetItem); + view.putInt("TargetItemCount", itemCount); + } + + public static void tick(World world, BlockPos blockPos, BlockState blockState, T t) { + if (t instanceof DisplayBlockEntity displayBlockEntity) { + if (!displayBlockEntity.attached && !world.isClient()) { + displayBlockEntity.attached = true; + ChunkAttachment.ofTicking(displayBlockEntity.holder, (ServerWorld) world, blockPos.toCenterPos()); + } + } + } +} diff --git a/src/main/java/systems/brn/serverstorage/blockentities/HardDriveContainerBlockEntity.java b/src/main/java/systems/brn/serverstorage/blockentities/HardDriveContainerBlockEntity.java index 18fe979..3c013d9 100644 --- a/src/main/java/systems/brn/serverstorage/blockentities/HardDriveContainerBlockEntity.java +++ b/src/main/java/systems/brn/serverstorage/blockentities/HardDriveContainerBlockEntity.java @@ -5,9 +5,9 @@ import net.minecraft.block.entity.LootableContainerBlockEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventories; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.RegistryWrapper; import net.minecraft.screen.ScreenHandler; +import net.minecraft.storage.ReadView; +import net.minecraft.storage.WriteView; import net.minecraft.text.Text; import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.math.BlockPos; @@ -61,19 +61,19 @@ public class HardDriveContainerBlockEntity extends LootableContainerBlockEntity } @Override - protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { - super.readNbt(nbt, registryLookup); + protected void readData(ReadView view) { + super.readData(view); this.inventory = DefaultedList.ofSize(this.size(), ItemStack.EMPTY); - if (!this.readLootTable(nbt)) { - Inventories.readNbt(nbt, this.inventory, registryLookup); + if (!this.readLootTable(view)) { + Inventories.readData(view, this.inventory); } } @Override - protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { - super.writeNbt(nbt, registryLookup); - if (!this.writeLootTable(nbt)) { - Inventories.writeNbt(nbt, this.inventory, registryLookup); + protected void writeData(WriteView view) { + super.writeData(view); + if (!this.writeLootTable(view)) { + Inventories.writeData(view, this.inventory); } } diff --git a/src/main/java/systems/brn/serverstorage/blockentities/InventoryInterfaceBlockEntity.java b/src/main/java/systems/brn/serverstorage/blockentities/InventoryInterfaceBlockEntity.java index e044a91..e223d49 100644 --- a/src/main/java/systems/brn/serverstorage/blockentities/InventoryInterfaceBlockEntity.java +++ b/src/main/java/systems/brn/serverstorage/blockentities/InventoryInterfaceBlockEntity.java @@ -4,10 +4,10 @@ import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.world.ServerWorld; import net.minecraft.state.property.EnumProperty; +import net.minecraft.storage.ReadView; +import net.minecraft.storage.WriteView; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.World; @@ -65,23 +65,23 @@ public class InventoryInterfaceBlockEntity extends BlockEntity { // Serialize the BlockEntity @Override - public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) { + public void writeData(WriteView view) { // Save the current value of the number to the nbt - nbt.putBoolean("isOutput", isOutput); - nbt.putInt("direction", direction.getIndex()); - nbt.putInt("tickCounter", tickCounter); - nbt.putString("query", query); - super.writeNbt(nbt, wrapperLookup); + view.putBoolean("isOutput", isOutput); + view.putInt("direction", direction.getIndex()); + view.putInt("tickCounter", tickCounter); + view.putString("query", query); + super.writeData(view); } // Deserialize the BlockEntity @Override - public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) { - super.readNbt(nbt, wrapperLookup); - isOutput = nbt.getBoolean("isOutput", false); - direction = Direction.byIndex(nbt.getInt("direction", Direction.NORTH.getIndex())); - tickCounter = nbt.getInt("tickCounter", 0); - query = nbt.getString("query", ""); + public void readData(ReadView view) { + super.readData(view); + isOutput = view.getBoolean("isOutput", false); + direction = Direction.byIndex(view.getInt("direction", Direction.NORTH.getIndex())); + tickCounter = view.getInt("tickCounter", 0); + query = view.getString("query", ""); } private static int processIncomingInternal(ItemStack stack, int count, InventoryInterfaceBlockEntity blockEntity, Inventory targetedBlockEntityInventory) { diff --git a/src/main/java/systems/brn/serverstorage/blockentities/RadioInterfaceBlockEntity.java b/src/main/java/systems/brn/serverstorage/blockentities/RadioInterfaceBlockEntity.java index 25b6e8c..547ac72 100644 --- a/src/main/java/systems/brn/serverstorage/blockentities/RadioInterfaceBlockEntity.java +++ b/src/main/java/systems/brn/serverstorage/blockentities/RadioInterfaceBlockEntity.java @@ -6,11 +6,10 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventories; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtList; -import net.minecraft.registry.RegistryWrapper; import net.minecraft.screen.ScreenHandler; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.storage.ReadView; +import net.minecraft.storage.WriteView; import net.minecraft.text.Text; import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.math.BlockPos; @@ -18,11 +17,13 @@ import systems.brn.serverstorage.lib.Session; import systems.brn.serverstorage.screenhandlers.RadioInterfaceScreenHandler; import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.UUID; import static systems.brn.serverstorage.ServerStorage.ANTENNA_RANGES; import static systems.brn.serverstorage.ServerStorage.RADIO_INTERFACE_BLOCK_ENTITY; +import static systems.brn.serverstorage.lib.Session.SESSION_LIST_CODEC; public class RadioInterfaceBlockEntity extends LootableContainerBlockEntity { public DefaultedList inventory; @@ -96,40 +97,28 @@ public class RadioInterfaceBlockEntity extends LootableContainerBlockEntity { } @Override - protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { - super.readNbt(nbt, registryLookup); + protected void readData(ReadView view) { + super.readData(view); this.inventory = DefaultedList.ofSize(this.size(), ItemStack.EMPTY); - this.antennaRange = nbt.getInt("AntennaRange", 0); - if (!this.readLootTable(nbt)) { - Inventories.readNbt(nbt, this.inventory, registryLookup); + this.antennaRange = view.getInt("AntennaRange", 0); + if (!this.readLootTable(view)) { + Inventories.readData(view, this.inventory); } updateAntenna(); // Deserialize sessions list this.sessions.clear(); - NbtList sessionsNbtList = nbt.getListOrEmpty("Sessions"); // 10 = NbtCompound type - for (int i = 0; i < sessionsNbtList.size(); i++) { - Optional sessionNbt = sessionsNbtList.getCompound(i); - if (sessionNbt.isPresent()) { - Session session = Session.fromNbt(sessionNbt.get()); - if (session != null) { - this.sessions.add(session); - } - } - } + + Optional> sessionsTmp = view.read("Sessions", SESSION_LIST_CODEC); + sessionsTmp.ifPresent(this.sessions::addAll); } @Override - protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { - super.writeNbt(nbt, registryLookup); - nbt.putInt("AntennaRange", antennaRange); - if (!this.writeLootTable(nbt)) { - Inventories.writeNbt(nbt, this.inventory, registryLookup); + protected void writeData(WriteView view) { + super.writeData(view); + view.putInt("AntennaRange", antennaRange); + if (!this.writeLootTable(view)) { + Inventories.writeData(view, this.inventory); } - // Serialize sessions list - NbtList sessionsNbtList = new NbtList(); - for (Session session : sessions) { - sessionsNbtList.add(session.toNbt()); - } - nbt.put("Sessions", sessionsNbtList); + view.put("Sessions", SESSION_LIST_CODEC, sessions); } } diff --git a/src/main/java/systems/brn/serverstorage/blockentities/StorageInterfaceBlockEntity.java b/src/main/java/systems/brn/serverstorage/blockentities/StorageInterfaceBlockEntity.java index c6d57cf..8c3a993 100644 --- a/src/main/java/systems/brn/serverstorage/blockentities/StorageInterfaceBlockEntity.java +++ b/src/main/java/systems/brn/serverstorage/blockentities/StorageInterfaceBlockEntity.java @@ -2,8 +2,8 @@ package systems.brn.serverstorage.blockentities; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.registry.RegistryWrapper; +import net.minecraft.storage.ReadView; +import net.minecraft.storage.WriteView; import net.minecraft.util.math.BlockPos; import systems.brn.serverstorage.lib.SortMode; import systems.brn.serverstorage.lib.StorageNetwork; @@ -62,24 +62,24 @@ public class StorageInterfaceBlockEntity extends BlockEntity { // Serialize the BlockEntity @Override - public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) { + public void writeData(WriteView view) { // Save the current value of the number to the nbt - nbt.putInt("page", page); - nbt.putInt("sortAlphabetically", sortAlphabetically.getId()); - nbt.putString("searchString", searchString); - nbt.putBoolean("groupSimilar", groupSimilar); + view.putInt("page", page); + view.putInt("sortAlphabetically", sortAlphabetically.getId()); + view.putString("searchString", searchString); + view.putBoolean("groupSimilar", groupSimilar); - super.writeNbt(nbt, wrapperLookup); + super.writeData(view); } // Deserialize the BlockEntity @Override - public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) { - super.readNbt(nbt, wrapperLookup); + public void readData(ReadView view) { + super.readData(view); - page = nbt.getInt("page", 0); - sortAlphabetically = SortMode.fromId(nbt.getInt("sortAlphabetically", SortMode.NUMERICALLY_REVERSE.getId())); - searchString = nbt.getString("searchString", ""); - groupSimilar = nbt.getBoolean("groupSimilar", false); + page = view.getInt("page", 0); + sortAlphabetically = SortMode.fromId(view.getInt("sortAlphabetically", SortMode.NUMERICALLY_REVERSE.getId())); + searchString = view.getString("searchString", ""); + groupSimilar = view.getBoolean("groupSimilar", false); } } diff --git a/src/main/java/systems/brn/serverstorage/blocks/DisplayBlock.java b/src/main/java/systems/brn/serverstorage/blocks/DisplayBlock.java new file mode 100644 index 0000000..f82059d --- /dev/null +++ b/src/main/java/systems/brn/serverstorage/blocks/DisplayBlock.java @@ -0,0 +1,175 @@ +package systems.brn.serverstorage.blocks; + +import eu.pb4.polymer.blocks.api.PolymerTexturedBlock; +import eu.pb4.polymer.core.api.block.PolymerBlockUtils; +import net.fabricmc.fabric.api.event.player.AttackBlockCallback; +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; +import net.minecraft.block.*; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.EnumProperty; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import systems.brn.serverstorage.blockentities.DisplayBlockEntity; +import systems.brn.serverstorage.screens.DisplayBlockMangementScreen; +import xyz.nucleoid.packettweaker.PacketContext; + +import java.util.HashMap; + +import static systems.brn.serverstorage.ServerStorage.*; +import static systems.brn.serverstorage.lib.StorageOperations.*; + + +public class DisplayBlock extends ConnectedBlock implements PolymerTexturedBlock, BlockEntityProvider { + final Identifier identifier; + public static final EnumProperty FACING = FacingBlock.FACING; + private final HashMap rotations; + + public DisplayBlock(Settings settings, Identifier identifier) { + super(settings, Blocks.NOTE_BLOCK); + this.setDefaultState(this.stateManager.getDefaultState().with(FACING, Direction.NORTH)); + this.rotations = generateRotations(identifier); + this.identifier = identifier; + } + + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return this.getDefaultState().with(FACING, ctx.getPlayerLookDirection().getOpposite()); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder); + builder.add(FACING); + } + + @Override + public BlockState getPolymerBlockState(BlockState state, PacketContext packetContext) { + Direction direction = state.get(FACING); + return rotations.get(direction); + } + + public static void register() { + var modId = id(DISPLAY_BLOCK_MODEL_ID); + DISPLAY_BLOCK = Registry.register(Registries.BLOCK, modId, + new DisplayBlock(Settings.copy(Blocks.WHITE_WOOL).registryKey(RegistryKey.of(RegistryKeys.BLOCK, modId)), modId)); + UseBlockCallback.EVENT.register(DisplayBlock::onUse); + DISPLAY_BLOCK.setDefaultState(); + + DISPLAY_BLOCK_ENTITY = Registry.register( + Registries.BLOCK_ENTITY_TYPE, + modId, + FabricBlockEntityTypeBuilder.create(DisplayBlockEntity::new, DISPLAY_BLOCK).build(null) + ); + DISPLAY_BLOCK_ENTITY.addSupportedBlock(DISPLAY_BLOCK); + AttackBlockCallback.EVENT.register(DisplayBlock::onAttack); + PolymerBlockUtils.registerBlockEntity(DISPLAY_BLOCK_ENTITY); + } + + private static ActionResult onAttack(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) { + BlockEntity storageBlockEntity = world.getBlockEntity(pos); + if (storageBlockEntity instanceof DisplayBlockEntity displayBlockEntity) { + displayBlockEntity.reindexDrives(); + int maxFit = howMuchFits(displayBlockEntity.targetItem, player.getInventory()); + int finalCount = Math.min(player.isSneaking() ? displayBlockEntity.targetItem.getCount() : 1, maxFit); + ItemStack insertedStack = displayBlockEntity.targetItem.copy(); + insertedStack.setCount(finalCount); + + displayBlockEntity.itemCount = displayBlockEntity.network.itemStackMap.getOrDefault(displayBlockEntity.targetItem, 0); + + displayBlockEntity.network.removeItemStack(insertedStack); + displayBlockEntity.network.updateDisplays(); + + displayBlockEntity.itemCount -= finalCount; + + displayBlockEntity.itemElement.setItem(displayBlockEntity.targetItem); + displayBlockEntity.textDisplayElement.setText(Text.of(String.valueOf(displayBlockEntity.itemCount))); + + //TODO update the count + + int remainingToInsert = finalCount; + for (int i = 0; i < Math.ceilDivExact(finalCount, displayBlockEntity.targetItem.getMaxCount()); i++) { + ItemStack cappedStack = insertedStack.copy(); + cappedStack.setCount(Math.min(insertedStack.getMaxCount(), remainingToInsert)); + + ItemStack remaining = insertStackIntoInventory(player.getInventory(), cappedStack.copy()); + if (!remaining.isEmpty()) { + ItemStack reverseStack = displayBlockEntity.targetItem.copy(); + reverseStack.setCount(remaining.getCount() + remainingToInsert); + displayBlockEntity.network.putItemStackRemainder(reverseStack); + break; + } + remainingToInsert -= cappedStack.getCount(); + } + displayBlockEntity.itemCount += remainingToInsert; + displayBlockEntity.itemElement.setItem(displayBlockEntity.targetItem); + displayBlockEntity.textDisplayElement.setText(Text.of(String.valueOf(displayBlockEntity.itemCount))); + } + return ActionResult.PASS; + } + + private static ActionResult onUse(PlayerEntity plr, World world, Hand hand, BlockHitResult hitResult) { + BlockPos pos = hitResult.getBlockPos(); + BlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + + if (block instanceof DisplayBlock) { + if (!world.isClient && !plr.isSpectator() && plr instanceof ServerPlayerEntity player && hand == Hand.MAIN_HAND) { + BlockEntity storageBlockEntity = world.getBlockEntity(pos); + if (storageBlockEntity instanceof DisplayBlockEntity displayBlockEntity) { + displayBlockEntity.reindexDrives(); + displayBlockEntity.itemCount = displayBlockEntity.network.itemStackMap.getOrDefault(displayBlockEntity.targetItem, 0); + displayBlockEntity.itemElement.setItem(displayBlockEntity.targetItem); + displayBlockEntity.textDisplayElement.setText(Text.of(String.valueOf(displayBlockEntity.itemCount))); + if (player.isSneaking()) { + DisplayBlockMangementScreen displayBlockMangementScreen = new DisplayBlockMangementScreen(player, displayBlockEntity); + displayBlockMangementScreen.updateDisplay(); + displayBlockMangementScreen.open(); + } else { + ItemStack stack = player.getStackInHand(hand); + int canPutIn = stack.getCount() - displayBlockEntity.network.putItemStackRemainder(stack); + if (canPutIn > 0) { + removeFromInventory(player.getInventory(), stack, canPutIn); + } + //TODO add update the item count + } + + } + } + return ActionResult.SUCCESS; + } + return ActionResult.PASS; + } + + @Nullable + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new DisplayBlockEntity(pos, state); + } + + @Nullable + @Override + public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + // Make sure to check world.isClient if you only want to tick only on serverside. + return world instanceof ServerWorld && type == DISPLAY_BLOCK_ENTITY ? DisplayBlockEntity::tick : null; + } +} diff --git a/src/main/java/systems/brn/serverstorage/blocks/RadioInterfaceBlock.java b/src/main/java/systems/brn/serverstorage/blocks/RadioInterfaceBlock.java index c68c055..aed237e 100644 --- a/src/main/java/systems/brn/serverstorage/blocks/RadioInterfaceBlock.java +++ b/src/main/java/systems/brn/serverstorage/blocks/RadioInterfaceBlock.java @@ -123,7 +123,7 @@ public class RadioInterfaceBlock extends ConnectedBlock implements PolymerTextur } } if (sessionStorageClass == null || !sessionStorageClass.getPlayerUUID().equals(player.getUuid())) { - sessionStorageClass = new SessionStorageClass(player.getUuid(), player.getServerWorld(), pos); + sessionStorageClass = new SessionStorageClass(player.getUuid(), player.getWorld(), pos); wirelessTerminalSessions.add(sessionStorageClass); } stack.set(WirelessTerminalComponents.SESSIONS, wirelessTerminalSessions); diff --git a/src/main/java/systems/brn/serverstorage/items/WirelessTerminalItem.java b/src/main/java/systems/brn/serverstorage/items/WirelessTerminalItem.java index 23907b4..d25a3e9 100644 --- a/src/main/java/systems/brn/serverstorage/items/WirelessTerminalItem.java +++ b/src/main/java/systems/brn/serverstorage/items/WirelessTerminalItem.java @@ -65,7 +65,7 @@ public class WirelessTerminalItem extends SimpleItem { Vec3d playerTempPos = player.getPos(); BlockPos playerPos = player.getBlockPos(); BlockPos pos = radioInterfaceBlockEntity.getPos(); - ServerWorld playerWorld = player.getServerWorld(); + ServerWorld playerWorld = player.getWorld(); ServerWorld terminalWorld = playerWorld; int finalDistance = 0; int actualDistance = 0; @@ -86,7 +86,7 @@ public class WirelessTerminalItem extends SimpleItem { public static boolean openTerminal(BlockPos pos, ServerPlayerEntity player, ItemStack stack, ServerWorld world) { - ServerWorld playerWorld = player.getServerWorld(); + ServerWorld playerWorld = player.getWorld(); String playerWorldName = playerWorld.getRegistryKey().getValue().toString(); String terminalWorldName = world.getRegistryKey().getValue().toString(); if (stack.getItem() == WIRELESS_TERMINAL) { diff --git a/src/main/java/systems/brn/serverstorage/lib/GenericPlayerListGui.java b/src/main/java/systems/brn/serverstorage/lib/GenericPlayerListGui.java index 476ba3b..d037a0d 100644 --- a/src/main/java/systems/brn/serverstorage/lib/GenericPlayerListGui.java +++ b/src/main/java/systems/brn/serverstorage/lib/GenericPlayerListGui.java @@ -3,6 +3,7 @@ package systems.brn.serverstorage.lib; import com.mojang.authlib.GameProfile; import eu.pb4.sgui.api.elements.GuiElementBuilder; import net.minecraft.item.Items; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -45,7 +46,11 @@ public class GenericPlayerListGui extends PagedGui { } protected DisplayElement getPlayerElement(UUID uuid) { - UserCache userCache = this.player.server.getUserCache(); + MinecraftServer srv = this.player.getServer(); + if (srv == null) { + return DisplayElement.empty(); + } + UserCache userCache = srv.getUserCache(); GameProfile gameProfile = null; Optional gameProfileTemp; boolean exists = false; diff --git a/src/main/java/systems/brn/serverstorage/lib/ItemGroups.java b/src/main/java/systems/brn/serverstorage/lib/ItemGroups.java index ca9923c..638a0cd 100644 --- a/src/main/java/systems/brn/serverstorage/lib/ItemGroups.java +++ b/src/main/java/systems/brn/serverstorage/lib/ItemGroups.java @@ -17,6 +17,7 @@ public class ItemGroups { entries.add(BUS_CONNECTOR_BLOCK); entries.add(INVENTORY_INTERFACE_BLOCK); entries.add(RADIO_INTERFACE_BLOCK); + entries.add(DISPLAY_BLOCK); })) .build(); diff --git a/src/main/java/systems/brn/serverstorage/lib/PagedGui.java b/src/main/java/systems/brn/serverstorage/lib/PagedGui.java index f59d572..96dbf95 100644 --- a/src/main/java/systems/brn/serverstorage/lib/PagedGui.java +++ b/src/main/java/systems/brn/serverstorage/lib/PagedGui.java @@ -71,8 +71,12 @@ public abstract class PagedGui extends SimpleGui { } } - protected void nextPage() { - this.page = Math.min(this.getPageAmount() - 1, this.page + 1); + protected void nextPage(boolean allTheWay) { + if (allTheWay) { + this.page = this.getPageAmount() - 1; + } else { + this.page = Math.min(this.getPageAmount() - 1, this.page + 1); + } this.updateDisplay(); } @@ -80,8 +84,12 @@ public abstract class PagedGui extends SimpleGui { return this.getPageAmount() > this.page + 1; } - protected void previousPage() { - this.page = Math.max(0, this.page - 1); + protected void previousPage(boolean allTheWay) { + if (allTheWay) { + this.page = 0; + } else { + this.page = Math.max(0, this.page - 1); + } this.updateDisplay(); } @@ -202,7 +210,7 @@ public abstract class PagedGui extends SimpleGui { .setSkullOwner(GUI_NEXT_PAGE) .setCallback((x, y, z) -> { playClickSound(gui.player); - gui.nextPage(); + gui.nextPage(y.shift); }) ); } else { @@ -224,7 +232,7 @@ public abstract class PagedGui extends SimpleGui { .setSkullOwner(GUI_PREVIOUS_PAGE) .setCallback((x, y, z) -> { playClickSound(gui.player); - gui.previousPage(); + gui.previousPage(y.shift); }) ); } else { diff --git a/src/main/java/systems/brn/serverstorage/lib/Session.java b/src/main/java/systems/brn/serverstorage/lib/Session.java index 64f8944..9a60abc 100644 --- a/src/main/java/systems/brn/serverstorage/lib/Session.java +++ b/src/main/java/systems/brn/serverstorage/lib/Session.java @@ -1,7 +1,11 @@ package systems.brn.serverstorage.lib; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.Uuids; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -27,4 +31,13 @@ public record Session(UUID sessionKey, UUID playerUUID) { } return null; } + + public static final Codec SESSION_CODEC = RecordCodecBuilder.create(instance -> instance.group( + Uuids.CODEC.fieldOf("SessionKey").forGetter(Session::sessionKey), + Uuids.CODEC.fieldOf("PlayerUUID").forGetter(Session::playerUUID) + ).apply(instance, Session::new)); + + public static final Codec> SESSION_LIST_CODEC = SESSION_CODEC.listOf(); + + } diff --git a/src/main/java/systems/brn/serverstorage/screens/DisplayBlockMangementScreen.java b/src/main/java/systems/brn/serverstorage/screens/DisplayBlockMangementScreen.java new file mode 100644 index 0000000..5371a08 --- /dev/null +++ b/src/main/java/systems/brn/serverstorage/screens/DisplayBlockMangementScreen.java @@ -0,0 +1,42 @@ +package systems.brn.serverstorage.screens; + +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import net.minecraft.item.Items; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import systems.brn.serverstorage.blockentities.DisplayBlockEntity; +import systems.brn.serverstorage.lib.PagedGui; + +public class DisplayBlockMangementScreen extends PagedGui { + public final DisplayBlockEntity displayBlockEntity; + + public DisplayBlockMangementScreen(ServerPlayerEntity player, DisplayBlockEntity displayBlockEntity) { + super(player, null); + this.displayBlockEntity = displayBlockEntity; + this.setTitle(Text.translatable("gui.serverstorage.display_block_title")); + } + + @Override + protected int getPageAmount() { + return 1; + } + + @Override + protected DisplayElement getElement(int id) { + var builder = new GuiElementBuilder(displayBlockEntity.targetItem.getCount() > 0 ? displayBlockEntity.targetItem.getItem() : Items.AIR) + .setName(displayBlockEntity.targetItem.getItemName()) + .setCallback((clickIndex, clickType, slotActionType) -> { + displayBlockEntity.targetItem = getPlayer().currentScreenHandler.getCursorStack(); + + displayBlockEntity.reindexDrives(); + displayBlockEntity.itemCount = displayBlockEntity.network.itemStackMap.getOrDefault(displayBlockEntity.targetItem, 0); + displayBlockEntity.itemElement.setItem(displayBlockEntity.targetItem); + displayBlockEntity.textDisplayElement.setText(Text.of(String.valueOf(displayBlockEntity.itemCount))); + displayBlockEntity.markDirty(); + playClickSound(getPlayer()); + updateDisplay(); + }); + + return DisplayElement.of(builder); + } +} diff --git a/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java b/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java index 1f85968..f606d74 100644 --- a/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java +++ b/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java @@ -61,7 +61,7 @@ public class StorageScreen extends PagedGui implements Searchable { assert blockEntity != null; this.network = null; this.itemStack = ItemStack.EMPTY; - this.world = player.getServerWorld(); + this.world = player.getWorld(); this.radioInterfaceBlockEntity = null; } @@ -72,7 +72,7 @@ public class StorageScreen extends PagedGui implements Searchable { this.setLockPlayerInventory(false); this.network = storageNetwork; this.itemStack = itemStack; - this.world = player.getServerWorld(); + this.world = player.getWorld(); this.radioInterfaceBlockEntity = radioInterfaceBlockEntity; } diff --git a/src/main/resources/assets/serverstorage/items/display_block.json b/src/main/resources/assets/serverstorage/items/display_block.json new file mode 100644 index 0000000..eae2855 --- /dev/null +++ b/src/main/resources/assets/serverstorage/items/display_block.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "serverstorage:block/display_block" + } +} diff --git a/src/main/resources/assets/serverstorage/lang/en_us.json b/src/main/resources/assets/serverstorage/lang/en_us.json index a355826..ec77c42 100644 --- a/src/main/resources/assets/serverstorage/lang/en_us.json +++ b/src/main/resources/assets/serverstorage/lang/en_us.json @@ -2,6 +2,9 @@ "block.serverstorage.storage": "Networked Storage Interface", "item.serverstorage.storage": "Networked Storage Interface", + "block.serverstorage.display_block": "Networked Display", + "item.serverstorage.display_block": "Networked Display", + "block.serverstorage.inventory_interface": "Networked Inventory Interface", "item.serverstorage.inventory_interface": "Networked Inventory Interface", @@ -73,6 +76,9 @@ "gui.serverstorage.player_management_session_owner_error": "Not owned", "gui.serverstorage.player_management_session_key": "Session key: %s", + "gui.serverstorage.display_block_title": "Display block", + "gui.serverstorage.display_block_item": "Target item: %s", + "gui.serverstorage.wireless_terminal_link_count": "Linked to %d devices", "gui.serverstorage.wireless_terminal_link_index": "Current link index is %d", "gui.serverstorage.wireless_terminal_page": "Page: %d", diff --git a/src/main/resources/assets/serverstorage/models/block/display_block.json b/src/main/resources/assets/serverstorage/models/block/display_block.json new file mode 100644 index 0000000..610cb0b --- /dev/null +++ b/src/main/resources/assets/serverstorage/models/block/display_block.json @@ -0,0 +1,12 @@ +{ + "parent": "block/orientable_with_bottom", + "textures": { + "front": "serverstorage:block/display_front", + "side": "serverstorage:block/drive_container_side", + "top": "serverstorage:block/drive_container_side", + "bottom": "serverstorage:block/drive_container_side", + "east": "serverstorage:block/drive_container_side", + "south": "serverstorage:block/drive_container_side", + "west": "serverstorage:block/drive_container_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/serverstorage/models/item/display_block.json b/src/main/resources/assets/serverstorage/models/item/display_block.json new file mode 100644 index 0000000..00fb132 --- /dev/null +++ b/src/main/resources/assets/serverstorage/models/item/display_block.json @@ -0,0 +1,3 @@ +{ + "parent": "serverstorage:block/display_block" +} \ No newline at end of file diff --git a/src/main/resources/assets/serverstorage/textures/block/display_front.png b/src/main/resources/assets/serverstorage/textures/block/display_front.png new file mode 100644 index 0000000000000000000000000000000000000000..236f0d169fed3e96fd18c7961b5c97587d6494f5 GIT binary patch literal 358 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4rT@h1`S>QU2f2pMLTD{+rj2Po6k%=Ja7RQ)6>86NXp+`}_O9 zOuu8#z`)S%>Eak7F*WquZLVem0hSA$yA8#2eHLxKbhJq~sO#_l_phTPpMN~S!z^KP zWLxR7uTLx&^v2eEI_s6rSy#+|Vav)Ap3dmc=cno1S+G#($n^<}b9vVDS>+X6?E;af