Get it to somehow work
This commit is contained in:
parent
94e25bb16e
commit
3301cf2d8b
@ -2,8 +2,6 @@ package systems.brn.server_storage;
|
|||||||
|
|
||||||
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
|
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
|
||||||
import systems.brn.server_storage.blockEntities.StorageBlockEntity;
|
|
||||||
import systems.brn.server_storage.blocks.StorageBlock;
|
import systems.brn.server_storage.blocks.StorageBlock;
|
||||||
import systems.brn.server_storage.items.StorageBlockItem;
|
import systems.brn.server_storage.items.StorageBlockItem;
|
||||||
|
|
||||||
@ -11,7 +9,6 @@ public class ServerStorage implements ModInitializer {
|
|||||||
public static final String MODID = "serverstorage";
|
public static final String MODID = "serverstorage";
|
||||||
public static final String MODELID = "storage";
|
public static final String MODELID = "storage";
|
||||||
public static StorageBlock STORAGE_BLOCK;
|
public static StorageBlock STORAGE_BLOCK;
|
||||||
public static BlockEntityType<StorageBlockEntity> CUSTOM_STORAGE_BLOCK_ENTITY;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize()
|
public void onInitialize()
|
||||||
@ -21,7 +18,6 @@ public class ServerStorage implements ModInitializer {
|
|||||||
|
|
||||||
StorageBlock.register();
|
StorageBlock.register();
|
||||||
StorageBlockItem.register();
|
StorageBlockItem.register();
|
||||||
StorageBlockEntity.register();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
package systems.brn.server_storage.blockEntities;
|
|
||||||
|
|
||||||
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
|
||||||
import net.minecraft.inventory.Inventory;
|
|
||||||
import net.minecraft.registry.Registries;
|
|
||||||
import net.minecraft.registry.Registry;
|
|
||||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
|
||||||
import net.minecraft.screen.ScreenHandler;
|
|
||||||
import net.minecraft.screen.ScreenHandlerContext;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
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.server_storage.screens.StorageScreen;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static systems.brn.server_storage.ServerStorage.*;
|
|
||||||
|
|
||||||
public class StorageBlockEntity extends BlockEntity implements NamedScreenHandlerFactory {
|
|
||||||
|
|
||||||
public StorageBlockEntity(BlockPos pos, BlockState state) {
|
|
||||||
super(CUSTOM_STORAGE_BLOCK_ENTITY, pos, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Text getDisplayName() {
|
|
||||||
return Text.of("Custom Storage");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
|
|
||||||
List<Inventory> connectedChests = getConnectedChests(world, pos);
|
|
||||||
return new StorageScreen(syncId, playerInventory, ScreenHandlerContext.create(world, pos), connectedChests.getFirst());
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<Inventory> getConnectedChests(World world, BlockPos pos) {
|
|
||||||
List<Inventory> inventories = new ArrayList<>();
|
|
||||||
|
|
||||||
// Logic to find nearby chests and add them to the list
|
|
||||||
// Example logic:
|
|
||||||
for (Direction direction : Direction.values()) {
|
|
||||||
BlockPos chestPos = pos.offset(direction);
|
|
||||||
BlockEntity blockEntity = world.getBlockEntity(chestPos);
|
|
||||||
if (blockEntity instanceof Inventory) {
|
|
||||||
inventories.add((Inventory) blockEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return inventories;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void register() {
|
|
||||||
Registry.register(
|
|
||||||
Registries.BLOCK_ENTITY_TYPE,
|
|
||||||
new Identifier(MODID, "custom_storage_block_entity"),
|
|
||||||
BlockEntityType.Builder.create(StorageBlockEntity::new, STORAGE_BLOCK).build()
|
|
||||||
);
|
|
||||||
PolymerBlockUtils.registerBlockEntity(CUSTOM_STORAGE_BLOCK_ENTITY);
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,33 +9,19 @@ import net.minecraft.block.AbstractBlock;
|
|||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.Inventory;
|
|
||||||
import net.minecraft.inventory.SimpleInventory;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.screen.ScreenHandlerContext;
|
|
||||||
import net.minecraft.screen.SimpleNamedScreenHandlerFactory;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import systems.brn.server_storage.ServerStorage;
|
import systems.brn.server_storage.ServerStorage;
|
||||||
import systems.brn.server_storage.screens.StorageScreen;
|
import systems.brn.server_storage.screens.StorageScreen;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static systems.brn.server_storage.ServerStorage.STORAGE_BLOCK;
|
import static systems.brn.server_storage.ServerStorage.STORAGE_BLOCK;
|
||||||
|
|
||||||
public class StorageBlock extends Block implements PolymerTexturedBlock {
|
public class StorageBlock extends Block implements PolymerTexturedBlock {
|
||||||
@ -59,22 +45,6 @@ public class StorageBlock extends Block implements PolymerTexturedBlock {
|
|||||||
UseBlockCallback.EVENT.register(StorageBlock::onUse);
|
UseBlockCallback.EVENT.register(StorageBlock::onUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Inventory> getConnectedChests(World world, BlockPos pos) {
|
|
||||||
List<Inventory> inventories = new ArrayList<>();
|
|
||||||
|
|
||||||
// Logic to find nearby chests and add them to the list
|
|
||||||
// Example logic:
|
|
||||||
for (Direction direction : Direction.values()) {
|
|
||||||
BlockPos chestPos = pos.offset(direction);
|
|
||||||
BlockEntity blockEntity = world.getBlockEntity(chestPos);
|
|
||||||
if (blockEntity instanceof Inventory) {
|
|
||||||
inventories.add((Inventory) blockEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return inventories;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ActionResult onUse(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
|
private static ActionResult onUse(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
|
||||||
BlockPos pos = hitResult.getBlockPos();
|
BlockPos pos = hitResult.getBlockPos();
|
||||||
BlockState state = world.getBlockState(pos);
|
BlockState state = world.getBlockState(pos);
|
||||||
@ -82,56 +52,7 @@ public class StorageBlock extends Block implements PolymerTexturedBlock {
|
|||||||
|
|
||||||
if (block instanceof StorageBlock) {
|
if (block instanceof StorageBlock) {
|
||||||
if (!world.isClient) {
|
if (!world.isClient) {
|
||||||
List<Inventory> inventories = getConnectedChests(world, pos);
|
new StorageScreen((ServerPlayerEntity) player, pos).open();
|
||||||
int size = 0;
|
|
||||||
for (Inventory inventory : inventories) {
|
|
||||||
size += inventory.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a map to keep track of item stacks and their counts
|
|
||||||
Map<Item, Integer> itemStackMap = new HashMap<>();
|
|
||||||
|
|
||||||
// Loop through inventories to add items to the inventory
|
|
||||||
for (Inventory inventory : inventories) {
|
|
||||||
int invsize = inventory.size();
|
|
||||||
for (int i = 0; i < invsize; i++) {
|
|
||||||
ItemStack stack = inventory.getStack(i);
|
|
||||||
if (!stack.isEmpty()) {
|
|
||||||
Item item = stack.getItem();
|
|
||||||
// Check if the item type already exists in the map
|
|
||||||
int count = stack.getCount();
|
|
||||||
if (itemStackMap.containsKey(item)) {
|
|
||||||
// If yes, increment the count
|
|
||||||
count += itemStackMap.get(item);
|
|
||||||
itemStackMap.put(item, count);
|
|
||||||
} else {
|
|
||||||
// If not, add the item type to the map with count 1
|
|
||||||
itemStackMap.put(item, count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate the inventory with item stacks from the map
|
|
||||||
|
|
||||||
SimpleInventory inv = new SimpleInventory(size);
|
|
||||||
int invpointer = 0;
|
|
||||||
for (Map.Entry<Item, Integer> entry : itemStackMap.entrySet()) {
|
|
||||||
Item item = entry.getKey();
|
|
||||||
int count = entry.getValue();
|
|
||||||
// Create a new ItemStack with the item type and the correct count
|
|
||||||
ItemStack stack = new ItemStack(item, count);
|
|
||||||
// Populate the inventory with the item stack
|
|
||||||
inv.heldStacks.set(invpointer, stack);
|
|
||||||
inv.markDirty();
|
|
||||||
invpointer++;
|
|
||||||
}
|
|
||||||
if (!inv.isEmpty()) {
|
|
||||||
NamedScreenHandlerFactory screenHandlerFactory = new SimpleNamedScreenHandlerFactory(
|
|
||||||
(syncId, playerInventory, playerEntity) -> new StorageScreen(syncId, playerInventory, ScreenHandlerContext.create(world, pos), inv),
|
|
||||||
Text.of("Storage System"));
|
|
||||||
player.openHandledScreen(screenHandlerFactory);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ActionResult.SUCCESS;
|
return ActionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,6 @@ public class StorageBlockItem extends BlockItem implements PolymerItem {
|
|||||||
public static void register() {
|
public static void register() {
|
||||||
var modId = new Identifier(ServerStorage.MODID, ServerStorage.MODELID);
|
var modId = new Identifier(ServerStorage.MODID, ServerStorage.MODELID);
|
||||||
Item item = Registry.register(Registries.ITEM, modId, new StorageBlockItem(new Item.Settings(), STORAGE_BLOCK, ServerStorage.MODELID));
|
Item item = Registry.register(Registries.ITEM, modId, new StorageBlockItem(new Item.Settings(), STORAGE_BLOCK, ServerStorage.MODELID));
|
||||||
ItemGroupEvents.modifyEntriesEvent(ItemGroups.FUNCTIONAL).register(content -> {
|
ItemGroupEvents.modifyEntriesEvent(ItemGroups.FUNCTIONAL).register(content -> content.add(item));
|
||||||
content.add(item);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
204
src/main/java/systems/brn/server_storage/lib/PagedGui.java
Normal file
204
src/main/java/systems/brn/server_storage/lib/PagedGui.java
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
package systems.brn.server_storage.lib;
|
||||||
|
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElement;
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementBuilderInterface;
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementInterface;
|
||||||
|
import eu.pb4.sgui.api.gui.SimpleGui;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.screen.slot.Slot;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
//from https://github.com/Patbox/get-off-my-lawn-reserved/blob/6c03c6b004f65616d1d8cb773c19da970eb8c1d1/src/main/java/draylar/goml/ui/PagedGui.java
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public abstract class PagedGui extends SimpleGui {
|
||||||
|
|
||||||
|
public static final String GUI_PREVIOUS_PAGE = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzEwODI5OGZmMmIyNjk1MWQ2ODNlNWFkZTQ2YTQyZTkwYzJmN2M3ZGQ0MWJhYTkwOGJjNTg1MmY4YzMyZTU4MyJ9fX0";
|
||||||
|
public static final String GUI_PREVIOUS_PAGE_BLOCKED = "ewogICJ0aW1lc3RhbXAiIDogMTY0MDYxNjE5MjE0MiwKICAicHJvZmlsZUlkIiA6ICJmMjc0YzRkNjI1MDQ0ZTQxOGVmYmYwNmM3NWIyMDIxMyIsCiAgInByb2ZpbGVOYW1lIiA6ICJIeXBpZ3NlbCIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81MDgyMGY3NmUzZTA0MWM3NWY3NmQwZjMwMTIzMmJkZjQ4MzIxYjUzNGZlNmE4NTljY2I4NzNkMjk4MWE5NjIzIiwKICAgICAgIm1ldGFkYXRhIiA6IHsKICAgICAgICAibW9kZWwiIDogInNsaW0iCiAgICAgIH0KICAgIH0KICB9Cn0=";
|
||||||
|
public static final String GUI_NEXT_PAGE = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzg2MTg1YjFkNTE5YWRlNTg1ZjE4NGMzNGYzZjNlMjBiYjY0MWRlYjg3OWU4MTM3OGU0ZWFmMjA5Mjg3In19fQ";
|
||||||
|
public static final String GUI_NEXT_PAGE_BLOCKED = "ewogICJ0aW1lc3RhbXAiIDogMTY0MDYxNjExMDQ4OCwKICAicHJvZmlsZUlkIiA6ICIxZjEyNTNhYTVkYTQ0ZjU5YWU1YWI1NmFhZjRlNTYxNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJOb3RNaUt5IiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzdlNTc3MjBhNDg3OGM4YmNhYjBlOWM5YzQ3ZDllNTUxMjhjY2Q3N2JhMzQ0NWE1NGE5MWUzZTFlMWEyNzM1NmUiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==";
|
||||||
|
|
||||||
|
public static final int PAGE_SIZE = 9 * 5;
|
||||||
|
protected final Runnable closeCallback;
|
||||||
|
protected int page = 0;
|
||||||
|
public boolean ignoreCloseCallback;
|
||||||
|
|
||||||
|
public PagedGui(ServerPlayerEntity player, @Nullable Runnable closeCallback) {
|
||||||
|
super(ScreenHandlerType.GENERIC_9X6, player, false);
|
||||||
|
this.closeCallback = closeCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void refreshOpen() {
|
||||||
|
this.updateDisplay();
|
||||||
|
this.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
if (this.closeCallback != null && !ignoreCloseCallback) {
|
||||||
|
this.closeCallback.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void nextPage() {
|
||||||
|
this.page = Math.min(this.getPageAmount() - 1, this.page + 1);
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canNextPage() {
|
||||||
|
return this.getPageAmount() > this.page + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void previousPage() {
|
||||||
|
this.page = Math.max(0, this.page - 1);
|
||||||
|
this.updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canPreviousPage() {
|
||||||
|
return this.page - 1 >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateDisplay() {
|
||||||
|
var offset = this.page * PAGE_SIZE;
|
||||||
|
|
||||||
|
for (int i = 0; i < PAGE_SIZE; i++) {
|
||||||
|
var element = this.getElement(offset + i);
|
||||||
|
|
||||||
|
if (element == null) {
|
||||||
|
element = DisplayElement.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.element() != null) {
|
||||||
|
this.setSlot(i, element.element());
|
||||||
|
} else if (element.slot() != null) {
|
||||||
|
this.setSlotRedirect(i, element.slot());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
var navElement = this.getNavElement(i);
|
||||||
|
|
||||||
|
if (navElement == null) {
|
||||||
|
navElement = DisplayElement.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navElement.element != null) {
|
||||||
|
this.setSlot(i + PAGE_SIZE, navElement.element);
|
||||||
|
} else if (navElement.slot != null) {
|
||||||
|
this.setSlotRedirect(i + PAGE_SIZE, navElement.slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getPage() {
|
||||||
|
return this.page;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract int getPageAmount();
|
||||||
|
|
||||||
|
protected abstract DisplayElement getElement(int id);
|
||||||
|
|
||||||
|
protected DisplayElement getNavElement(int id) {
|
||||||
|
return switch (id) {
|
||||||
|
case 1 -> DisplayElement.previousPage(this);
|
||||||
|
case 3 -> DisplayElement.nextPage(this);
|
||||||
|
case 7 -> DisplayElement.of(
|
||||||
|
new GuiElementBuilder(Items.STRUCTURE_VOID)
|
||||||
|
.setName(Text.translatable(this.closeCallback != null ? "gui.back" : "mco.selectServer.close").formatted(Formatting.RED))
|
||||||
|
.hideDefaultTooltip().noDefaults()
|
||||||
|
.setCallback((x, y, z) -> {
|
||||||
|
playClickSound(this.player);
|
||||||
|
this.close(this.closeCallback != null);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
default -> DisplayElement.filler();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public record DisplayElement(@Nullable GuiElementInterface element, @Nullable Slot slot) {
|
||||||
|
private static final DisplayElement EMPTY = DisplayElement.of(new GuiElement(ItemStack.EMPTY, GuiElementInterface.EMPTY_CALLBACK));
|
||||||
|
private static final DisplayElement FILLER = DisplayElement.of(
|
||||||
|
new GuiElementBuilder(Items.WHITE_STAINED_GLASS_PANE)
|
||||||
|
.setName(Text.empty())
|
||||||
|
.hideTooltip()
|
||||||
|
);
|
||||||
|
|
||||||
|
public static DisplayElement of(GuiElementInterface element) {
|
||||||
|
return new DisplayElement(element, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayElement of(GuiElementBuilderInterface<?> element) {
|
||||||
|
return new DisplayElement(element.build(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayElement of(Slot slot) {
|
||||||
|
return new DisplayElement(null, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayElement nextPage(PagedGui gui) {
|
||||||
|
if (gui.canNextPage()) {
|
||||||
|
return DisplayElement.of(
|
||||||
|
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||||
|
.setName(Text.translatable("createWorld.customize.custom.next").formatted(Formatting.WHITE))
|
||||||
|
.hideDefaultTooltip().noDefaults()
|
||||||
|
.setSkullOwner(GUI_NEXT_PAGE)
|
||||||
|
.setCallback((x, y, z) -> {
|
||||||
|
playClickSound(gui.player);
|
||||||
|
gui.nextPage();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return DisplayElement.of(
|
||||||
|
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||||
|
.setName(Text.translatable("createWorld.customize.custom.next").formatted(Formatting.DARK_GRAY))
|
||||||
|
.hideDefaultTooltip().noDefaults()
|
||||||
|
.setSkullOwner(GUI_NEXT_PAGE_BLOCKED)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayElement previousPage(PagedGui gui) {
|
||||||
|
if (gui.canPreviousPage()) {
|
||||||
|
return DisplayElement.of(
|
||||||
|
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||||
|
.setName(Text.translatable("createWorld.customize.custom.prev").formatted(Formatting.WHITE))
|
||||||
|
.hideDefaultTooltip().noDefaults()
|
||||||
|
.setSkullOwner(GUI_PREVIOUS_PAGE)
|
||||||
|
.setCallback((x, y, z) -> {
|
||||||
|
playClickSound(gui.player);
|
||||||
|
gui.previousPage();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return DisplayElement.of(
|
||||||
|
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||||
|
.setName(Text.translatable("createWorld.customize.custom.prev").formatted(Formatting.DARK_GRAY))
|
||||||
|
.hideDefaultTooltip().noDefaults()
|
||||||
|
.setSkullOwner(GUI_PREVIOUS_PAGE_BLOCKED)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayElement filler() {
|
||||||
|
return FILLER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayElement empty() {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final void playClickSound(ServerPlayerEntity player) {
|
||||||
|
player.playSoundToPlayer(SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.MASTER, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
package systems.brn.server_storage.lib;
|
||||||
|
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.inventory.Inventory;
|
||||||
|
import net.minecraft.inventory.SimpleInventory;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import systems.brn.server_storage.blocks.StorageBlock;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class StorageOperations {
|
||||||
|
public static List<Inventory> getConnectedChests(World world, BlockPos startPos) {
|
||||||
|
List<Inventory> inventories = new ArrayList<>();
|
||||||
|
Set<BlockPos> visited = new HashSet<>();
|
||||||
|
|
||||||
|
getConnectedChestsHelper(world, startPos, inventories, visited);
|
||||||
|
|
||||||
|
return inventories;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getConnectedChestsHelper(World world, BlockPos pos, List<Inventory> inventories, Set<BlockPos> visited) {
|
||||||
|
if (visited.contains(pos)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
visited.add(pos);
|
||||||
|
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof Inventory || world.getBlockState(pos).getBlock() instanceof StorageBlock) {
|
||||||
|
if (blockEntity instanceof Inventory) {
|
||||||
|
inventories.add((Inventory) blockEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Direction direction : Direction.values()) {
|
||||||
|
BlockPos nextPos = pos.offset(direction);
|
||||||
|
getConnectedChestsHelper(world, nextPos, inventories, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean tryPutItemStackIntoChests(World world, BlockPos startPos, ItemStack stack) {
|
||||||
|
List<Inventory> chests = getConnectedChests(world, startPos);
|
||||||
|
|
||||||
|
// Iterate over each chest to try and insert the ItemStack
|
||||||
|
for (Inventory chest : chests) {
|
||||||
|
stack = insertStackIntoInventory(chest, stack);
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we still have remaining items, return false
|
||||||
|
return stack.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack insertStackIntoInventory(Inventory inventory, ItemStack stack) {
|
||||||
|
// First, try to merge with existing stacks
|
||||||
|
for (int i = 0; i < inventory.size(); i++) {
|
||||||
|
ItemStack slotStack = inventory.getStack(i);
|
||||||
|
if (canCombine(slotStack, stack)) {
|
||||||
|
int transferAmount = Math.min(stack.getCount(), slotStack.getMaxCount() - slotStack.getCount());
|
||||||
|
if (transferAmount > 0) {
|
||||||
|
slotStack.increment(transferAmount);
|
||||||
|
stack.decrement(transferAmount);
|
||||||
|
inventory.markDirty();
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, try to find an empty slot
|
||||||
|
for (int i = 0; i < inventory.size(); i++) {
|
||||||
|
ItemStack slotStack = inventory.getStack(i);
|
||||||
|
if (slotStack.isEmpty()) {
|
||||||
|
inventory.setStack(i, stack.copy());
|
||||||
|
stack.setCount(0);
|
||||||
|
inventory.markDirty();
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean tryRemoveItemStackFromChests(World world, BlockPos startPos, ItemStack stackToRemove) {
|
||||||
|
List<Inventory> chests = getConnectedChests(world, startPos);
|
||||||
|
|
||||||
|
int remainingToRemove = stackToRemove.getCount();
|
||||||
|
|
||||||
|
for (Inventory chest : chests) {
|
||||||
|
remainingToRemove = removeFromInventory(chest, stackToRemove, remainingToRemove);
|
||||||
|
if (remainingToRemove <= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return remainingToRemove <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int removeFromInventory(Inventory inventory, ItemStack stackToRemove, int remainingToRemove) {
|
||||||
|
for (int i = 0; i < inventory.size(); i++) {
|
||||||
|
ItemStack slotStack = inventory.getStack(i);
|
||||||
|
if (canCombine(slotStack, stackToRemove)) {
|
||||||
|
int removeAmount = Math.min(slotStack.getCount(), remainingToRemove);
|
||||||
|
slotStack.decrement(removeAmount);
|
||||||
|
remainingToRemove -= removeAmount;
|
||||||
|
inventory.markDirty();
|
||||||
|
|
||||||
|
if (slotStack.isEmpty()) {
|
||||||
|
inventory.setStack(i, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainingToRemove <= 0) {
|
||||||
|
return remainingToRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return remainingToRemove;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SimpleInventory getCombinedInventoryFromChests(World world, BlockPos startPos) {
|
||||||
|
List<Inventory> inventories = getConnectedChests(world, startPos);
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
// Create a map to keep track of item stacks and their counts
|
||||||
|
Map<Item, Integer> itemStackMap = new HashMap<>();
|
||||||
|
|
||||||
|
// Loop through inventories to add items to the inventory
|
||||||
|
for (Inventory inventory : inventories) {
|
||||||
|
int inventorySize = inventory.size();
|
||||||
|
for (int i = 0; i < inventorySize; i++) {
|
||||||
|
ItemStack stack = inventory.getStack(i);
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
// Check if the item type already exists in the map
|
||||||
|
int count = stack.getCount();
|
||||||
|
if (itemStackMap.containsKey(item)) {
|
||||||
|
// If yes, increment the count
|
||||||
|
count += itemStackMap.get(item);
|
||||||
|
itemStackMap.put(item, count);
|
||||||
|
} else {
|
||||||
|
// If not, add the item type to the map with count 1
|
||||||
|
itemStackMap.put(item, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size += inventorySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate the inventory with item stacks from the map
|
||||||
|
|
||||||
|
return getSimpleInventory(size, itemStackMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NotNull SimpleInventory getSimpleInventory(int size, Map<Item, Integer> itemStackMap) {
|
||||||
|
SimpleInventory inv = new SimpleInventory(size);
|
||||||
|
int invPointer = 0;
|
||||||
|
for (Map.Entry<Item, Integer> entry : itemStackMap.entrySet()) {
|
||||||
|
Item item = entry.getKey();
|
||||||
|
int count = entry.getValue();
|
||||||
|
// Create a new ItemStack with the item type and the correct count
|
||||||
|
ItemStack stack = new ItemStack(item, count);
|
||||||
|
// Populate the inventory with the item stack
|
||||||
|
inv.setStack(invPointer, stack);
|
||||||
|
invPointer++;
|
||||||
|
}
|
||||||
|
return inv;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean canCombine(ItemStack stack1, ItemStack stack2) {
|
||||||
|
return !stack1.isEmpty() && stack1.getItem() == stack2.getItem() && ItemStack.areItemsAndComponentsEqual(stack1, stack2);
|
||||||
|
}
|
||||||
|
}
|
@ -1,55 +1,78 @@
|
|||||||
package systems.brn.server_storage.screens;
|
package systems.brn.server_storage.screens;
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import eu.pb4.sgui.api.ClickType;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||||
|
import eu.pb4.sgui.api.elements.GuiElementInterface;
|
||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.screen.ScreenHandler;
|
import net.minecraft.screen.slot.SlotActionType;
|
||||||
import net.minecraft.screen.ScreenHandlerContext;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.screen.slot.Slot;
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import systems.brn.server_storage.lib.PagedGui;
|
||||||
|
|
||||||
import static net.minecraft.screen.ScreenHandlerType.GENERIC_9X6;
|
import static systems.brn.server_storage.lib.StorageOperations.*;
|
||||||
|
|
||||||
public class StorageScreen extends ScreenHandler {
|
public class StorageScreen extends PagedGui {
|
||||||
private Inventory inventory;
|
private Inventory inventory;
|
||||||
|
private final BlockPos pos;
|
||||||
|
private final ServerPlayerEntity player;
|
||||||
|
private final World world;
|
||||||
|
|
||||||
public StorageScreen(int syncId, PlayerInventory playerInventory, ScreenHandlerContext context, Inventory inventory) {
|
public StorageScreen(ServerPlayerEntity player, BlockPos pos) {
|
||||||
super(GENERIC_9X6, syncId);
|
super(player, null);
|
||||||
this.inventory = inventory;
|
this.player = player;
|
||||||
|
this.pos = pos;
|
||||||
|
this.world = player.getWorld();
|
||||||
|
|
||||||
// Add custom storage inventory slots (9x6 grid for example)
|
this.setTitle(Text.literal("Networked storage system"));
|
||||||
for (int row = 0; row < 6; ++row) {
|
this.setLockPlayerInventory(false);
|
||||||
for (int col = 0; col < 9; ++col) {
|
this.updateDisplay();
|
||||||
this.addSlot(new Slot(this.inventory, row * 9 + col, col, row));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canUse(PlayerEntity player) {
|
protected void updateDisplay() {
|
||||||
return true; // Add appropriate checks here
|
this.inventory = getCombinedInventoryFromChests(world, pos);
|
||||||
|
super.updateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack quickMove(PlayerEntity player, int index) {
|
protected int getPageAmount() {
|
||||||
ItemStack newStack = ItemStack.EMPTY;
|
int sizeX = 9;
|
||||||
Slot slot = this.slots.get(index);
|
int sizeY = 6;
|
||||||
if (slot.hasStack()) {
|
return Math.ceilDivExact(this.inventory.size(), sizeX * sizeY);
|
||||||
ItemStack originalStack = slot.getStack();
|
|
||||||
newStack = originalStack.copy();
|
|
||||||
if (index < this.inventory.size()) {
|
|
||||||
if (!this.insertItem(originalStack, this.inventory.size(), this.slots.size(), true)) {
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
}
|
||||||
} else if (!this.insertItem(originalStack, 0, this.inventory.size(), false)) {
|
|
||||||
return ItemStack.EMPTY;
|
@Override
|
||||||
|
protected DisplayElement getElement(int id) {
|
||||||
|
if (this.inventory.size() > id) {
|
||||||
|
ItemStack itemStack = this.inventory.getStack(id);
|
||||||
|
GuiElementBuilder guiElement = GuiElementBuilder.from(itemStack);
|
||||||
|
return DisplayElement.of(guiElement);
|
||||||
}
|
}
|
||||||
if (originalStack.isEmpty()) {
|
return DisplayElement.empty();
|
||||||
slot.setStack(ItemStack.EMPTY);
|
}
|
||||||
} else {
|
|
||||||
slot.markDirty();
|
@Override
|
||||||
|
public boolean onClick(int index, ClickType type, SlotActionType action, GuiElementInterface element) {
|
||||||
|
GuiElementInterface clickedElement = this.getSlot(index);
|
||||||
|
if (clickedElement != null) {
|
||||||
|
ItemStack clickedItem = clickedElement.getItemStack();
|
||||||
|
if (tryRemoveItemStackFromChests(world, pos, clickedItem)) {
|
||||||
|
this.player.getInventory().insertStack(clickedItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newStack;
|
this.updateDisplay();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean insertItem(ItemStack stack, int startIndex, int endIndex, boolean fromLast) {
|
||||||
|
if(tryPutItemStackIntoChests(world, pos, stack)){
|
||||||
|
removeFromInventory(player.getInventory(), stack, stack.getCount());
|
||||||
|
}
|
||||||
|
this.updateDisplay();
|
||||||
|
return super.insertItem(stack, startIndex, endIndex, fromLast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
"systems.brn.server_storage.ServerStorage"
|
"systems.brn.server_storage.ServerStorage"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mixins": [
|
|
||||||
"server_storage.mixins.json"
|
|
||||||
],
|
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=${loader_version}",
|
"fabricloader": ">=${loader_version}",
|
||||||
"fabric": "*",
|
"fabric": "*",
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"required": true,
|
|
||||||
"minVersion": "0.8",
|
|
||||||
"package": "systems.brn.server_storage.mixin",
|
|
||||||
"compatibilityLevel": "JAVA_21",
|
|
||||||
"mixins": [
|
|
||||||
],
|
|
||||||
"injectors": {
|
|
||||||
"defaultRequire": 1
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user