A bit of an update

This commit is contained in:
2024-07-04 13:44:48 +02:00
parent 7f8d4b8eb3
commit c6b94b2716
137 changed files with 2468 additions and 724 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -4,11 +4,11 @@ org.gradle.jvmargs=-Xmx1G
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.21
yarn_mappings=1.21+build.2
yarn_mappings=1.21+build.7
loader_version=0.15.11
# Fabric API
fabric_version=0.100.3+1.21
fabric_version=0.100.4+1.21
# Mod Properties
mod_version=2.6.2
@@ -6,12 +6,16 @@ import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory;
import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroups;
import net.minecraft.util.Identifier;
import net.minecraft.world.GameRules;
import systems.brn.server_storage.blockentities.HardDriveContainerBlockEntity;
import systems.brn.server_storage.blockentities.StorageBlockEntity;
import systems.brn.server_storage.blockentities.InventoryInterfaceBlockEntity;
import systems.brn.server_storage.blockentities.StorageInterfaceBlockEntity;
import systems.brn.server_storage.blocks.BusConnectorBlock;
import systems.brn.server_storage.blocks.HardDriveContainerBlock;
import systems.brn.server_storage.blocks.StorageBlock;
import systems.brn.server_storage.blocks.InventoryInterfaceBlock;
import systems.brn.server_storage.blocks.StorageInterfaceBlock;
import systems.brn.server_storage.items.HardDriveItem;
import systems.brn.server_storage.items.SimpleBlockItem;
import systems.brn.server_storage.items.SimpleItem;
@@ -20,26 +24,40 @@ import java.util.Arrays;
import java.util.List;
public class ServerStorage implements ModInitializer {
public static final List<String> moduleList = Arrays.asList("bus", "configuration", "container", "display", "drive", "filtering", "inventory", "pagination", "pcb", "transport");
public static final List<String> tiers = Arrays.asList("iron", "golden", "diamond", "netherite");
public static final String MOD_ID = "serverstorage";
public static final String STORAGE_MODEL_ID = "storage";
public static final String HARD_DRIVE_CONTAINER_BLOCK_MODEL_ID = "drive_container";
public static final String BUS_CONNECTOR_MODEL_ID = "bus_connector";
public static BusConnectorBlock BUS_CONNECTOR_BLOCK;
public static final String HARD_DRIVE_CONTAINER_BLOCK_MODEL_ID = "drive_container";
public static BlockEntityType<HardDriveContainerBlockEntity> HARD_DRIVE_CONTAINER_BLOCK_ENTITY;
public static HardDriveContainerBlock HARD_DRIVE_CONTAINER_BLOCK;
public static StorageBlock STORAGE_BLOCK;
public static BlockEntityType<StorageBlockEntity> STORAGE_BLOCK_ENTITY;
public static final String STORAGE_MODEL_ID = "storage";
public static StorageInterfaceBlock STORAGE_INTERFACE_BLOCK;
public static BlockEntityType<StorageInterfaceBlockEntity> STORAGE_INTERFACE_BLOCK_ENTITY;
public static final String INVENTORY_INTERFACE_BLOCK_MODEL_ID = "inventory_interface";
public static InventoryInterfaceBlock INVENTORY_INTERFACE_BLOCK;
public static BlockEntityType<InventoryInterfaceBlockEntity> INVENTORY_INTERFACE_BLOCK_ENTITY;
public static Item DRIVE_CASING;
public static Item CPU;
public static Item CPU_SUBSTRATE;
public static Item DRIVE_CONTROLLER;
public static Item PCB;
public static Item PCB_SUBSTRATE;
public static List<Item> MODULES;
public static List<Item> PLATTERS;
public static List<Item> DRIVES;
public static List<Item> HEADS;
public static final GameRules.Key<GameRules.BooleanRule> ServerStorage_Crafting_Enable =
GameRuleRegistry.register("enableserverstoragecrafting", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(false));
GameRuleRegistry.register("enableServerStorageCrafting", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(false));
public static Identifier id(String path) {
@@ -49,17 +67,34 @@ public class ServerStorage implements ModInitializer {
@Override
public void onInitialize()
{
StorageBlock.register();
SimpleBlockItem.register(STORAGE_BLOCK);
StorageInterfaceBlock.register();
SimpleBlockItem.register(STORAGE_INTERFACE_BLOCK);
HardDriveContainerBlock.register();
SimpleBlockItem.register(HARD_DRIVE_CONTAINER_BLOCK);
HEADS = SimpleItem.register("head", tiers);
PLATTERS = SimpleItem.register("platter", tiers);
DRIVE_CASING = SimpleItem.register("drive_casing");
BusConnectorBlock.register();
SimpleBlockItem.register(BUS_CONNECTOR_BLOCK);
InventoryInterfaceBlock.register();
SimpleBlockItem.register(INVENTORY_INTERFACE_BLOCK);
PCB = SimpleItem.register("pcb", ItemGroups.INGREDIENTS);
PCB_SUBSTRATE = SimpleItem.register("pcb_substrate", ItemGroups.INGREDIENTS);
CPU = SimpleItem.register("cpu", ItemGroups.INGREDIENTS);
CPU_SUBSTRATE = SimpleItem.register("cpu_substrate", ItemGroups.INGREDIENTS);
DRIVE_CONTROLLER = SimpleItem.register("drive_controller", ItemGroups.INGREDIENTS);
DRIVE_CASING = SimpleItem.register("drive_casing", ItemGroups.INGREDIENTS);
MODULES = SimpleItem.register("module", moduleList, false, ItemGroups.INGREDIENTS);
HEADS = SimpleItem.register("head", tiers, ItemGroups.INGREDIENTS);
PLATTERS = SimpleItem.register("platter", tiers, ItemGroups.INGREDIENTS);
DRIVES = HardDriveItem.register(tiers);
PolymerResourcePackUtils.addModAssets(MOD_ID);
PolymerResourcePackUtils.markAsRequired();
@@ -11,13 +11,22 @@ import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.Text;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import systems.brn.server_storage.items.HardDrive;
import systems.brn.server_storage.screenhandlers.DriveContainerScreenHandler;
import java.util.ArrayList;
import static systems.brn.server_storage.ServerStorage.DRIVES;
import static systems.brn.server_storage.ServerStorage.HARD_DRIVE_CONTAINER_BLOCK_ENTITY;
public class HardDriveContainerBlockEntity extends LootableContainerBlockEntity {
private DefaultedList<ItemStack> inventory;
private static final int INVENTORY_SIZE = 9;
public DefaultedList<ItemStack> inventory;
public ArrayList<HardDrive> drives = new ArrayList<>();
public static final int INVENTORY_SIZE = 5;
private int totalSlots;
private int usedSlots;
private int availableSlots;
public HardDriveContainerBlockEntity(BlockPos pos, BlockState state) {
super(HARD_DRIVE_CONTAINER_BLOCK_ENTITY, pos, state);
@@ -65,4 +74,44 @@ public class HardDriveContainerBlockEntity extends LootableContainerBlockEntity
Inventories.writeNbt(nbt, this.inventory, registryLookup);
}
}
public void commitDrives(){
for (int i = 0; i < this.inventory.size(); i++) {
for (HardDrive drive: this.drives) {
if(drive.getContainerIndex() == i){
this.inventory.set(i, drive.getCommitedStack());
break;
}
}
}
}
public void indexDrives() {
drives = new ArrayList<>();
totalSlots = 0;
availableSlots = 0;
usedSlots = 0;
for (int i = 0; i < this.inventory.size(); i++) {
ItemStack stack = this.inventory.get(i);
if (!stack.isEmpty() && DRIVES.contains(stack.getItem())) {
HardDrive drive = new HardDrive(stack, this, i);
totalSlots += drive.getMaxItems();
availableSlots += drive.getAvailableItems();
usedSlots += drive.getUsedItems();
drives.add(drive);
}
}
}
public int getTotalSlots() {
return totalSlots;
}
public int getUsedSlots() {
return usedSlots;
}
public int getAvailableSlots() {
return availableSlots;
}
}
@@ -0,0 +1,173 @@
package systems.brn.server_storage.blockentities;
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.state.property.EnumProperty;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import systems.brn.server_storage.lib.ConnectionType;
import systems.brn.server_storage.lib.StorageNetwork;
import systems.brn.server_storage.screens.SettingsScreen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import static systems.brn.server_storage.ServerStorage.INVENTORY_INTERFACE_BLOCK_ENTITY;
import static systems.brn.server_storage.blocks.ConnectedBlock.getPropertyForDirection;
import static systems.brn.server_storage.lib.StorageOperations.*;
public class InventoryInterfaceBlockEntity extends BlockEntity {
public StorageNetwork network;
public final ArrayList<SettingsScreen> openSettingsScreens = new ArrayList<>();
public boolean isOutput = false;
public String query = "";
public int tickCounter = 0;
public Direction direction = Direction.NORTH;
public InventoryInterfaceBlockEntity(BlockPos pos, BlockState state) {
super(INVENTORY_INTERFACE_BLOCK_ENTITY, pos, state);
}
public void reindexDrives() {
if (this.network != null) {
this.network.reindexNetwork(world, this.pos, false, query);
} else {
this.network = new StorageNetwork(world, this.pos, false, query);
}
}
public void updateDisplays() {
for (SettingsScreen screen : openSettingsScreens) {
screen.updateDisplay();
}
}
public void nextDirection() {
int newId = (direction.getId() + 1) % 6;
direction = Direction.byId(newId);
}
// Serialize the BlockEntity
@Override
public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
// Save the current value of the number to the nbt
nbt.putBoolean("isOutput", isOutput);
nbt.putInt("direction", direction.getId());
nbt.putInt("tickCounter", tickCounter);
nbt.putString("query", query);
super.writeNbt(nbt, wrapperLookup);
}
// Deserialize the BlockEntity
@Override
public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
super.readNbt(nbt, wrapperLookup);
isOutput = nbt.getBoolean("isOutput");
direction = Direction.byId(nbt.getInt("direction"));
tickCounter = nbt.getInt("tickCounter");
query = nbt.getString("query");
}
private static int processIncomingInternal(ItemStack stack, int count, InventoryInterfaceBlockEntity blockEntity, Inventory targetedBlockEntityInventory) {
int maxFit = howMuchFits(stack, targetedBlockEntityInventory);
int finalCount = Math.min(count, maxFit);
ItemStack insertedStack = stack.copy();
insertedStack.setCount(finalCount);
blockEntity.network.removeItemStack(insertedStack);
blockEntity.network.updateDisplays();
int remainingToInsert = finalCount;
for (int i = 0; i < Math.ceilDivExact(finalCount, stack.getMaxCount()); i++) {
ItemStack cappedStack = insertedStack.copy();
cappedStack.setCount(Math.min(insertedStack.getMaxCount(), remainingToInsert));
ItemStack remaining = insertStackIntoInventory(targetedBlockEntityInventory, cappedStack.copy());
if (!remaining.isEmpty()) {
ItemStack reverseStack = stack.copy();
reverseStack.setCount(remaining.getCount() + remainingToInsert);
blockEntity.network.putItemStackRemainder(reverseStack);
break;
}
remainingToInsert -= cappedStack.getCount();
}
return count - (finalCount - remainingToInsert);
}
public int processIncoming(ItemStack stack, int count) {
if (world != null && isOutput && filterItem(stack.getItem(), query)) {
BlockPos targetedPos = pos.offset(direction);
BlockEntity targetedBlockEntity = world.getBlockEntity(targetedPos);
EnumProperty<ConnectionType> connectionType = getPropertyForDirection(direction);
BlockState thisState = world.getBlockState(pos);
if (targetedBlockEntity instanceof Inventory targetedBlockEntityInventory &&
thisState.contains(connectionType) &&
thisState.get(connectionType) == ConnectionType.INVENTORY) {
reindexDrives();
return processIncomingInternal(stack, count, this, targetedBlockEntityInventory);
}
}
return count;
}
public static <T extends BlockEntity> void tick(World world, BlockPos blockPos, BlockState state, T t) {
InventoryInterfaceBlockEntity blockEntity = (InventoryInterfaceBlockEntity) world.getBlockEntity(blockPos);
if (blockEntity != null) {
if (blockEntity.tickCounter == 0) {
BlockPos targetedPos = blockPos.offset(blockEntity.direction);
BlockEntity targetedBlockEntity = world.getBlockEntity(targetedPos);
BlockState thisState = world.getBlockState(blockPos);
EnumProperty<ConnectionType> connectionType = getPropertyForDirection(blockEntity.direction);
if (targetedBlockEntity instanceof Inventory targetedBlockEntityInventory &&
thisState.contains(connectionType) &&
thisState.get(connectionType) == ConnectionType.INVENTORY) {
blockEntity.reindexDrives();
if (blockEntity.isOutput) {
for (Map.Entry<ItemStack, Integer> entry : blockEntity.network.filteredItemStackMap.entrySet()) {
int leftOver = processIncomingInternal(entry.getKey(), entry.getValue(), blockEntity, targetedBlockEntityInventory);
if (leftOver > 0) {
break;
}
}
} else {
Map<ItemStack, Integer> targetedBlockInventoryMap = new HashMap<>();
addInventoryToMap(targetedBlockEntityInventory, targetedBlockInventoryMap);
targetedBlockInventoryMap = sortAndFilterMap(targetedBlockInventoryMap, false, blockEntity.query);
for (Map.Entry<ItemStack, Integer> entry : targetedBlockInventoryMap.entrySet()) {
ItemStack stack = entry.getKey();
int count = entry.getValue();
ItemStack insertingStack = stack.copy();
insertingStack.setCount(count);
if (count > 0) {
int canPutInside = count - blockEntity.network.putItemStackRemainder(insertingStack.copy());
blockEntity.network.updateDisplays();
if (canPutInside > 0) {
removeFromInventory(targetedBlockEntityInventory, insertingStack.copy(), canPutInside);
}
}
}
}
}
}
blockEntity.tickCounter = (blockEntity.tickCounter + 1) % 160;
}
}
public void doSearch(String query) {
this.query = query;
reindexDrives();
updateDisplays();
}
}
@@ -1,181 +0,0 @@
package systems.brn.server_storage.blockentities;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import systems.brn.server_storage.lib.ConnectedChests;
import systems.brn.server_storage.screens.StorageScreen;
import java.util.ArrayList;
import static systems.brn.server_storage.ServerStorage.STORAGE_BLOCK_ENTITY;
public class StorageBlockEntity extends BlockEntity implements Inventory, SidedInventory {
public void removeScreen(StorageScreen storageScreenToDelete) {
openStorageScreens.remove(storageScreenToDelete);
}
public Boolean sortAlphabetically = false;
public Boolean allInventories = false;
public Boolean autoSuck = false;
public String searchString = "";
public int page = 0;
public ConnectedChests chests;
public ArrayList<StorageScreen> openStorageScreens = new ArrayList<>();
public StorageBlockEntity(BlockPos pos, BlockState state) {
super(STORAGE_BLOCK_ENTITY, pos, state);
}
public void rescanChests() {
this.chests = new ConnectedChests(world, this.pos, sortAlphabetically, searchString, allInventories);
if(autoSuck){
this.chests.autoSuck();
}
this.updateDisplays();
}
@Override
public int size() {
if (chests != null) {
this.rescanChests();
return chests.inventory.size();
}
else {
return 1;
}
}
@Override
public boolean isEmpty() {
if (chests != null) {
this.rescanChests();
return chests.inventory.isEmpty();
}
else {
return true;
}
}
@Override
public ItemStack getStack(int slot) {
if (chests != null) {
this.rescanChests();
return chests.inventory.getStack(slot);
}
else {
return ItemStack.EMPTY;
}
}
@Override
public ItemStack removeStack(int slot, int amount) {
if (chests != null) {
ItemStack stackToRemove = chests.inventory.getStack(slot);
stackToRemove.setCount(
Math.min(
Math.min(stackToRemove.getCount(), amount), stackToRemove.getMaxCount())
);
return chests.removeItemStack(stackToRemove);
}
else {
return ItemStack.EMPTY;
}
}
@Override
public ItemStack removeStack(int slot) {
if (chests != null) {
ItemStack stackToRemove = chests.inventory.getStack(slot);
stackToRemove.setCount(Math.min(stackToRemove.getCount(), stackToRemove.getMaxCount()));
return chests.removeItemStack(stackToRemove);
}
else {
return ItemStack.EMPTY;
}
}
@Override
public void setStack(int slot, ItemStack stack) {
chests.tryPutItemStack(stack);
updateDisplays();
}
public void updateDisplays() {
for (StorageScreen screen : openStorageScreens) {
screen.updateDisplay();
}
}
@Override
public boolean canPlayerUse(PlayerEntity player) {
return false;
}
@Override
public void clear() {
// Do nothing, prevent clearing the inventory
}
// SidedInventory methods
@Override
public int[] getAvailableSlots(Direction side) {
if(this.chests != null) {
this.rescanChests();
int[] output = new int[chests.inventory.size()];
for (int i = 0; i < chests.inventory.size() - 1; i++) {
output[i] = i;
}
return output;
}
else {
return new int[0];
}
}
@Override
public boolean canInsert(int slot, ItemStack stack, Direction dir) {
rescanChests();
return chests.canAddItemStack(stack);
}
@Override
public boolean canExtract(int slot, ItemStack stack, Direction dir) {
rescanChests();
return chests.canRemove(stack);
}
// Serialize the BlockEntity
@Override
public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
// Save the current value of the number to the nbt
nbt.putInt("page", page);
nbt.putBoolean("sortAlphabetically", sortAlphabetically);
nbt.putString("searchString", searchString);
nbt.putBoolean("allInventories", allInventories);
nbt.putBoolean("autoSuck", autoSuck);
super.writeNbt(nbt, wrapperLookup);
}
// Deserialize the BlockEntity
@Override
public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
super.readNbt(nbt, wrapperLookup);
page = nbt.getInt("page");
sortAlphabetically = nbt.getBoolean("sortAlphabetically");
searchString = nbt.getString("searchString");
allInventories = nbt.getBoolean("allInventories");
autoSuck = nbt.getBoolean("autoSuck");
}
}
@@ -0,0 +1,71 @@
package systems.brn.server_storage.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.util.math.BlockPos;
import systems.brn.server_storage.lib.StorageNetwork;
import systems.brn.server_storage.screens.StorageScreen;
import java.util.ArrayList;
import static systems.brn.server_storage.ServerStorage.STORAGE_INTERFACE_BLOCK_ENTITY;
public class StorageInterfaceBlockEntity extends BlockEntity {
public void removeScreen(StorageScreen storageScreenToDelete) {
openStorageScreens.remove(storageScreenToDelete);
}
public Boolean sortAlphabetically = false;
public String searchString = "";
public int page = 0;
public StorageNetwork network;
public final ArrayList<StorageScreen> openStorageScreens = new ArrayList<>();
public StorageInterfaceBlockEntity(BlockPos pos, BlockState state) {
super(STORAGE_INTERFACE_BLOCK_ENTITY, pos, state);
}
public void justReindexDrives() {
if (this.network != null) {
this.network.reindexNetwork(world, this.pos, sortAlphabetically, searchString);
} else {
this.network = new StorageNetwork(world, this.pos, sortAlphabetically, searchString);
}
}
public void reindexDrives() {
justReindexDrives();
this.network.updateDisplays();
}
public void updateDisplays() {
for (StorageScreen screen : openStorageScreens) {
screen.updateDisplay();
}
}
// Serialize the BlockEntity
@Override
public void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
// Save the current value of the number to the nbt
nbt.putInt("page", page);
nbt.putBoolean("sortAlphabetically", sortAlphabetically);
nbt.putString("searchString", searchString);
super.writeNbt(nbt, wrapperLookup);
}
// Deserialize the BlockEntity
@Override
public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
super.readNbt(nbt, wrapperLookup);
page = nbt.getInt("page");
sortAlphabetically = nbt.getBoolean("sortAlphabetically");
searchString = nbt.getString("searchString");
}
}
@@ -0,0 +1,40 @@
package systems.brn.server_storage.blocks;
import eu.pb4.polymer.blocks.api.BlockModelType;
import eu.pb4.polymer.blocks.api.PolymerBlockModel;
import eu.pb4.polymer.blocks.api.PolymerBlockResourceUtils;
import eu.pb4.polymer.blocks.api.PolymerTexturedBlock;
import net.minecraft.block.*;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import static systems.brn.server_storage.ServerStorage.*;
public class BusConnectorBlock extends ConnectedBlock implements PolymerTexturedBlock {
final Identifier identifier;
private final BlockState polymerBlockState;
public BusConnectorBlock(Settings settings, Identifier identifier) {
super(settings, Blocks.NOTE_BLOCK);
this.identifier = identifier;
this.polymerBlockState = PolymerBlockResourceUtils.requestBlock(
BlockModelType.FULL_BLOCK,
PolymerBlockModel.of(
identifier.withPath("block/" + identifier.getPath())
)
);
}
@Override
public BlockState getPolymerBlockState(BlockState state) {
return this.polymerBlockState;
}
public static void register() {
var modId = id(BUS_CONNECTOR_MODEL_ID);
BUS_CONNECTOR_BLOCK = Registry.register(Registries.BLOCK, modId,
new BusConnectorBlock(AbstractBlock.Settings.copy(Blocks.WHITE_WOOL), modId));
BUS_CONNECTOR_BLOCK.setDefaultState();
}
}
@@ -0,0 +1,90 @@
package systems.brn.server_storage.blocks;
import eu.pb4.polymer.core.api.block.SimplePolymerBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import systems.brn.server_storage.lib.ConnectionType;
public class ConnectedBlock extends SimplePolymerBlock {
public static final EnumProperty<ConnectionType> NORTH = EnumProperty.of("north", ConnectionType.class);
public static final EnumProperty<ConnectionType> SOUTH = EnumProperty.of("south", ConnectionType.class);
public static final EnumProperty<ConnectionType> WEST = EnumProperty.of("west", ConnectionType.class);
public static final EnumProperty<ConnectionType> EAST = EnumProperty.of("east", ConnectionType.class);
public static final EnumProperty<ConnectionType> UP = EnumProperty.of("up", ConnectionType.class);
public static final EnumProperty<ConnectionType> DOWN = EnumProperty.of("down", ConnectionType.class);
public void setDefaultState() {
setDefaultState(getStateManager().getDefaultState()
.with(NORTH, ConnectionType.NONE)
.with(SOUTH, ConnectionType.NONE)
.with(WEST, ConnectionType.NONE)
.with(EAST, ConnectionType.NONE)
.with(UP, ConnectionType.NONE)
.with(DOWN, ConnectionType.NONE));
}
public ConnectedBlock(Settings settings, Block block) {
super(settings, block);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
super.onPlaced(world, pos, state, placer, itemStack);
updateBlockState(world, pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(NORTH, SOUTH, WEST, EAST, UP, DOWN);
}
public void updateBlockState(World world, BlockPos pos, BlockState state) {
world.setBlockState(pos, updateState(state, world, pos), Block.NOTIFY_LISTENERS);
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
updateBlockState(world, pos, state);
super.neighborUpdate(state, world, pos, block, fromPos, notify);
}
private BlockState updateState(BlockState state, World world, BlockPos pos) {
for (Direction direction : Direction.values()) {
BlockPos neighborPos = pos.offset(direction);
BlockState neighborState = world.getBlockState(neighborPos);
boolean isConnectedToBus = neighborState.getBlock() instanceof ConnectedBlock;
BlockEntity blockEntity = world.getBlockEntity(neighborPos);
boolean isConnectedToInventory = blockEntity instanceof Inventory;
ConnectionType connectionType = ConnectionType.NONE;
if (isConnectedToBus){
connectionType = ConnectionType.BUS;
} else if (isConnectedToInventory){
connectionType = ConnectionType.INVENTORY;
}
state = state.with(getPropertyForDirection(direction), connectionType);
}
return state;
}
public static EnumProperty<ConnectionType> getPropertyForDirection(Direction direction) {
return switch (direction) {
case NORTH -> NORTH;
case SOUTH -> SOUTH;
case WEST -> WEST;
case EAST -> EAST;
case UP -> UP;
case DOWN -> DOWN;
};
}
}
@@ -5,7 +5,6 @@ import eu.pb4.polymer.blocks.api.PolymerBlockModel;
import eu.pb4.polymer.blocks.api.PolymerBlockResourceUtils;
import eu.pb4.polymer.blocks.api.PolymerTexturedBlock;
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
import eu.pb4.polymer.core.api.block.SimplePolymerBlock;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
@@ -29,7 +28,7 @@ import systems.brn.server_storage.blockentities.HardDriveContainerBlockEntity;
import static systems.brn.server_storage.ServerStorage.*;
public class HardDriveContainerBlock extends SimplePolymerBlock implements PolymerTexturedBlock, BlockEntityProvider {
public class HardDriveContainerBlock extends ConnectedBlock implements PolymerTexturedBlock, BlockEntityProvider {
final Identifier identifier;
public static final DirectionProperty FACING = FacingBlock.FACING;
@@ -49,6 +48,7 @@ public class HardDriveContainerBlock extends SimplePolymerBlock implements Polym
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FACING);
}
@@ -63,12 +63,14 @@ public class HardDriveContainerBlock extends SimplePolymerBlock implements Polym
new HardDriveContainerBlock(Settings.copy(Blocks.WHITE_WOOL), modId));
UseBlockCallback.EVENT.register(HardDriveContainerBlock::onUse);
HARD_DRIVE_CONTAINER_BLOCK.setDefaultState();
HARD_DRIVE_CONTAINER_BLOCK_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE,
modId,
BlockEntityType.Builder.create(HardDriveContainerBlockEntity::new, HARD_DRIVE_CONTAINER_BLOCK).build(null)
);
PolymerBlockUtils.registerBlockEntity(STORAGE_BLOCK_ENTITY);
PolymerBlockUtils.registerBlockEntity(STORAGE_INTERFACE_BLOCK_ENTITY);
}
private static ActionResult onUse(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
@@ -0,0 +1,179 @@
package systems.brn.server_storage.blocks;
import eu.pb4.polymer.blocks.api.BlockModelType;
import eu.pb4.polymer.blocks.api.PolymerBlockModel;
import eu.pb4.polymer.blocks.api.PolymerBlockResourceUtils;
import eu.pb4.polymer.blocks.api.PolymerTexturedBlock;
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
import eu.pb4.sgui.api.elements.GuiElementBuilder;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
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.Items;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.DirectionProperty;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
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.server_storage.blockentities.InventoryInterfaceBlockEntity;
import systems.brn.server_storage.lib.PagedGui;
import systems.brn.server_storage.screens.SearchScreen;
import systems.brn.server_storage.screens.SettingsScreen;
import static systems.brn.server_storage.ServerStorage.*;
import static systems.brn.server_storage.lib.PagedGui.*;
public class InventoryInterfaceBlock extends ConnectedBlock implements PolymerTexturedBlock, BlockEntityProvider {
final Identifier identifier;
public static final DirectionProperty FACING = FacingBlock.FACING;
private final BlockState polymerBlockState;
public InventoryInterfaceBlock(Settings settings, Identifier identifier) {
super(settings, Blocks.NOTE_BLOCK);
this.identifier = identifier;
this.setDefaultState(this.stateManager.getDefaultState().with(FACING, Direction.NORTH));
this.polymerBlockState = PolymerBlockResourceUtils.requestBlock(BlockModelType.FULL_BLOCK, PolymerBlockModel.of(identifier.withPath("block/" + identifier.getPath())));
}
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return this.getDefaultState().with(FACING, ctx.getHorizontalPlayerFacing().getOpposite());
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FACING);
}
@Override
public BlockState getPolymerBlockState(BlockState state) {
return this.polymerBlockState;
}
public static void register() {
var modId = id(INVENTORY_INTERFACE_BLOCK_MODEL_ID);
INVENTORY_INTERFACE_BLOCK = Registry.register(Registries.BLOCK, modId,
new InventoryInterfaceBlock(Settings.copy(Blocks.WHITE_WOOL), modId));
UseBlockCallback.EVENT.register(InventoryInterfaceBlock::onUse);
INVENTORY_INTERFACE_BLOCK.setDefaultState();
INVENTORY_INTERFACE_BLOCK_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE,
modId,
BlockEntityType.Builder.create(InventoryInterfaceBlockEntity::new, INVENTORY_INTERFACE_BLOCK).build(null)
);
PolymerBlockUtils.registerBlockEntity(INVENTORY_INTERFACE_BLOCK_ENTITY);
}
private static void loadSettings(SettingsScreen settingsScreen, InventoryInterfaceBlockEntity blockEntity) {
settingsScreen.clearSettings();
settingsScreen.addSetting(PagedGui.DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable(switch (blockEntity.direction) {
case NORTH -> "gui.serverstorage.direction_north";
case SOUTH -> "gui.serverstorage.direction_south";
case WEST -> "gui.serverstorage.direction_west";
case EAST -> "gui.serverstorage.direction_east";
case UP -> "gui.serverstorage.direction_up";
case DOWN -> "gui.serverstorage.direction_down";
}).formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(switch (blockEntity.direction) {
case NORTH -> GUI_SIDE_NORTH;
case SOUTH -> GUI_SIDE_SOUTH;
case WEST -> GUI_SIDE_WEST;
case EAST -> GUI_SIDE_EAST;
case UP -> GUI_SIDE_UP;
case DOWN -> GUI_SIDE_DOWN;
})
.setCallback((x, y, z) -> {
playClickSound(settingsScreen.getPlayer());
blockEntity.nextDirection();
loadSettings(settingsScreen, blockEntity);
blockEntity.updateDisplays();
})
));
settingsScreen.addSetting(PagedGui.DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable(blockEntity.isOutput ? "gui.serverstorage.mode_output" : "gui.serverstorage.mode_input").formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(blockEntity.isOutput ? GUI_MODE_OUTPUT : GUI_MODE_INPUT)
.setCallback((x, y, z) -> {
playClickSound(settingsScreen.getPlayer());
blockEntity.isOutput ^= true;
loadSettings(settingsScreen, blockEntity);
blockEntity.updateDisplays();
})
));
String queryNow = blockEntity.query;
if (queryNow == null || queryNow.isEmpty() || queryNow.equals("*")) {
queryNow = "Filter not set";
}
settingsScreen.addSetting(PagedGui.DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.literal(queryNow).formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(GUI_QUESTION_MARK)
.setCallback((x, y, z) -> {
SearchScreen searchScreen = new SearchScreen(settingsScreen, "");
playClickSound(settingsScreen.getPlayer());
searchScreen.open();
})
));
}
private static ActionResult onUse(PlayerEntity playerEntity, World world, Hand hand, BlockHitResult hitResult) {
BlockPos pos = hitResult.getBlockPos();
BlockState state = world.getBlockState(pos);
Block block = state.getBlock();
if (block instanceof InventoryInterfaceBlock) {
BlockEntity tempBlockEntity = world.getBlockEntity(pos);
if (tempBlockEntity instanceof InventoryInterfaceBlockEntity blockEntity) {
if (!world.isClient && !playerEntity.isSpectator()) {
ServerPlayerEntity player = (ServerPlayerEntity) playerEntity;
if (!player.isSneaking()) {
SettingsScreen settingsScreen = new SettingsScreen(player, blockEntity);
blockEntity.reindexDrives();
loadSettings(settingsScreen, blockEntity);
settingsScreen.updateDisplay();
settingsScreen.open();
} else {
return ActionResult.PASS;
}
}
return ActionResult.SUCCESS;
}
}
return ActionResult.PASS;
}
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return world instanceof ServerWorld && type == INVENTORY_INTERFACE_BLOCK_ENTITY ? InventoryInterfaceBlockEntity::tick : null;
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new InventoryInterfaceBlockEntity(pos, state);
}
}
@@ -5,7 +5,6 @@ import eu.pb4.polymer.blocks.api.PolymerBlockModel;
import eu.pb4.polymer.blocks.api.PolymerBlockResourceUtils;
import eu.pb4.polymer.blocks.api.PolymerTexturedBlock;
import eu.pb4.polymer.core.api.block.PolymerBlockUtils;
import eu.pb4.polymer.core.api.block.SimplePolymerBlock;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
@@ -31,7 +30,7 @@ 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.blockentities.StorageBlockEntity;
import systems.brn.server_storage.blockentities.StorageInterfaceBlockEntity;
import systems.brn.server_storage.screens.StorageScreen;
import java.util.List;
@@ -39,12 +38,12 @@ import java.util.List;
import static systems.brn.server_storage.ServerStorage.*;
import static systems.brn.server_storage.lib.Util.generateBookContent;
public class StorageBlock extends SimplePolymerBlock implements PolymerTexturedBlock, BlockEntityProvider {
public class StorageInterfaceBlock extends ConnectedBlock implements PolymerTexturedBlock, BlockEntityProvider {
final Identifier identifier;
public static final DirectionProperty FACING = FacingBlock.FACING;
private final BlockState polymerBlockState;
public StorageBlock(Settings settings, Identifier identifier) {
public StorageInterfaceBlock(Settings settings, Identifier identifier) {
super(settings, Blocks.NOTE_BLOCK);
this.identifier = identifier;
this.setDefaultState(this.stateManager.getDefaultState().with(FACING, Direction.NORTH));
@@ -58,6 +57,7 @@ public class StorageBlock extends SimplePolymerBlock implements PolymerTexturedB
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FACING);
}
@@ -68,16 +68,16 @@ public class StorageBlock extends SimplePolymerBlock implements PolymerTexturedB
public static void register() {
var modId = id(STORAGE_MODEL_ID);
STORAGE_BLOCK = Registry.register(Registries.BLOCK, modId,
new StorageBlock(AbstractBlock.Settings.copy(Blocks.WHITE_WOOL), modId));
UseBlockCallback.EVENT.register(StorageBlock::onUse);
STORAGE_BLOCK_ENTITY = Registry.register(
STORAGE_INTERFACE_BLOCK = Registry.register(Registries.BLOCK, modId,
new StorageInterfaceBlock(AbstractBlock.Settings.copy(Blocks.WHITE_WOOL), modId));
UseBlockCallback.EVENT.register(StorageInterfaceBlock::onUse);
STORAGE_INTERFACE_BLOCK.setDefaultState();
STORAGE_INTERFACE_BLOCK_ENTITY = Registry.register(
Registries.BLOCK_ENTITY_TYPE,
modId,
BlockEntityType.Builder.create(StorageBlockEntity::new, STORAGE_BLOCK).build(null)
BlockEntityType.Builder.create(StorageInterfaceBlockEntity::new, STORAGE_INTERFACE_BLOCK).build(null)
);
PolymerBlockUtils.registerBlockEntity(STORAGE_BLOCK_ENTITY);
PolymerBlockUtils.registerBlockEntity(STORAGE_INTERFACE_BLOCK_ENTITY);
}
private static ActionResult onUse(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
@@ -85,17 +85,18 @@ public class StorageBlock extends SimplePolymerBlock implements PolymerTexturedB
BlockState state = world.getBlockState(pos);
Block block = state.getBlock();
if (block instanceof StorageBlock) {
if (block instanceof StorageInterfaceBlock) {
if (!world.isClient && !player.isSpectator()) {
if (!player.isSneaking()) {
StorageScreen storageScreen = new StorageScreen((ServerPlayerEntity) player, pos, null);
storageScreen.updateDisplay();
storageScreen.open();
} else if (player.getStackInHand(hand).getItem() == Items.WRITTEN_BOOK) {
ItemStack book = player.getStackInHand(hand);
StorageBlockEntity storageBlockEntity = (StorageBlockEntity) world.getBlockEntity(pos);
assert storageBlockEntity != null;
List<RawFilteredPair<Text>> generatedContent = generateBookContent(storageBlockEntity.chests.inventory);
StorageInterfaceBlockEntity storageInterfaceBlockEntity = (StorageInterfaceBlockEntity) world.getBlockEntity(pos);
assert storageInterfaceBlockEntity != null;
List<RawFilteredPair<Text>> generatedContent = generateBookContent(storageInterfaceBlockEntity.network.itemStackMap);
book.set(DataComponentTypes.WRITTEN_BOOK_CONTENT, new WrittenBookContentComponent(
RawFilteredPair.of("Item Listing"),
player.getGameProfile().getName(),
@@ -115,6 +116,6 @@ public class StorageBlock extends SimplePolymerBlock implements PolymerTexturedB
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new StorageBlockEntity(pos, state);
return new StorageInterfaceBlockEntity(pos, state);
}
}
@@ -0,0 +1,300 @@
package systems.brn.server_storage.items;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.LoreComponent;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import systems.brn.server_storage.blockentities.HardDriveContainerBlockEntity;
import java.util.*;
import static systems.brn.server_storage.lib.DriveComponents.*;
import static systems.brn.server_storage.lib.StorageOperations.canCombine;
public class HardDrive {
private ItemStack driveStack;
public final HardDriveContainerBlockEntity blockEntity;
private int containerIndex;
private int maxItems;
private int usedItems;
private int availableItems;
private final UUID myUUID;
private int tier;
public Map<ItemStack, Integer> items;
public void loadComponents() {
Map<ItemStack, Integer> loadedItems = driveStack.getComponents().getOrDefault(ITEMSTACK_MAP, new HashMap<>());
if (this.items == null) {
this.items = loadedItems;
}
updateData();
}
public void setMaxItems() {
String itemName = driveStack.getItem().getRegistryEntry().registryKey().getValue().getPath();
switch (itemName) {
case "iron_drive":
tier = 0;
break;
case "golden_drive":
tier = 1;
break;
case "diamond_drive":
tier = 2;
break;
case "netherite_drive":
tier = 3;
break;
default:
tier = -1;
break;
}
maxItems = 0;
if (tier >= 0) {
maxItems = (int) Math.pow(2, tier + 8);
}
}
public void updateData() {
usedItems = 0;
for (Map.Entry<ItemStack, Integer> entry : items.entrySet()) {
if (entry.getKey().getItem() == Items.AIR) {
items.remove(entry.getKey());
} else {
usedItems += entry.getValue();
}
}
addLoreInfo();
availableItems = maxItems - usedItems;
assert maxItems >= usedItems;
assert usedItems >= 0;
}
public void saveComponents() {
ItemStack tempStack = driveStack.copy();
HashMap<ItemStack, Integer> itemsTemp = new HashMap<>();
for (Map.Entry<ItemStack, Integer> entry : items.entrySet()) {
int count = entry.getKey().getCount();
if (count > entry.getKey().getMaxCount()) {
count = entry.getKey().getMaxCount();
}
ItemStack limitedStack = entry.getKey().copy();
limitedStack.setCount(count);
itemsTemp.put(limitedStack, entry.getValue());
}
tempStack.remove(ITEMSTACK_MAP);
tempStack.set(ITEMSTACK_MAP, itemsTemp);
driveStack = tempStack;
}
private boolean isNotTheSameDrive(ItemStack currentStack) {
return currentStack.getItem() != driveStack.getItem() || (currentStack.contains(UUID_COMPONENT) && currentStack.get(UUID_COMPONENT) != myUUID);
}
public ItemStack getCommitedStack() {
ItemStack tempDriveStack = driveStack.copy();
driveStack = ensureUUID(tempDriveStack);
loadComponents();
updateData();
saveComponents();
return driveStack;
}
public void commitChangesToContainer() {
getCommitedStack();
ItemStack currentStack = blockEntity.inventory.get(containerIndex);
boolean updated = false;
if (isNotTheSameDrive(currentStack)) {
updateIndex();
updated = true;
}
if (updated && isNotTheSameDrive(currentStack)) {
return;
}
blockEntity.inventory.set(containerIndex, driveStack);
blockEntity.markDirty();
}
public ItemStack removeStackFromInventory(ItemStack stack) {
int outCount = 0;
ItemStack outStack = stack.copy();
for (Map.Entry<ItemStack, Integer> entry : items.entrySet()) {
if (canCombine(entry.getKey(), stack)) {
int countInDrive = entry.getValue();
int needToRemove = stack.getCount();
if (countInDrive <= needToRemove) {
items.remove(entry.getKey());
needToRemove -= countInDrive;
outCount += needToRemove;
} else {
entry.setValue(countInDrive - needToRemove);
}
break;
}
}
outStack.setCount(outCount);
commitChangesToContainer();
blockEntity.markDirty();
return outStack;
}
public ItemStack insertStackIntoInventory(ItemStack stack) {
// First, try to merge with existing stacks
boolean merged = false;
if (stack.isEmpty()) {
return stack;
}
int transferAmount = Math.min(stack.getCount(), availableItems);
if (transferAmount > 0) {
for (Map.Entry<ItemStack, Integer> entry : items.entrySet()) {
ItemStack slotStack = entry.getKey();
if (canCombine(slotStack, stack)) {
entry.setValue(transferAmount + entry.getValue());
stack.decrement(transferAmount);
merged = true;
break;
}
}
if (!merged) {
ItemStack inStack = stack.copy();
inStack.capCount(inStack.getMaxCount());
items.put(inStack, transferAmount);
stack.decrement(transferAmount);
}
}
commitChangesToContainer();
blockEntity.markDirty();
if (stack.isEmpty() || stack.getCount() < 1) {
return ItemStack.EMPTY;
} else {
return stack;
}
}
private void addLoreInfo() {
ItemStack tempDriveStack = driveStack.copy();
Formatting availableLineFormatting;
Formatting usedLineFormatting;
if (usedItems > maxItems){
usedLineFormatting = Formatting.LIGHT_PURPLE;
} else if (usedItems == maxItems) {
usedLineFormatting = Formatting.RED;
} else if (usedItems >= maxItems * 0.8){
usedLineFormatting = Formatting.YELLOW;
} else if (usedItems >= maxItems * 0.5){
usedLineFormatting = Formatting.GOLD;
} else {
usedLineFormatting = Formatting.GREEN;
}
if (usedItems > maxItems) {
availableLineFormatting = Formatting.LIGHT_PURPLE; //how did you do this
} else if (usedItems == maxItems) {
availableLineFormatting = Formatting.RED; // full
} else if (usedItems >= maxItems * 0.9) {
availableLineFormatting = Formatting.YELLOW; //90% or more full
} else {
availableLineFormatting = Formatting.GREEN; //good
}
Formatting totalLineFormatting = switch (tier) {
case 0 -> Formatting.DARK_GRAY;
case 1 -> Formatting.GOLD;
case 2 -> Formatting.AQUA;
case 3 -> Formatting.BLACK;
default -> Formatting.OBFUSCATED;
};
Text usedLine = Text.literal("Used slots: " + usedItems).setStyle(Style.EMPTY.withColor(usedLineFormatting).withItalic(true));
Text availableLine = Text.literal("Available slots: " + availableItems).setStyle(Style.EMPTY.withColor(availableLineFormatting).withItalic(true));
Text totalLine = Text.literal("Total slots: " + maxItems).setStyle(Style.EMPTY.withColor(totalLineFormatting).withItalic(true));
LoreComponent newLore;
List<Text> loreList = new ArrayList<>();
loreList.add(availableLine);
loreList.add(usedLine);
loreList.add(totalLine);
newLore = new LoreComponent(loreList);
tempDriveStack.set(DataComponentTypes.LORE, newLore);
driveStack = tempDriveStack;
}
private void updateIndex() {
for (int i = 0; i < blockEntity.inventory.size(); i++) {
ItemStack stack = blockEntity.inventory.get(i);
UUID foundUUID = stack.getOrDefault(UUID_COMPONENT, null);
if (foundUUID != null && foundUUID.equals(myUUID)) {
containerIndex = i;
break;
}
}
}
public HardDrive(ItemStack driveStack, HardDriveContainerBlockEntity blockEntity, int containerIndex) {
this.driveStack = driveStack;
this.blockEntity = blockEntity;
this.myUUID = driveStack.get(UUID_COMPONENT);
this.containerIndex = containerIndex;
setMaxItems();
loadComponents();
updateData();
}
public int getMaxItems() {
return maxItems;
}
public int getAvailableItems() {
return availableItems;
}
public int getUsedItems() {
return usedItems;
}
public Map<ItemStack, Integer> addToMap(Map<ItemStack, Integer> itemStackMap) {
for (Map.Entry<ItemStack, Integer> diskEntry : items.entrySet()) {
boolean found = false;
for (Map.Entry<ItemStack, Integer> mapEntry : itemStackMap.entrySet()) {
ItemStack existingStack = mapEntry.getKey();
if (ItemStack.areItemsAndComponentsEqual(diskEntry.getKey(), existingStack)) {
int newCount = mapEntry.getValue() + diskEntry.getValue();
itemStackMap.put(existingStack, newCount);
found = true;
break;
}
}
if (!found) {
itemStackMap.put(diskEntry.getKey(), diskEntry.getValue());
}
}
return itemStackMap;
}
public int getContainerIndex() {
return containerIndex;
}
public static ItemStack ensureUUID(ItemStack driveStack) {
if (driveStack.getComponents().contains(UUID_COMPONENT)) {
return driveStack;
} else {
ItemStack tempStack = driveStack.copy();
tempStack.set(UUID_COMPONENT, UUID.randomUUID());
return tempStack;
}
}
}
@@ -21,18 +21,14 @@ public class HardDriveItem extends SimpleItem {
public static List<Item> register(List<String> tiers){
ArrayList<Item> items = new ArrayList<>();
int numberItems = 128;
for (String tier : tiers) {
Identifier identifier = id(tier + "_drive");
Item item = Registry.register(Registries.ITEM, identifier, new SimpleItem(new Settings()
.maxCount(1)
.component(DriveComponents.MAX_ITEMS, numberItems)
.component(DriveComponents.USED_ITEMS, 0)
.component(DriveComponents.ITEMSTACK_MAP, new HashMap<>())
, identifier));
ItemGroupEvents.modifyEntriesEvent(ItemGroups.FUNCTIONAL).register(content -> content.add(item));
items.add(item);
numberItems *= 2;
}
return items;
}
@@ -5,12 +5,10 @@ import eu.pb4.polymer.core.api.item.SimplePolymerItem;
import eu.pb4.polymer.resourcepack.api.PolymerModelData;
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroups;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.*;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
@@ -38,25 +36,35 @@ public class SimpleItem extends SimplePolymerItem implements PolymerItem {
return this.polymerModel.value();
}
public static Item register(String name){
return register(name, 64);
public static Item register(String name, RegistryKey<ItemGroup> group){
return register(name, 64, group);
}
public static Item register(String name, int maxCount) {
public static Item register(String name, int maxCount, RegistryKey<ItemGroup> group) {
Identifier identifier = id(name);
Item item = Registry.register(Registries.ITEM, identifier, new SimpleItem(new Settings().maxCount(maxCount), identifier));
ItemGroupEvents.modifyEntriesEvent(ItemGroups.FUNCTIONAL).register(content -> content.add(item));
ItemGroupEvents.modifyEntriesEvent(group).register(content -> content.add(item));
return item;
}
public static List<Item> register(String name, List<String> tiers) {
return register(name, tiers, 64);
public static List<Item> register(String name, List<String> tiers, boolean tierFirst, RegistryKey<ItemGroup> group) {
return register(name, tiers, 64, tierFirst, group);
}
public static List<Item> register(String name, List<String> tiers, int maxCount) {
public static List<Item> register(String name, List<String> tiers, RegistryKey<ItemGroup> group) {
return register(name, tiers, 64, true, group);
}
public static List<Item> register(String name, List<String> tiers, int maxCount, boolean tierFirst, RegistryKey<ItemGroup> group) {
ArrayList<Item> items = new ArrayList<>();
for (String tier : tiers) {
items.add(SimpleItem.register(tier + "_" + name, maxCount));
String itemName;
if (tierFirst){
itemName = tier + "_" + name;
} else {
itemName = name + "_" + tier;
}
items.add(SimpleItem.register(itemName, maxCount, group));
}
return items;
}
@@ -1,212 +0,0 @@
package systems.brn.server_storage.lib;
import net.minecraft.block.entity.*;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import systems.brn.server_storage.blockentities.HardDriveContainerBlockEntity;
import systems.brn.server_storage.blockentities.StorageBlockEntity;
import systems.brn.server_storage.items.HardDriveItem;
import java.util.*;
import static systems.brn.server_storage.lib.StorageOperations.*;
public class ConnectedChests {
public final List<Inventory> inventories;
public final List<Inventory> hoppers;
public final List<Inventory> driveContainers;
public final List<HardDriveItem> drives;
public final Inventory inventory;
public final int containerCount;
public final int containerSlots;
public final int containerUsedSlots;
public final int containerFreeSlots;
public ConnectedChests(World world, BlockPos startPos, boolean sortAlphabetically, String searchString, boolean allInventories) {
List<Inventory> inventories = new ArrayList<>();
List<Inventory> hoppers = new ArrayList<>();
List<Inventory> driveContainers = new ArrayList<>();
List<HardDriveItem> drives = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>();
getConnectedChestsHelper(world, startPos, inventories, hoppers, driveContainers, drives, visited, allInventories);
this.inventories = inventories;
this.hoppers = hoppers;
this.driveContainers = driveContainers;
this.drives = drives;
this.containerCount = inventories.size();
this.inventory = getCombinedInventory(sortAlphabetically, searchString);
int tempContainerSlots = 0;
int tempContainerUsedSlots = 0;
int tempContainerFreeSlots = 0;
for (Inventory inventory : inventories) {
tempContainerSlots += inventory.size();
for (int slot = 0; slot < inventory.size(); slot++) {
if (inventory.getStack(slot).isEmpty()) {
tempContainerFreeSlots++;
} else {
tempContainerUsedSlots++;
}
}
assert tempContainerSlots == tempContainerUsedSlots + tempContainerFreeSlots;
}
containerSlots = tempContainerSlots;
containerUsedSlots = tempContainerUsedSlots;
containerFreeSlots = tempContainerFreeSlots;
}
private static boolean isEnabledContainer(BlockEntity blockEntity, boolean allContainers) {
return (allContainers && blockEntity instanceof Inventory) ||
blockEntity instanceof BarrelBlockEntity ||
blockEntity instanceof ChestBlockEntity ||
blockEntity instanceof ShulkerBoxBlockEntity;
}
private static void getConnectedChestsHelper(World world, BlockPos pos, List<Inventory> inventories, List<Inventory> hoppers, List<Inventory> driveContainers, List<HardDriveItem> drives, Set<BlockPos> visited, Boolean allContainers) {
if (visited.contains(pos)) {
return;
}
visited.add(pos);
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof HardDriveContainerBlockEntity) {
driveContainers.add((Inventory) blockEntity);
//loop over all items in inventory
for (int slot = 0; slot < inventories.size(); slot++) {
ItemStack slotStack = ((Inventory) blockEntity).getStack(slot);
//drives.add(new HardDriveItem(slotStack, (HardDriveContainerBlockEntity) blockEntity));
}
}
if (isEnabledHopper(blockEntity)) {
hoppers.add((Inventory) blockEntity);
}
if (isEnabledContainer(blockEntity, allContainers) || blockEntity instanceof StorageBlockEntity) {
if (isEnabledContainer(blockEntity, allContainers) && !(blockEntity instanceof StorageBlockEntity)) {
inventories.add((Inventory) blockEntity);
}
for (Direction direction : Direction.values()) {
BlockPos nextPos = pos.offset(direction);
getConnectedChestsHelper(world, nextPos, inventories, hoppers, driveContainers, drives, visited, allContainers);
}
}
}
// Modify getCombinedInventoryFromChests to include item metadata and combine stacks
private SimpleInventory getCombinedInventory(boolean sortAlphabetically, String query) {
Map<ItemStack, Integer> itemStackMap = new HashMap<>();
for (Inventory inventory : inventories) {
addInventoryToMap(inventory, itemStackMap);
}
return filterInventory(getSimpleInventory(itemStackMap.size(), itemStackMap, sortAlphabetically), query, sortAlphabetically);
}
// Modify filterInventory to include item metadata
private SimpleInventory filterInventory(SimpleInventory inventory, String query, boolean sortAlphabetically) {
if (query == null || query.isEmpty()) {
return inventory;
}
Map<ItemStack, Integer> itemStackMap = new HashMap<>();
int itemCount = 0;
for (int slot = 0; slot < inventory.size(); slot++) {
ItemStack stack = inventory.getStack(slot);
ItemStack filteredStack = filterStack(stack, query);
if (!filteredStack.isEmpty()) {
itemCount++;
int count = itemStackMap.getOrDefault(filteredStack, 0) + filteredStack.getCount();
itemStackMap.put(filteredStack, count);
}
}
return getSimpleInventory(itemCount, itemStackMap, sortAlphabetically);
}
public boolean tryPutItemStack(ItemStack stack) {
// Iterate over each chest to try and insert the ItemStack
for (Inventory chest : inventories) {
if (!(chest instanceof HopperBlockEntity)) {
stack = insertStackIntoInventory(chest, stack);
if (stack.isEmpty()) {
return true;
}
}
}
// If we still have remaining items, return false
return stack.isEmpty();
}
public static boolean isEnabledHopper(BlockEntity blockEntity) {
return blockEntity instanceof HopperBlockEntity ||
blockEntity instanceof TrappedChestBlockEntity ||
blockEntity instanceof FurnaceBlockEntity ||
blockEntity instanceof BlastFurnaceBlockEntity ||
blockEntity instanceof SmokerBlockEntity ||
blockEntity instanceof BrewingStandBlockEntity;
}
public boolean canAddItemStack(ItemStack stack) {
// Iterate over each chest to check if it's possible to insert the ItemStack
for (Inventory chest : inventories) {
if (!(chest instanceof HopperBlockEntity)) {
// Attempt to insert the ItemStack into the current chest
for (int i = 0; i < chest.size(); i++) {
ItemStack slotStack = chest.getStack(i);
if (slotStack.isEmpty() || canCombine(slotStack, stack)) {
// If the slot is empty or can be combined with the ItemStack, return true
return true;
}
}
}
}
// If it's not possible to insert into any chest, return false
return false;
}
public void autoSuck() {
for (Inventory chest : hoppers) {
for (int i = 0; i < chest.size(); i++) {
ItemStack slotStack = chest.getStack(i);
if (!slotStack.isEmpty()) {
if (this.canAddItemStack(slotStack)) {
if (this.tryPutItemStack(slotStack)) {
removeFromInventory(chest, slotStack, slotStack.getCount());
}
;
} else {
return;
}
}
}
}
}
public boolean canRemove(ItemStack stackToRemove) {
return canRemoveCount(stackToRemove, inventory) == 0;
}
public ItemStack removeItemStack(ItemStack stackToRemove) {
int remainingToRemove = stackToRemove.getCount();
ItemStack outStack = stackToRemove.copy();
for (Inventory chest : inventories) {
remainingToRemove = removeFromInventory(chest, stackToRemove, remainingToRemove);
if (remainingToRemove <= 0) {
return outStack;
}
}
outStack.setCount(outStack.getCount() - remainingToRemove);
return outStack;
}
}
@@ -0,0 +1,24 @@
package systems.brn.server_storage.lib;
import net.minecraft.util.StringIdentifiable;
public enum ConnectionType implements StringIdentifiable {
NONE("none"),
BUS("bus"),
INVENTORY("inventory");
private final String name;
ConnectionType(String name) {
this.name = name;
}
@Override
public String asString() {
return this.name;
}
@Override
public String toString() {
return this.name;
}
}
@@ -1,34 +1,50 @@
package systems.brn.server_storage.lib;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import eu.pb4.polymer.core.api.other.PolymerComponent;
import net.minecraft.component.ComponentType;
import net.minecraft.item.ItemStack;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.dynamic.Codecs;
import java.util.Map;
import java.util.*;
import java.util.function.UnaryOperator;
public class DriveComponents {
public static final Codec<Map<ItemStack, Integer>> ITEMSTACK_MAP_CODEC = Codec.unboundedMap(ItemStack.CODEC, Codec.INT);
public static final Codec<List<ItemStack>> ITEMSTACK_LIST_CODEC = Codec.list(ItemStack.CODEC);
public static final Codec<List<Integer>> INTEGER_LIST_CODEC = Codec.list(Codec.INT);
public static final ComponentType<Integer> MAX_ITEMS = register(
"max_items", builder -> builder.codec(Codecs.POSITIVE_INT).packetCodec(PacketCodecs.VAR_INT)
public static final Codec<Map<ItemStack, Integer>> ITEMSTACK_MAP_CODEC = RecordCodecBuilder.create(instance ->
instance.group(
ITEMSTACK_LIST_CODEC.fieldOf("itemStacks").forGetter(map -> new ArrayList<>(map.keySet())),
INTEGER_LIST_CODEC.fieldOf("counts").forGetter(map -> new ArrayList<>(map.values()))
).apply(instance, (itemStacks, counts) -> {
Map<ItemStack, Integer> map = new HashMap<>();
for (int i = 0; i < itemStacks.size(); i++) {
map.put(itemStacks.get(i), counts.get(i));
}
return map;
})
);
public static final ComponentType<Integer> USED_ITEMS = register(
"used_items", builder -> builder.codec(Codecs.NONNEGATIVE_INT).packetCodec(PacketCodecs.VAR_INT)
);
public static final Codec<UUID> UUID_CODEC = RecordCodecBuilder.create(instance ->
instance.group(
Codec.LONG.fieldOf("mostSigBits").forGetter(UUID::getMostSignificantBits),
Codec.LONG.fieldOf("leastSigBits").forGetter(UUID::getLeastSignificantBits)
).apply(instance, UUID::new));
public static final ComponentType<Map<ItemStack, Integer>> ITEMSTACK_MAP = register(
"itemstack_map",
builder -> builder.codec(ITEMSTACK_MAP_CODEC) // No packetCodec needed for this example
);
public static final ComponentType<UUID> UUID_COMPONENT = register(
"drive_uuid",
builder -> builder.codec(UUID_CODEC) // No packetCodec needed for this example
);
private static <T> ComponentType<T> register(String id, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
ComponentType<T> componentType = Registry.register(
@@ -37,6 +37,15 @@ public abstract class PagedGui extends SimpleGui {
public static final String GUI_AUTOSUCK_OFF = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGViODFlZjg5MDIzNzk2NTBiYTc5ZjQ1NzIzZDZiOWM4ODgzODhhMDBmYzRlMTkyZjM0NTRmZTE5Mzg4MmVlMSJ9fX0=";
public static final String GUI_AUTOSUCK_ON = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMThjNDQzYWRhNmUzOWZjYTgzN2EwMzgzYjBhNWUzZTU1NDc3M2I5NjYwYzQ4NzNmNTkxMDMyZGJlOWFkY2RmOCJ9fX0=";
public static final String GUI_SIDE_NORTH = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGEyMjFlNGY5NmJlZTYyNjE3NTIzOTZhMzI2NWZmYTRkZWRmOGZmNDgzOWFiZDE0ZjQ5ZWRlZTFlNTMwOTIifX19";
public static final String GUI_SIDE_SOUTH = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDcxMDEzODQxNjUyODg4OTgxNTU0OGI0NjIzZDI4ZDg2YmJiYWU1NjE5ZDY5Y2Q5ZGJjNWFkNmI0Mzc0NCJ9fX0=";
public static final String GUI_SIDE_EAST = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWFlZWY4OGUyYzkyOGI0NjZjNmVkNWRlYWE0ZTE5NzVhOTQzNmMyYjFiNDk4ZjlmN2NiZjkyYTliNTk5YTYifX19";
public static final String GUI_SIDE_WEST = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODBjOTQ4M2Y1MWQxMjY3NDMyZTBmMmYzYmFhOGNkOTNlNjViNWVhYzc0ODJiMjdkYmNjZWJhZmI3MjE3NDhiIn19fQ==";
public static final String GUI_SIDE_UP = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZDY5OTFkY2JhMjVlYWUyNDNlYjVjZWI4MzI1ZjRhYjc4ZjlmMTQxMjdjMzgyZjZjZDQyYzRjNzgwNDJkNGI1In19fQ==";
public static final String GUI_SIDE_DOWN = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZmE2NjE0MTlkZTQ5ZmY0YTJjOTdiMjdmODY4MDE0ZmJkYWViOGRkN2Y0MzkyNzc3ODMwYjI3MTRjYWFmZDFmIn19fQ==";
public static final String GUI_MODE_INPUT = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWM5OWRmYjI3MDRlMWJkNmU3ZmFjZmI0M2IzZTZmYmFiYWYxNmViYzdlMWZhYjA3NDE3YTZjNDY0ZTFkIn19fQ==";
public static final String GUI_MODE_OUTPUT = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2JiMWQxN2NlYmM1ZjBlY2M5ODdiODBlZmMwM2UzMmVjYjFjYjQwZGJjNWJjZTJmYWYzZTYwNTQyYTQwIn19fQ==";
public static final int PAGE_SIZE = 9 * 5;
protected final Runnable closeCallback;
public boolean ignoreCloseCallback;
@@ -73,7 +82,7 @@ public abstract class PagedGui extends SimpleGui {
return this.page - 1 >= 0;
}
protected void updateDisplay() {
public void updateDisplay() {
var offset = page * PAGE_SIZE;
for (int i = 0; i < PAGE_SIZE; i++) {
@@ -0,0 +1,199 @@
package systems.brn.server_storage.lib;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.*;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import systems.brn.server_storage.blockentities.HardDriveContainerBlockEntity;
import systems.brn.server_storage.blockentities.InventoryInterfaceBlockEntity;
import systems.brn.server_storage.blockentities.StorageInterfaceBlockEntity;
import systems.brn.server_storage.blocks.BusConnectorBlock;
import systems.brn.server_storage.blocks.HardDriveContainerBlock;
import systems.brn.server_storage.blocks.InventoryInterfaceBlock;
import systems.brn.server_storage.blocks.StorageInterfaceBlock;
import systems.brn.server_storage.items.HardDrive;
import java.util.*;
import static systems.brn.server_storage.ServerStorage.DRIVES;
import static systems.brn.server_storage.blocks.BusConnectorBlock.*;
import static systems.brn.server_storage.lib.StorageOperations.*;
public class StorageNetwork {
public List<HardDriveContainerBlockEntity> driveContainers;
public List<StorageInterfaceBlockEntity> storageInterfaceBlockEntities;
public List<InventoryInterfaceBlockEntity> inventoryInterfaceBlockEntities;
public List<HardDrive> drives;
public Map<ItemStack, Integer> itemStackMap;
public Map<ItemStack, Integer> filteredItemStackMap;
public int driveContainerCount;
public int drivesCount;
public int driveTotalSlots;
public int driveUsedSlots;
public int driveFreeSlots;
public StorageNetwork(World world, BlockPos startPos, boolean sortAlphabetically, String searchString) {
reindexNetwork(world, startPos, sortAlphabetically, searchString);
}
public void reindexNetwork(World world, BlockPos startPos, boolean sortAlphabetically, String searchString) {
List<HardDriveContainerBlockEntity> driveContainers = new ArrayList<>();
List<StorageInterfaceBlockEntity> storageInterfaceBlockEntities = new ArrayList<>();
List<InventoryInterfaceBlockEntity> inventoryInterfaceBlockEntities = new ArrayList<>();
List<HardDrive> drives = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>();
scan(world, startPos, startPos, driveContainers, storageInterfaceBlockEntities, inventoryInterfaceBlockEntities, drives, visited);
this.driveContainers = driveContainers;
this.drives = drives;
this.storageInterfaceBlockEntities = storageInterfaceBlockEntities;
this.inventoryInterfaceBlockEntities = inventoryInterfaceBlockEntities;
countStuff();
filteredItemStackMap = getCombinedMap(sortAlphabetically, searchString);
}
private void countStuff() {
driveUsedSlots = 0;
driveFreeSlots = 0;
driveTotalSlots = 0;
driveContainerCount = driveContainers.size();
drivesCount = drives.size();
for (HardDriveContainerBlockEntity driveContainer : this.driveContainers) {
driveFreeSlots += driveContainer.getAvailableSlots();
driveUsedSlots += driveContainer.getUsedSlots();
driveTotalSlots += driveContainer.getTotalSlots();
}
}
public void updateDisplays(){
for (StorageInterfaceBlockEntity storageInterfaceBlockEntity : storageInterfaceBlockEntities) {
storageInterfaceBlockEntity.updateDisplays();
}
}
private static void scan(World world, BlockPos pos, BlockPos startPos, List<HardDriveContainerBlockEntity> driveContainers, List<StorageInterfaceBlockEntity> storageInterfaceBlockEntities, List<InventoryInterfaceBlockEntity> inventoryInterfaceBlockEntities, List<HardDrive> drives, Set<BlockPos> visited) {
if (visited.contains(pos)) {
return;
}
visited.add(pos);
BlockState blockState = world.getBlockState(pos);
Block block = blockState.getBlock();
if (block instanceof HardDriveContainerBlock) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof HardDriveContainerBlockEntity driveContainerBlockEntity) {
driveContainers.add(driveContainerBlockEntity);
driveContainerBlockEntity.indexDrives();
drives.addAll(driveContainerBlockEntity.drives);
}
}
if (block instanceof StorageInterfaceBlock) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof StorageInterfaceBlockEntity storageInterfaceBlockEntity){
storageInterfaceBlockEntities.add(storageInterfaceBlockEntity);
}
}
if (block instanceof InventoryInterfaceBlock) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity){
inventoryInterfaceBlockEntities.add(inventoryInterfaceBlockEntity);
}
}
if (block instanceof BusConnectorBlock || pos == startPos) {
if (blockState.getOrEmpty(NORTH).isPresent() && blockState.get(NORTH) == ConnectionType.BUS) {
BlockPos nextPos = pos.offset(Direction.NORTH);
scan(world, nextPos, startPos, driveContainers, storageInterfaceBlockEntities, inventoryInterfaceBlockEntities, drives, visited);
}
if (blockState.getOrEmpty(SOUTH).isPresent() && blockState.get(SOUTH) == ConnectionType.BUS) {
BlockPos nextPos = pos.offset(Direction.SOUTH);
scan(world, nextPos, startPos, driveContainers, storageInterfaceBlockEntities, inventoryInterfaceBlockEntities, drives, visited);
}
if (blockState.getOrEmpty(EAST).isPresent() && blockState.get(EAST) == ConnectionType.BUS) {
BlockPos nextPos = pos.offset(Direction.EAST);
scan(world, nextPos, startPos, driveContainers, storageInterfaceBlockEntities, inventoryInterfaceBlockEntities, drives, visited);
}
if (blockState.getOrEmpty(WEST).isPresent() && blockState.get(WEST) == ConnectionType.BUS) {
BlockPos nextPos = pos.offset(Direction.WEST);
scan(world, nextPos, startPos, driveContainers, storageInterfaceBlockEntities, inventoryInterfaceBlockEntities, drives, visited);
}
if (blockState.getOrEmpty(UP).isPresent() && blockState.get(UP) == ConnectionType.BUS) {
BlockPos nextPos = pos.offset(Direction.UP);
scan(world, nextPos, startPos, driveContainers, storageInterfaceBlockEntities, inventoryInterfaceBlockEntities, drives, visited);
}
if (blockState.getOrEmpty(DOWN).isPresent() && blockState.get(DOWN) == ConnectionType.BUS) {
BlockPos nextPos = pos.offset(Direction.DOWN);
scan(world, nextPos, startPos, driveContainers, storageInterfaceBlockEntities, inventoryInterfaceBlockEntities, drives, visited);
}
}
}
// Modify getCombinedInventoryFromChests to include item metadata and combine stacks
private TreeMap<ItemStack, Integer> getCombinedMap(boolean sortAlphabetically, String query) {
itemStackMap = new HashMap<>();
for (HardDrive drive : drives) {
itemStackMap = drive.addToMap(itemStackMap);
}
return sortAndFilterMap(itemStackMap, sortAlphabetically, query);
}
public int putItemStackRemainder(ItemStack stack) {
if (DRIVES.contains(stack.getItem())){
return stack.getCount();
}
// Iterate over each chest to try and insert the ItemStack
int leftOvers = stack.getCount();
for (InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity : inventoryInterfaceBlockEntities) {
leftOvers = inventoryInterfaceBlockEntity.processIncoming(stack.copy(), leftOvers);
if (leftOvers <= 0) {
return 0;
}
}
ItemStack driveStack = stack.copy();
driveStack.setCount(leftOvers);
for (HardDrive drive : drives) {
driveStack = drive.insertStackIntoInventory(driveStack);
if (driveStack.isEmpty()) {
return 0;
}
}
// If we still have remaining items, return false
return driveStack.getCount();
}
public boolean canAddItemStack(ItemStack stack) {
return stack.getCount() <= driveFreeSlots && !DRIVES.contains(stack.getItem());
}
public boolean canRemove(ItemStack stackToRemove) {
return canRemoveCount(stackToRemove, itemStackMap) == 0;
}
public ItemStack removeItemStack(ItemStack stackToRemove) {
ItemStack outStack = stackToRemove.copy();
for (HardDrive drive : drives) {
outStack = drive.removeStackFromInventory(outStack);
if (outStack.getCount() >= stackToRemove.getCount()) {
break;
}
}
// If we still have remaining items, return false
return outStack;
}
}
@@ -1,19 +1,43 @@
package systems.brn.server_storage.lib;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class StorageOperations {
// Modify getSimpleInventory to include item metadata and sort conditionally
public static @NotNull SimpleInventory getSimpleInventory(int size, Map<ItemStack, Integer> itemStackMap, boolean sortAlphabetically) {
public static TreeMap<ItemStack, Integer> sortAndFilterMap(Map<ItemStack, Integer> itemStackMap, boolean sortAlphabetically, String query) {
TreeMap<ItemStack, Integer> sortedMap = getItemStackIntegerTreeMap(itemStackMap, sortAlphabetically);
if (query == null || query.isEmpty() || query.equals("*")) {
sortedMap.putAll(itemStackMap);
} else {
Map<ItemStack, Integer> filteredMap = new HashMap<>();
for (Map.Entry<ItemStack, Integer> entry : itemStackMap.entrySet()) {
if (filterItem(entry.getKey().getItem(), query)){
filteredMap.put(entry.getKey(), entry.getValue());
}
}
sortedMap.putAll(filteredMap);
}
return sortedMap;
}
public static boolean filterItem(Item item, String query){
if (item != null) {
String itemName = String.valueOf(item);
return itemName == null || itemName.contains(query);
}
return false;
}
private static @NotNull TreeMap<ItemStack, Integer> getItemStackIntegerTreeMap(Map<ItemStack, Integer> itemStackMap, boolean sortAlphabetically) {
TreeMap<ItemStack, Integer> sortedMap;
if (sortAlphabetically) {
@@ -33,51 +57,35 @@ public class StorageOperations {
return countCompare == 0 ? String.valueOf(o1.getItem()).compareToIgnoreCase(String.valueOf(o2.getItem())) : countCompare;
});
}
sortedMap.putAll(itemStackMap);
SimpleInventory inv = new SimpleInventory(size);
int invPointer = 0;
for (Map.Entry<ItemStack, Integer> entry : sortedMap.entrySet()) {
ItemStack stack = entry.getKey();
int count = entry.getValue();
stack.setCount(count);
inv.heldStacks.set(invPointer, stack); //bypass stack maximum
invPointer++;
}
return inv;
return sortedMap;
}
// Modify filterStack to include item metadata
public static ItemStack filterStack(ItemStack stack, String query) {
Item item = stack.getItem();
if (item != null) {
String itemName = String.valueOf(item);
if (itemName != null && !itemName.contains(query)) {
return ItemStack.EMPTY;
public static int canInsertToStack(ItemStack stack1, ItemStack stack2, int maxInsert) {
if (stack1.isEmpty() || ItemStack.areItemsEqual(stack1, stack2)) {
int remainingSpace = stack1.isEmpty() ? stack2.getMaxCount() : stack1.getMaxCount() - stack1.getCount();
maxInsert += remainingSpace;
// If the maximum insertion count is greater than or equal to the item count, return the item count
if (maxInsert >= stack2.getCount()) {
return stack2.getCount();
}
}
return stack;
return maxInsert;
}
public static int canInsertItemIntoPlayerInventory(PlayerEntity player, ItemStack itemStack) {
public static int canInsertItemIntoInventory(Inventory inventory, ItemStack itemStack) {
// Get the player's inventory
PlayerInventory playerInventory = player.getInventory();
int maxInsert = 0;
// Iterate through the slots in the player's inventory
for (int i = 0; i < playerInventory.main.size(); i++) {
ItemStack slotStack = playerInventory.main.get(i);
// Check if the slot is empty or if there's space for the item
if (slotStack.isEmpty() || ItemStack.areItemsEqual(slotStack, itemStack)) {
int remainingSpace = slotStack.isEmpty() ? itemStack.getMaxCount() : slotStack.getMaxCount() - slotStack.getCount();
maxInsert += remainingSpace;
// If the maximum insertion count is greater than or equal to the item count, return the item count
if (maxInsert >= itemStack.getCount()) {
return itemStack.getCount();
}
if (inventory instanceof PlayerInventory playerInventory) {
// Iterate through the slots in the player's inventory
for (int i = 0; i < playerInventory.main.size(); i++) {
ItemStack slotStack = playerInventory.main.get(i);
maxInsert = canInsertToStack(slotStack, itemStack, maxInsert);
}
} else {
for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i);
maxInsert = canInsertToStack(slotStack, itemStack, maxInsert);
}
}
@@ -115,7 +123,7 @@ public class StorageOperations {
return stack;
}
public static int removeFromInventory(Inventory inventory, ItemStack stackToRemove, int remainingToRemove) {
public static void removeFromInventory(Inventory inventory, ItemStack stackToRemove, int remainingToRemove) {
for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i);
if (canCombine(slotStack, stackToRemove)) {
@@ -129,21 +137,36 @@ public class StorageOperations {
}
if (remainingToRemove <= 0) {
return remainingToRemove;
return;
}
}
}
return remainingToRemove;
}
public static int canRemoveCount(ItemStack stackToRemove, Inventory inventory) {
int remainingToRemove = stackToRemove.getCount();
public static int howMuchFits(ItemStack stack, Inventory inventory){
int out = 0;
for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i);
if (slotStack.isEmpty()) {
out += stack.getMaxCount();
continue;
}
if (canCombine(slotStack, stack)) {
int remaining = slotStack.getMaxCount() - slotStack.getCount();
out += remaining;
}
}
return out;
}
public static int canRemoveCount(ItemStack stackToRemove, Map<ItemStack, Integer> itemsMap) {
int remainingToRemove = stackToRemove.getCount();
for (Map.Entry<ItemStack, Integer> entry : itemsMap.entrySet()) {
ItemStack slotStack = entry.getKey();
if (canCombine(slotStack, stackToRemove)) {
// If the slot contains the same item type
if (slotStack.getCount() >= remainingToRemove) {
if (entry.getValue() >= remainingToRemove) {
// If the count in the slot is sufficient to remove the requested amount
return 0;
} else {
@@ -174,7 +197,7 @@ public class StorageOperations {
ItemStack existingStack = entry.getKey();
if (ItemStack.areItemsAndComponentsEqual(stack, existingStack)) {
int newCount = entry.getValue() + stack.getCount();
itemStackMap.put(existingStack, newCount);
entry.setValue(newCount);
return;
}
}
@@ -2,7 +2,6 @@ package systems.brn.server_storage.lib;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.LoreComponent;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
@@ -21,13 +20,13 @@ import java.util.stream.Collectors;
public class Util {
public static List<RawFilteredPair<Text>> generateBookContent(Inventory inventory) {
public static List<RawFilteredPair<Text>> generateBookContent(Map<ItemStack, Integer> itemMap) {
List<String> pages = new ArrayList<>();
for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i);
for (Map.Entry<ItemStack, Integer> entry : itemMap.entrySet()) {
ItemStack slotStack = entry.getKey();
if (!slotStack.isEmpty()) {
Item itemName = slotStack.getItem();
pages.add(itemName + " " + slotStack.getCount());
pages.add(itemName + " " + entry.getValue());
}
}
return stringToBookContent(String.join(System.lineSeparator(), pages));
@@ -106,7 +105,7 @@ public class Util {
}
}
public static ArrayList<CraftingEntry> getCraftableRecipes(Inventory inventory, MinecraftServer server) {
public static ArrayList<CraftingEntry> getCraftableRecipes(Map<ItemStack, Integer> itemStackMap, MinecraftServer server) {
RecipeManager recipeManager = server.getRecipeManager();
List<RecipeEntry<CraftingRecipe>> allRecipes = recipeManager.listAllOfType(RecipeType.CRAFTING);
@@ -152,10 +151,9 @@ public class Util {
ItemStack stackIn = entry.getKey();
Integer count = entry.getValue();
boolean itemFound = false;
for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i);
Item slotItem = slotStack.getItem();
int slotCount = slotStack.getCount();
for (Map.Entry<ItemStack, Integer> itemEntry : itemStackMap.entrySet()){
Item slotItem = itemEntry.getKey().getItem();
int slotCount = itemEntry.getValue();
if (stackIn.getItem() == slotItem) {
count -= slotCount;
entry.setValue(count);
@@ -172,9 +170,6 @@ public class Util {
if (count > 0) {
canMake = false;
} else {
if(recipe.value().getResult(server.getRegistryManager()).getItem() == Items.REDSTONE_BLOCK){
int asdasd = 0;
}
int thisMaxAmount = Math.floorDivExact(Math.abs(count), stackIn.getCount());
if (maxAmount == -1) {
maxAmount = thisMaxAmount;
@@ -7,36 +7,34 @@ import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.screen.slot.Slot;
import systems.brn.server_storage.lib.HardDriveSlot;
import systems.brn.server_storage.blockentities.HardDriveContainerBlockEntity;
public class DriveContainerScreenHandler extends ScreenHandler {
private static final int CONTAINER_SIZE = 9;
private static final int INVENTORY_START = 9;
private static final int INVENTORY_END = 36;
private static final int HOTBAR_START = 36;
private static final int HOTBAR_END = 45;
private final Inventory inventory;
private final HardDriveContainerBlockEntity blockEntity;
public DriveContainerScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
super(ScreenHandlerType.GENERIC_3X3, syncId);
checkSize(inventory, 9);
this.inventory = inventory;
public DriveContainerScreenHandler(int syncId, PlayerInventory playerInventory, HardDriveContainerBlockEntity blockEntity) {
super(ScreenHandlerType.HOPPER, syncId);
this.blockEntity = blockEntity;
checkSize(blockEntity, HardDriveContainerBlockEntity.INVENTORY_SIZE);
this.inventory = blockEntity;
blockEntity.indexDrives();
blockEntity.commitDrives();
inventory.onOpen(playerInventory.player);
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
this.addSlot(new HardDriveSlot(inventory, j + i * 3, 62 + j * 18, 17 + i * 18));
int j;
for (j = 0; j < 5; ++j) {
this.addSlot(new Slot(inventory, j, 44 + j * 18, 20));
}
for (j = 0; j < 3; ++j) {
for (int k = 0; k < 9; ++k) {
this.addSlot(new Slot(playerInventory, k + j * 9 + 9, 8 + k * 18, j * 18 + 51));
}
}
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 9; ++j) {
this.addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for(int i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
for (j = 0; j < 9; ++j) {
this.addSlot(new Slot(playerInventory, j, 8 + j * 18, 109));
}
}
@@ -45,18 +43,25 @@ public class DriveContainerScreenHandler extends ScreenHandler {
return this.inventory.canPlayerUse(player);
}
@Override
public ItemStack quickMove(PlayerEntity player, int slot) {
ItemStack temp = quickMoveHelper(player, slot);
blockEntity.indexDrives();
return temp;
}
public ItemStack quickMoveHelper(PlayerEntity player, int slot) {
ItemStack itemStack = ItemStack.EMPTY;
Slot slot2 = this.slots.get(slot);
if (slot2.hasStack()) {
ItemStack itemStack2 = slot2.getStack();
itemStack = itemStack2.copy();
if (slot < 9) {
if (!this.insertItem(itemStack2, 9, 45, true)) {
if (slot < this.inventory.size()) {
if (!this.insertItem(itemStack2, this.inventory.size(), this.slots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (!this.insertItem(itemStack2, 0, 9, false)) {
} else if (!this.insertItem(itemStack2, 0, this.inventory.size(), false)) {
return ItemStack.EMPTY;
}
@@ -80,5 +85,6 @@ public class DriveContainerScreenHandler extends ScreenHandler {
public void onClosed(PlayerEntity player) {
super.onClosed(player);
this.inventory.onClose(player);
blockEntity.indexDrives();
}
}
@@ -2,12 +2,14 @@ package systems.brn.server_storage.screens;
import eu.pb4.sgui.api.elements.GuiElementBuilder;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.text.Text;
import systems.brn.server_storage.blockentities.StorageInterfaceBlockEntity;
import systems.brn.server_storage.lib.CraftingEntry;
import systems.brn.server_storage.lib.PagedGui;
@@ -24,23 +26,26 @@ public class CraftingScreen extends PagedGui {
private ArrayList<CraftingEntry> craftingEntries;
private final StorageInterfaceBlockEntity blockEntity;
private ArrayList<DisplayElement> recipesList;
public CraftingScreen(StorageScreen storageScreen) {
super(storageScreen.getPlayer(), null);
this.storageScreen = storageScreen;
this.blockEntity = storageScreen.blockEntity;
this.setTitle(Text.translatable("container.crafting"));
this.updateDisplay();
}
@Override
public void updateDisplay(){
storageScreen.blockEntity.rescanChests();
blockEntity.reindexDrives();
Map<ItemStack, Integer> itemStackMap = new HashMap<>();
addInventoryToMap(storageScreen.getPlayer().getInventory(), itemStackMap);
addInventoryToMap(storageScreen.blockEntity.chests.inventory, itemStackMap);
Inventory inventory = getSimpleInventory(itemStackMap.size(), itemStackMap, false);
this.craftingEntries = getCraftableRecipes(inventory, Objects.requireNonNull(player.getServer()));
itemStackMap.putAll(blockEntity.network.itemStackMap);
Map<ItemStack, Integer> items = sortAndFilterMap(itemStackMap, false, null);
this.craftingEntries = getCraftableRecipes(items, Objects.requireNonNull(player.getServer()));
this.recipesList = getAvailableRecipes();
super.updateDisplay();
}
@@ -89,6 +94,23 @@ public class CraftingScreen extends PagedGui {
}
}
private boolean canCraft(RecipeEntry<CraftingRecipe> recipeEntry) {
for (Ingredient ingredient : recipeEntry.value().getIngredients()) {
ItemStack stackToRemove = findMatchingStack(ingredient);
if (stackToRemove == null) {
return false;
}
int requiredCount = canRemoveCount(stackToRemove, this.blockEntity.network.itemStackMap);
Map<ItemStack, Integer> playerInventory = new HashMap<>();
addInventoryToMap(this.storageScreen.getPlayer().getInventory(), playerInventory);
if (requiredCount > 0 && canRemoveCount(stackToRemove, playerInventory) < requiredCount) {
return false;
}
}
return true;
}
private boolean craftOneStack(PlayerEntity player, RecipeEntry<CraftingRecipe> recipeEntry, boolean toPlayerInventory) {
if (!canCraft(recipeEntry)) {
return true; //stop
@@ -97,18 +119,12 @@ public class CraftingScreen extends PagedGui {
ArrayList<ItemStack> stacksToRemove = new ArrayList<>();
// Check and remove ingredients
if (!canCraft(recipeEntry)) {
return true;
}
for (Ingredient ingredient : recipeEntry.value().getIngredients()) {
ItemStack stackToRemove = findMatchingStack(ingredient);
if (stackToRemove == null){
return false;
}
int requiredCount = canRemoveCount(stackToRemove, this.storageScreen.blockEntity.chests.inventory);
if (requiredCount > 0 && canRemoveCount(stackToRemove, this.storageScreen.getPlayer().getInventory()) < requiredCount) {
return true;
} else {
stacksToRemove.add(stackToRemove);
}
stacksToRemove.add(stackToRemove);
}
for (ItemStack stack : stacksToRemove) {
@@ -118,14 +134,15 @@ public class CraftingScreen extends PagedGui {
// Add the result to the appropriate inventory
ItemStack outputStack = recipeEntry.value().getResult(storageScreen.getPlayer().getRegistryManager()).copy();
if (toPlayerInventory) {
if (canInsertItemIntoPlayerInventory(player, outputStack) == outputStack.getCount()) {
player.getInventory().insertStack(outputStack);
PlayerInventory playerInventory = player.getInventory();
if (canInsertItemIntoInventory(playerInventory, outputStack) == outputStack.getCount()) {
playerInventory.insertStack(outputStack);
} else {
return true;
}
} else {
if (this.storageScreen.blockEntity.chests.canAddItemStack(outputStack)) {
this.storageScreen.blockEntity.chests.tryPutItemStack(outputStack);
if (this.blockEntity.network.canAddItemStack(outputStack)) {
this.blockEntity.network.putItemStackRemainder(outputStack);
} else {
return true;
}
@@ -142,24 +159,9 @@ public class CraftingScreen extends PagedGui {
return false;
}
private boolean canCraft(RecipeEntry<CraftingRecipe> recipeEntry) {
for (Ingredient ingredient : recipeEntry.value().getIngredients()) {
ItemStack stackToRemove = findMatchingStack(ingredient);
if (stackToRemove == null){
return false;
}
int requiredCount = canRemoveCount(stackToRemove, this.storageScreen.blockEntity.chests.inventory);
if (requiredCount > 0 && canRemoveCount(stackToRemove, this.storageScreen.getPlayer().getInventory()) < requiredCount) {
return false;
}
}
return true;
}
private ItemStack findMatchingStack(Ingredient ingredient) {
for (ItemStack stack : ingredient.getMatchingStacks()) {
if (this.storageScreen.blockEntity.chests.canRemove(stack)) {
if (this.blockEntity.network.canRemove(stack)) {
return stack;
}
}
@@ -168,7 +170,7 @@ public class CraftingScreen extends PagedGui {
private void removeItems(ItemStack stack) {
// Logic to remove items from the storage
ItemStack fromPlayer = this.storageScreen.blockEntity.chests.removeItemStack(stack);
ItemStack fromPlayer = this.blockEntity.network.removeItemStack(stack);
if (fromPlayer != null && fromPlayer.getCount() > 0) {
Inventory playerInventory = player.getInventory();
for (int i = 0; i < playerInventory.size(); i++) {
@@ -1,14 +0,0 @@
package systems.brn.server_storage.screens;
import eu.pb4.sgui.api.gui.SimpleGui;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
public class DriveScreen extends SimpleGui {
BlockPos pos;
public DriveScreen(ServerPlayerEntity player, BlockPos pos) {
super(ScreenHandlerType.HOPPER, player, false);
this.pos = pos;
}
}
@@ -1,26 +1,29 @@
package systems.brn.server_storage.screens;
import eu.pb4.sgui.api.gui.AnvilInputGui;
import systems.brn.server_storage.lib.PagedGui;
import eu.pb4.sgui.api.gui.SimpleGui;
import systems.brn.server_storage.blockentities.InventoryInterfaceBlockEntity;
public class SearchScreen extends AnvilInputGui {
private final PagedGui storageScreen;
private final SimpleGui parentScreen;
public SearchScreen(PagedGui storageScreen, String defaultText) {
super(storageScreen.getPlayer(), storageScreen.getLockPlayerInventory());
this.storageScreen = storageScreen;
storageScreen.close();
public SearchScreen(SimpleGui parentScreen, String defaultText) {
super(parentScreen.getPlayer(), parentScreen.getLockPlayerInventory());
this.parentScreen = parentScreen;
parentScreen.close();
this.setDefaultInputValue(defaultText);
}
@Override
public void onClose() {
super.onClose();
storageScreen.open();
parentScreen.open();
String query = this.getInput();
if (storageScreen instanceof StorageScreen) {
((StorageScreen) storageScreen).doSearch(query);
if (parentScreen instanceof StorageScreen storageScreen) {
storageScreen.doSearch(query);
} else if (parentScreen instanceof SettingsScreen settingsScreen && settingsScreen.blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity) {
inventoryInterfaceBlockEntity.doSearch(query);
}
}
}
@@ -1,83 +1,97 @@
package systems.brn.server_storage.screens;
import eu.pb4.sgui.api.elements.GuiElementBuilder;
import eu.pb4.sgui.api.gui.SimpleGui;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.item.Items;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.jetbrains.annotations.Nullable;
import systems.brn.server_storage.blockentities.InventoryInterfaceBlockEntity;
import systems.brn.server_storage.lib.PagedGui;
import java.util.ArrayList;
public class SettingsScreen extends PagedGui {
private final StorageScreen storageScreen;
private final SimpleGui parentScreen;
private ArrayList<DisplayElement> settingsList;
public SettingsScreen(StorageScreen storageScreen) {
super(storageScreen.getPlayer(), null);
this.storageScreen = storageScreen;
public final BlockEntity blockEntity;
public SettingsScreen(@Nullable SimpleGui parentScreen, ServerPlayerEntity player, BlockEntity blockEntity) {
super(player, null);
this.parentScreen = parentScreen;
this.blockEntity = blockEntity;
clearSettings();
this.setTitle(Text.translatable("mco.configure.world.buttons.settings"));
if (blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity) {
inventoryInterfaceBlockEntity.openSettingsScreens.add(this);
}
this.updateDisplay();
}
public SettingsScreen(StorageScreen parentScreen) {
this(parentScreen, parentScreen.getPlayer(), parentScreen.blockEntity);
}
public SettingsScreen(SimpleGui parentScreen, BlockEntity blockEntity) {
this(parentScreen, parentScreen.getPlayer(), blockEntity);
}
public SettingsScreen(ServerPlayerEntity player, BlockEntity blockEntity) {
this(null, player, blockEntity);
}
public void addSetting(DisplayElement setting) {
this.settingsList.add(setting);
}
@Override
public void onClose() {
super.onClose();
storageScreen.open();
}
@Override
public void updateDisplay() {
this.settingsList = new ArrayList<>();
this.settingsList.add(containers());
this.settingsList.add(autoSuck());
super.updateDisplay();
}
protected PagedGui.DisplayElement containers() {
return PagedGui.DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable(storageScreen.blockEntity.allInventories ? "gui.all" : "options.fov.min").formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(GUI_CONTAINERS)
.setCallback((x, y, z) -> {
storageScreen.blockEntity.allInventories ^= true;
storageScreen.blockEntity.markDirty();
storageScreen.blockEntity.rescanChests();
playClickSound(getPlayer());
updateDisplay();
})
);
if (parentScreen != null) {
parentScreen.open();
}
if (blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity) {
inventoryInterfaceBlockEntity.openSettingsScreens.remove(this);
}
}
@Override
protected int getPageAmount() {
return Math.ceilDivExact(settingsList.size(), 9*6);
return Math.ceilDivExact(settingsList.size(), 9 * 6);
}
@Override
protected DisplayElement getElement(int id) {
if (id >= 0 && id < settingsList.size()) {
return settingsList.get(id);
}
else {
} else {
return DisplayElement.empty();
}
}
protected PagedGui.DisplayElement autoSuck() {
return PagedGui.DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable(storageScreen.blockEntity.autoSuck ? "gui.yes" : "gui.no").formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(storageScreen.blockEntity.autoSuck ? GUI_AUTOSUCK_ON : GUI_AUTOSUCK_OFF)
.setCallback((x, y, z) -> {
storageScreen.blockEntity.autoSuck ^= true;
storageScreen.blockEntity.rescanChests();
playClickSound(getPlayer());
updateDisplay();
})
);
public DisplayElement getItem() {
if (settingsList.isEmpty()) {
return DisplayElement.filler();
} else {
return DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable("mco.configure.world.settings.title").formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(GUI_SETTINGS)
.setCallback((x, y, z) -> {
playClickSound(getPlayer());
this.open();
})
);
}
}
public void clearSettings() {
this.settingsList = new ArrayList<>();
}
}
@@ -3,6 +3,7 @@ package systems.brn.server_storage.screens;
import eu.pb4.sgui.api.ClickType;
import eu.pb4.sgui.api.elements.GuiElementBuilder;
import eu.pb4.sgui.api.elements.GuiElementInterface;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.screen.slot.SlotActionType;
@@ -11,7 +12,7 @@ import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable;
import systems.brn.server_storage.blockentities.StorageBlockEntity;
import systems.brn.server_storage.blockentities.StorageInterfaceBlockEntity;
import systems.brn.server_storage.lib.PagedGui;
import static systems.brn.server_storage.ServerStorage.ServerStorage_Crafting_Enable;
@@ -21,13 +22,13 @@ import static systems.brn.server_storage.lib.Util.removeCountFromLore;
public class StorageScreen extends PagedGui {
private final ServerPlayerEntity player;
public final StorageBlockEntity blockEntity;
public final StorageInterfaceBlockEntity blockEntity;
public StorageScreen(ServerPlayerEntity player, BlockPos pos, @Nullable Runnable closeCallback) {
super(player, closeCallback);
this.player = player;
this.setLockPlayerInventory(false);
this.blockEntity = (StorageBlockEntity) player.getWorld().getBlockEntity(pos);
this.blockEntity = (StorageInterfaceBlockEntity) player.getWorld().getBlockEntity(pos);
assert blockEntity != null;
}
@@ -35,21 +36,25 @@ public class StorageScreen extends PagedGui {
public boolean open() {
page = blockEntity.page;
this.blockEntity.openStorageScreens.add(this);
this.blockEntity.rescanChests();
blockEntity.updateDisplays();
return super.open();
}
@Override
public void updateDisplay() {
String title = blockEntity.chests.containerUsedSlots +
blockEntity.justReindexDrives();
String title = blockEntity.network.driveUsedSlots +
"u/" +
blockEntity.chests.containerSlots +
blockEntity.network.driveTotalSlots +
"t(" +
blockEntity.chests.containerFreeSlots +
blockEntity.network.driveFreeSlots +
"f)" +
"[" +
blockEntity.chests.containerCount +
"c]";
blockEntity.network.driveContainerCount +
"c]" +
"[" +
blockEntity.network.drivesCount +
"d]";
setTitle(Text.of(title));
super.updateDisplay();
@@ -57,14 +62,17 @@ public class StorageScreen extends PagedGui {
@Override
protected int getPageAmount() {
return Math.ceilDivExact(blockEntity.chests.inventory.size(), 9 * 6);
return Math.ceilDivExact(blockEntity.network.itemStackMap.size(), 9 * 6);
}
@Override
protected DisplayElement getElement(int id) {
if (blockEntity.chests.inventory.size() > id) {
ItemStack itemStack = blockEntity.chests.inventory.getStack(id);
ItemStack newStack = addCountToLore(itemStack.getCount(), itemStack, null);
if (blockEntity.network.itemStackMap.size() > id) {
ItemStack itemStackKey = (ItemStack) blockEntity.network.itemStackMap.keySet().toArray()[id];
ItemStack aestheticStack = itemStackKey.copy();
int count = blockEntity.network.itemStackMap.get(itemStackKey);
aestheticStack.setCount(Math.max(aestheticStack.getMaxCount(), count));
ItemStack newStack = addCountToLore(count, aestheticStack, null);
GuiElementBuilder guiElement = new GuiElementBuilder(newStack);
return DisplayElement.of(guiElement);
}
@@ -74,7 +82,8 @@ public class StorageScreen extends PagedGui {
@Override
public boolean onClick(int index, ClickType type, SlotActionType action, GuiElementInterface element) {
GuiElementInterface clickedElement = getSlot(index);
if (clickedElement != null) {
ItemStack cursorStack = getPlayer().currentScreenHandler.getCursorStack();
if (clickedElement != null && cursorStack.isEmpty()) {
ItemStack clickedItem = clickedElement.getItemStack();
ItemStack noLoreStack = removeCountFromLore(clickedItem);
if (type.isRight) {
@@ -95,27 +104,35 @@ public class StorageScreen extends PagedGui {
}
}
if (!(type.isRight && type.shift)) {
int insertCount = canInsertItemIntoPlayerInventory(player, noLoreStack);
PlayerInventory playerInventory = player.getInventory();
int insertCount = canInsertItemIntoInventory(playerInventory, noLoreStack);
ItemStack insertingStack = noLoreStack.copy();
insertingStack.setCount(insertCount);
blockEntity.rescanChests();
if (blockEntity.chests.canRemove(noLoreStack) && insertCount > 0) {
player.getInventory().insertStack(insertingStack.copy());
blockEntity.chests.removeItemStack(insertingStack);
blockEntity.rescanChests();
blockEntity.reindexDrives();
if (blockEntity.network.canRemove(noLoreStack) && insertCount > 0) {
playerInventory.insertStack(insertingStack.copy());
blockEntity.network.removeItemStack(insertingStack);
blockEntity.reindexDrives();
}
}
} else if (!cursorStack.isEmpty()) {
insertItem(cursorStack);
}
return false;
}
public void insertItem(ItemStack stack) {
int canPutIn = stack.getCount() - blockEntity.network.putItemStackRemainder(stack);
if (canPutIn > 0) {
removeFromInventory(player.getInventory(), stack, canPutIn);
blockEntity.reindexDrives();
}
}
@Override
public boolean insertItem(ItemStack stack, int startIndex, int endIndex, boolean fromLast) {
blockEntity.rescanChests();
if (blockEntity.chests.tryPutItemStack(stack)) {
removeFromInventory(player.getInventory(), stack, stack.getCount());
}
blockEntity.rescanChests();
blockEntity.reindexDrives();
insertItem(stack);
return super.insertItem(stack, startIndex, endIndex, fromLast);
}
@@ -136,17 +153,8 @@ public class StorageScreen extends PagedGui {
@Override
protected DisplayElement settings() {
return DisplayElement.of(
new GuiElementBuilder(Items.PLAYER_HEAD)
.setName(Text.translatable("mco.configure.world.settings.title").formatted(Formatting.WHITE))
.hideDefaultTooltip().noDefaults()
.setSkullOwner(GUI_SETTINGS)
.setCallback((x, y, z) -> {
SettingsScreen settingsScreen = new SettingsScreen(this);
playClickSound(getPlayer());
settingsScreen.open();
})
);
SettingsScreen settingsScreen = new SettingsScreen(this);
return settingsScreen.getItem();
}
@Override
@@ -159,7 +167,7 @@ public class StorageScreen extends PagedGui {
.setCallback((x, y, z) -> {
this.blockEntity.sortAlphabetically ^= true;
playClickSound(getPlayer());
this.blockEntity.rescanChests();
this.blockEntity.reindexDrives();
})
);
}
@@ -184,7 +192,7 @@ public class StorageScreen extends PagedGui {
@Override
protected DisplayElement crafting() {
if (!this.getPlayer().getWorld().getGameRules().getBoolean(ServerStorage_Crafting_Enable)){
if (!this.getPlayer().getWorld().getGameRules().getBoolean(ServerStorage_Crafting_Enable)) {
return DisplayElement.filler();
}
return DisplayElement.of(
@@ -203,7 +211,7 @@ public class StorageScreen extends PagedGui {
public void doSearch(String query) {
this.blockEntity.searchString = query;
this.blockEntity.rescanChests();
this.blockEntity.reindexDrives();
this.page = 0;
}
@@ -218,7 +226,7 @@ public class StorageScreen extends PagedGui {
playClickSound(player);
this.page = 0;
this.blockEntity.searchString = "";
this.blockEntity.rescanChests();
this.blockEntity.reindexDrives();
})
);
}
@@ -0,0 +1,32 @@
{
"multipart": [
{
"when": { "north": "none", "south": "none", "west": "none", "east": "none", "up": "none", "down": "none" },
"apply": { "model": "serverstorage:block/bus_connector_blank" }
},
{
"when": { "north": "bus" },
"apply": { "model": "serverstorage:block/bus_connector_bus_north" }
},
{
"when": { "south": "bus" },
"apply": { "model": "serverstorage:block/bus_connector_bus_south" }
},
{
"when": { "west": "bus" },
"apply": { "model": "serverstorage:block/bus_connector_bus_west" }
},
{
"when": { "east": "bus" },
"apply": { "model": "serverstorage:block/bus_connector_bus_east" }
},
{
"when": { "up": "bus" },
"apply": { "model": "serverstorage:block/bus_connector_bus_up" }
},
{
"when": { "down": "bus" },
"apply": { "model": "serverstorage:block/bus_connector_bus_down" }
}
]
}
@@ -0,0 +1,32 @@
{
"multipart": [
{
"when": { "north": "none", "south": "none", "west": "none", "east": "none", "up": "none", "down": "none" },
"apply": { "model": "serverstorage:block/inventory_interface_blank" }
},
{
"when": { "north": "inventory" },
"apply": { "model": "serverstorage:block/inventory_interface_inventory_north" }
},
{
"when": { "south": "inventory" },
"apply": { "model": "serverstorage:block/inventory_interface_inventory_south" }
},
{
"when": { "west": "inventory" },
"apply": { "model": "serverstorage:block/inventory_interface_inventory_west" }
},
{
"when": { "east": "inventory" },
"apply": { "model": "serverstorage:block/inventory_interface_inventory_east" }
},
{
"when": { "up": "inventory" },
"apply": { "model": "serverstorage:block/inventory_interface_inventory_up" }
},
{
"when": { "down": "inventory" },
"apply": { "model": "serverstorage:block/inventory_interface_inventory_down" }
}
]
}
@@ -1,10 +1,14 @@
{
"block.serverstorage.storage": "Networked storage interface",
"block.serverstorage.inventory_interface": "Networked inventory interface",
"block.serverstorage.drive_container": "Hard drive container",
"item.serverstorage.drive_casing": "Hard drive casing",
"block.serverstorage.bus_connector": "Storage network connector",
"item.serverstorage.iron_drive": "Iron hard drive",
"item.serverstorage.iron_head": "Iron hard drive head",
"item.serverstorage.iron_platter": "Iron hard drive platter",
@@ -19,5 +23,37 @@
"item.serverstorage.netherite_drive": "Netherite hard drive",
"item.serverstorage.netherite_head": "Netherite hard drive head",
"item.serverstorage.netherite_platter": "Netherite hard drive platter"
"item.serverstorage.netherite_platter": "Netherite hard drive platter",
"item.serverstorage.module_bus": "Bus module",
"item.serverstorage.module_configuration": "Configuration module",
"item.serverstorage.module_container": "Container module",
"item.serverstorage.module_display": "Display module",
"item.serverstorage.module_drive": "Drive module",
"item.serverstorage.module_filtering": "Filtering module",
"item.serverstorage.module_inventory": "Inventory module",
"item.serverstorage.module_pagination": "Pagination module",
"item.serverstorage.module_transport": "Transport module",
"item.serverstorage.module_pcb": "Module PCB",
"item.serverstorage.drive_controller": "Drive controller",
"item.serverstorage.cpu": "Central Processing Unit",
"item.serverstorage.cpu_substrate": "CPU substrate",
"item.serverstorage.pcb": "Printed Circuit Board",
"item.serverstorage.pcb_substrate": "PCB substrate",
"gui.serverstorage.store_all": "Store all items from inventory",
"gui.serverstorage.filter": "Filter",
"gui.serverstorage.sort_alphabetically": "Sort alphabetically",
"gui.serverstorage.sort_descending": "Sort by count descending",
"gui.serverstorage.mode_input": "Input",
"gui.serverstorage.mode_output": "Output",
"gui.serverstorage.direction_north": "North",
"gui.serverstorage.direction_south": "South",
"gui.serverstorage.direction_west": "West",
"gui.serverstorage.direction_east": "East",
"gui.serverstorage.direction_up": "Up",
"gui.serverstorage.direction_down": "Down"
}
@@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "serverstorage:block/bus_connector_bus"
}
}
@@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/bus_connector_bus",
"up": "serverstorage:block/bus_connector_blank",
"north": "serverstorage:block/bus_connector_blank",
"south": "serverstorage:block/bus_connector_blank",
"west": "serverstorage:block/bus_connector_blank",
"east": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/bus_connector_blank",
"up": "serverstorage:block/bus_connector_blank",
"north": "serverstorage:block/bus_connector_blank",
"south": "serverstorage:block/bus_connector_blank",
"west": "serverstorage:block/bus_connector_blank",
"east": "serverstorage:block/bus_connector_bus"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/bus_connector_blank",
"up": "serverstorage:block/bus_connector_blank",
"north": "serverstorage:block/bus_connector_bus",
"south": "serverstorage:block/bus_connector_blank",
"west": "serverstorage:block/bus_connector_blank",
"east": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/bus_connector_blank",
"up": "serverstorage:block/bus_connector_blank",
"north": "serverstorage:block/bus_connector_blank",
"south": "serverstorage:block/bus_connector_bus",
"west": "serverstorage:block/bus_connector_blank",
"east": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/bus_connector_blank",
"up": "serverstorage:block/bus_connector_bus",
"north": "serverstorage:block/bus_connector_blank",
"south": "serverstorage:block/bus_connector_blank",
"west": "serverstorage:block/bus_connector_blank",
"east": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/bus_connector_blank",
"up": "serverstorage:block/bus_connector_blank",
"north": "serverstorage:block/bus_connector_blank",
"south": "serverstorage:block/bus_connector_blank",
"west": "serverstorage:block/bus_connector_bus",
"east": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "serverstorage:block/bus_connector_blank"
}
}
@@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "serverstorage:block/inventory_interface_blank"
}
}
@@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "serverstorage:block/inventory_interface_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/inventory_interface_inventory",
"up": "serverstorage:block/inventory_interface_blank",
"north": "serverstorage:block/inventory_interface_blank",
"south": "serverstorage:block/inventory_interface_blank",
"west": "serverstorage:block/inventory_interface_blank",
"east": "serverstorage:block/inventory_interface_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/inventory_interface_blank",
"up": "serverstorage:block/inventory_interface_blank",
"north": "serverstorage:block/inventory_interface_blank",
"south": "serverstorage:block/inventory_interface_blank",
"west": "serverstorage:block/inventory_interface_blank",
"east": "serverstorage:block/inventory_interface_inventory"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/inventory_interface_blank",
"up": "serverstorage:block/inventory_interface_blank",
"north": "serverstorage:block/inventory_interface_inventory",
"south": "serverstorage:block/inventory_interface_blank",
"west": "serverstorage:block/inventory_interface_blank",
"east": "serverstorage:block/inventory_interface_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/inventory_interface_blank",
"up": "serverstorage:block/inventory_interface_blank",
"north": "serverstorage:block/inventory_interface_blank",
"south": "serverstorage:block/inventory_interface_inventory",
"west": "serverstorage:block/inventory_interface_blank",
"east": "serverstorage:block/inventory_interface_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/inventory_interface_blank",
"up": "serverstorage:block/inventory_interface_inventory",
"north": "serverstorage:block/inventory_interface_blank",
"south": "serverstorage:block/inventory_interface_blank",
"west": "serverstorage:block/inventory_interface_blank",
"east": "serverstorage:block/inventory_interface_blank"
}
}
@@ -0,0 +1,11 @@
{
"parent": "block/cube",
"textures": {
"down": "serverstorage:block/inventory_interface_blank",
"up": "serverstorage:block/inventory_interface_blank",
"north": "serverstorage:block/inventory_interface_blank",
"south": "serverstorage:block/inventory_interface_blank",
"west": "serverstorage:block/inventory_interface_inventory",
"east": "serverstorage:block/inventory_interface_blank"
}
}
@@ -0,0 +1,3 @@
{
"parent": "serverstorage:block/bus_connector_blank"
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/cpu"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/cpu_substrate"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/drive_controller"
}
}
@@ -0,0 +1,3 @@
{
"parent": "serverstorage:block/inventory_interface"
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_bus"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_configuration"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_container"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_display"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_drive"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_filtering"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_inventory"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_pagination"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_pcb"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/module_transport"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/pcb"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "serverstorage:item/pcb_substrate"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 757 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 759 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 761 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 B

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Some files were not shown because too many files have changed in this diff Show More