Skip to content

Instantly share code, notes, and snippets.

@falseresync
Created February 3, 2024 11:40
Show Gist options
  • Save falseresync/3fb9b973d93055e2118e6171081cfd46 to your computer and use it in GitHub Desktop.
Save falseresync/3fb9b973d93055e2118e6171081cfd46 to your computer and use it in GitHub Desktop.
public class InventoryDescription {
protected final Int2ObjectMap<SlotDescription> slots = new Int2ObjectRBTreeMap<>();
protected final Int2ObjectMap<BiPredicate<@Nullable Direction, ItemStack>> insertionRules = new Int2ObjectRBTreeMap<>();
protected final Int2ObjectMap<BiPredicate<@Nullable Direction, ItemStack>> extractionRules = new Int2ObjectRBTreeMap<>();
public SlotDescription describeSlot(int index, @Nullable Predicate<ItemStack> inputFilter, @Nullable Predicate<ItemStack> outputFilter) {
Preconditions.checkArgument(index >= 0, "Slot indices must be non-negative");
Preconditions.checkArgument(!slots.containsKey(index), "Slot with index %d already exists", index);
final Predicate<ItemStack> normalizedInputFilter = inputFilter == null ? Predicates.alwaysTrue() : inputFilter;
final Predicate<ItemStack> normalizedOutputFilter = outputFilter == null ? Predicates.alwaysTrue() : outputFilter;
var slotDescription = new SlotDescription() {
@Override
public boolean canInsert(ItemStack stack) {
return normalizedInputFilter.test(stack);
}
@Override
public boolean canExtract(ItemStack stack) {
return normalizedOutputFilter.test(stack);
}
@Override
public int getIndex() {
return index;
}
};
slots.put(index, slotDescription);
insertionRules.computeIfAbsent(index, key -> (side, stack) -> true);
extractionRules.computeIfAbsent(index, key -> (side, stack) -> true);
return slotDescription;
}
public InventoryDescription addInsertionRule(int slot, BiPredicate<@Nullable Direction, ItemStack> rule) {
insertionRules.compute(slot, (key, oldValue) -> oldValue == null ? rule : oldValue.and(rule));
return this;
}
public InventoryDescription addExtractionRule(int slot, BiPredicate<@Nullable Direction, ItemStack> rule) {
extractionRules.compute(slot, (key, oldValue) -> oldValue == null ? rule : oldValue.and(rule));
return this;
}
public ImplementedInventory generateInventory(Runnable onDirty) {
return new ImplementedInventory() {
private final DefaultedList<ItemStack> items = DefaultedList.ofSize(slots.size(), ItemStack.EMPTY);
@Override
public DefaultedList<ItemStack> getItems() {
return items;
}
@Override
public boolean canInsert(int slot, ItemStack stack, @Nullable Direction side) {
return isValid(slot, stack) && insertionRules.get(slot).test(side, stack);
}
@Override
public boolean canExtract(int slot, ItemStack stack, Direction side) {
return extractionRules.get(slot).test(side, stack);
}
@Override
public boolean isValid(int slot, ItemStack stack) {
return slots.get(slot).canInsert(stack);
}
@Override
public void markDirty() {
onDirty.run();
}
};
}
}
public interface SlotDescription {
boolean canInsert(ItemStack stack);
boolean canExtract(ItemStack stack);
int getIndex();
}
// In your BE, Entity or wherever
protected static final InventoryDescription INV_DESC = new InventoryDescription();
public static final SlotDescription FUEL_SLOT = INV_DESC.describeSlot(0, stack -> FuelRegistry.INSTANCE.get(stack.getItem()) != null, null);
protected final ImplementedInventory inventory = INV_DESC.generateInventory(this::markDirty);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment