whitelist and blacklist filtering for blockstacker

This commit is contained in:
Jottyfan 2022-12-03 22:12:08 +01:00
parent fab948b9c3
commit 5d140c8ce0
5 changed files with 104 additions and 37 deletions

View File

@ -9,7 +9,7 @@
loader_version=0.14.9
# Mod Properties
mod_version = 1.19.2.3
mod_version = 1.19.2.4
maven_group = de.jottyfan.minecraft
archives_base_name = quickiefabric

View File

@ -1,7 +1,6 @@
package de.jottyfan.minecraft.quickiefabric.blockentity;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.logging.log4j.LogManager;
@ -35,7 +34,7 @@ import net.minecraft.world.World;
public class BlockStackerEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory {
private static final Logger LOGGER = LogManager.getLogger(BlockStackerEntity.class);
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(9, ItemStack.EMPTY);
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(BlockStackerScreenHandler.SLOTSIZE, ItemStack.EMPTY);
public BlockStackerEntity(BlockPos blockPos, BlockState blockState) {
super(QuickieFabricBlockEntity.BLOCKSTACKER_ENTITY, blockPos, blockState);
@ -46,6 +45,30 @@ public class BlockStackerEntity extends BlockEntity implements NamedScreenHandle
return inventory;
}
public List<ItemStack> getWhiteList() {
int counter = 0;
List<ItemStack> list = new ArrayList<>();
for (ItemStack stack : inventory) {
counter++;
if (counter < 10) { // first 9 items are whitelist items
list.add(stack);
}
}
return list;
}
public List<ItemStack> getBlackList() {
int counter = 0;
List<ItemStack> list = new ArrayList<>();
for (ItemStack stack : inventory) {
counter++;
if (counter > 9) { // second 9 items are blacklist items
list.add(stack);
}
}
return list;
}
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new BlockStackerScreenHandler(syncId, playerInventory, this);
@ -92,38 +115,57 @@ public class BlockStackerEntity extends BlockEntity implements NamedScreenHandle
if (sourceIsLootable && destIsLootable) {
LootableContainerBlockEntity lootableSource = (LootableContainerBlockEntity) source;
LootableContainerBlockEntity lootableDest = (LootableContainerBlockEntity) dest;
List<Item> checked = new ArrayList<>();
Boolean found = false;
Boolean whitelist = hasAnyItem(entity.getItems());
if (whitelist) {
Item item = findNextItem(entity.getItems(), checked);
while(!found && item != null) {
checked.add(item);
found = transferOneStack(lootableSource, lootableDest, item, whitelist);
item = findNextItem(entity.getItems(), checked);
}
} else {
transferOneStack(lootableSource, lootableDest, null, whitelist);
}
transferOneStack(lootableSource, lootableDest, entity.getWhiteList(), entity.getBlackList());
}
}
}
private static final Boolean hasAnyItem(DefaultedList<ItemStack> list) {
Iterator<ItemStack> i = list.iterator();
while (i.hasNext()) {
ItemStack s = i.next();
if (s != null && s.getCount() > 0) {
return true;
private static final Boolean transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest, List<ItemStack> whiteList, List<ItemStack> blackList) {
// whitelist behaviour
List<Item> checked = new ArrayList<>();
// this way, we block whitelist items that are in the blacklist
for (ItemStack stack : blackList) {
if (stack != null && !stack.isEmpty()) {
checked.add(stack.getItem());
}
}
return false;
Boolean found = false;
Item matchItem = findNextItem(whiteList, checked);
while(!found && matchItem != null) {
checked.add(matchItem);
List<Item> matchItems = new ArrayList<>();
matchItems.add(matchItem);
found = transferOneStack(source, dest, matchItems, true, !hasItems(whiteList));
matchItem = findNextItem(whiteList, checked);
}
// blacklist behaviour
// for all the items that are not in the (already handled) whitelist and not in the blacklist, handle the transport
List<Item> ignoreItems = new ArrayList<>();
for (ItemStack stack : blackList) {
if (stack != null && !stack.isEmpty()) {
ignoreItems.add(stack.getItem());
}
}
for (ItemStack stack : whiteList) {
if (stack != null && !stack.isEmpty()) {
ignoreItems.add(stack.getItem());
}
}
if (!found) {
found = transferOneStack(source, dest, ignoreItems, false, !hasItems(whiteList));
}
return found;
}
private static final Boolean transferOneStack(LootableContainerBlockEntity source, LootableContainerBlockEntity dest,
Item filterItem, Boolean whitelist) {
List<Item> ignoreItems, Boolean whitelist, Boolean emptyWhitelist) {
Boolean result = false;
Integer sourceSlot = findItemStackPos(source, filterItem, whitelist);
Integer sourceSlot = findItemStackPos(source, ignoreItems, whitelist, emptyWhitelist);
if (sourceSlot != null && !Items.AIR.equals(source.getStack(sourceSlot).getItem())) {
ItemStack sourceStack = source.getStack(sourceSlot);
Integer destSlot = findItemStackPos(dest, sourceStack);
@ -155,6 +197,14 @@ public class BlockStackerEntity extends BlockEntity implements NamedScreenHandle
return result;
}
private static final Boolean hasItems(List<ItemStack> list) {
Boolean result = false;
for (ItemStack stack : list) {
result = result || (stack != null && !stack.isEmpty() && stack.getCount() > 0);
}
return result;
}
private static final Item findNextItem(List<ItemStack> inventory, List<Item> exclude) {
for (ItemStack stack : inventory) {
if (!stack.isEmpty()) {
@ -193,19 +243,26 @@ public class BlockStackerEntity extends BlockEntity implements NamedScreenHandle
return null;
}
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, Item item, Boolean whitelist) {
if (item == null) {
return findItemStackPos(lcbe, false);
} else {
if (whitelist == null) {
whitelist = true;
LOGGER.error("whitelist is null");
private static final Integer findItemStackPos(LootableContainerBlockEntity lcbe, List<Item> filterItems, Boolean whitelist, Boolean emptyWhitelist) {
if (whitelist == null) {
whitelist = true;
LOGGER.error("whitelist is null");
}
if (filterItems == null || filterItems.size() < 1) {
if (whitelist) {
return null;
} else if (emptyWhitelist) {
return findItemStackPos(lcbe, false);
} else {
LOGGER.error("no filter items, but whitelist is not empty");
return null;
}
} else {
Integer counter = lcbe.size();
while (counter > 0) {
counter--;
ItemStack stack = lcbe.getStack(counter);
Boolean found = whitelist ? item.equals(stack.getItem()) : true;
Boolean found = whitelist ? filterItems.contains(stack.getItem()) : (!emptyWhitelist && !filterItems.contains(stack.getItem()));
if (found) {
return counter;
}

View File

@ -2,6 +2,7 @@ package de.jottyfan.minecraft.quickiefabric.container;
import com.mojang.blaze3d.systems.RenderSystem;
import de.jottyfan.minecraft.quickiefabric.init.RegistryManager;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
@ -20,7 +21,7 @@ import net.minecraft.util.Identifier;
@Environment(EnvType.CLIENT)
public class BlockStackerScreen extends HandledScreen<BlockStackerScreenHandler>
implements ScreenHandlerProvider<BlockStackerScreenHandler> {
private final static Identifier TEXTURE = new Identifier("minecraft", "textures/gui/container/dispenser.png");
private final static Identifier TEXTURE = new Identifier(RegistryManager.QUICKIEFABRIC, "textures/gui/blockstacker.png");
public BlockStackerScreen(BlockStackerScreenHandler handler, PlayerInventory inventory, Text text) {
super(handler, inventory, text);

View File

@ -16,7 +16,7 @@ import net.minecraft.screen.slot.Slot;
*/
public class BlockStackerScreenHandler extends ScreenHandler {
public static final Integer SLOTSIZE = 9;
public static final Integer SLOTSIZE = 18;
private final Inventory inventory;
@ -31,14 +31,23 @@ public class BlockStackerScreenHandler extends ScreenHandler {
inventory.onOpen(playerInventory.player);
int m;
int l;
// whitelist
for (m = 0; m < 3; ++m) {
for (l = 0; l < 3; ++l) {
this.addSlot(new Slot(inventory, l + m * 3, 62 + l * 18, 17 + m * 18));
this.addSlot(new Slot(inventory, l + m * 3, 8 + l * 18, 17 + m * 18));
}
}
// blacklist
for (m = 0; m < 3; ++m) {
for (l = 0; l < 3; ++l) {
this.addSlot(new Slot(inventory, l + m * 3 + 9, 116 + l * 18, 17 + m * 18));
}
}
for (m = 0; m < 3; ++m) {
for (l = 0; l < 9; ++l) {
this.addSlot(new Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 84 + m * 18));
this.addSlot(new Slot(playerInventory, l + m * 9 + 18, 8 + l * 18, 84 + m * 18));
}
}
for (m = 0; m < 9; ++m) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB