From 0cc978d1c2a1d5254c121e3d656f3d1bf9be157e Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 16 Aug 2021 12:29:57 +0700 Subject: [PATCH] Simplify and add item handler to everything --- .../block/entity/BlockEntityBatteryBank.java | 17 +- .../entity/BlockEntityMatterDecomposer.java | 96 +-------- .../entity/BlockEntityMatterScanner.java | 40 +++- .../entity/BlockEntityPatternStorage.java | 95 +-------- .../mc/otm/container/MatteryContainer.java | 190 +++++++++++++++++- 5 files changed, 252 insertions(+), 186 deletions(-) diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java index dce538c66..4f2a2d88e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java @@ -16,6 +16,9 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.IEnergyStorage; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import ru.dbotthepony.mc.otm.MatterRegistry; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; @@ -30,7 +33,12 @@ import java.util.Optional; public class BlockEntityBatteryBank extends BlockEntityMattery { // 5 на 3 - public MatteryContainer battery_container = new MatteryContainer(this::setChanged, 5 * 3); + public final MatteryContainer battery_container = new MatteryContainer(this::setChanged, 5 * 3); + + private final LazyOptional item_handler_resolver = LazyOptional.of(() -> battery_container.handler( + (slot, stack) -> stack.getCapability(CapabilityEnergy.ENERGY).isPresent(), + (slot, amount, stack) -> true + )); public static class BatteryBankDistribution { private final BigDecimal[] distribution; @@ -252,9 +260,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { @Override public void load(CompoundTag nbt) { - if (nbt.contains("battery_bank") && nbt.get("battery_bank") instanceof CompoundTag tag) - battery_container = MatteryContainer.of(this::setChanged, tag, battery_container.getContainerSize()); - + battery_container.deserializeNBT(nbt.get("battery_bank")); super.load(nbt); } @@ -295,6 +301,9 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { return energy_receiver_resolver.cast(); } + if (valid && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + return item_handler_resolver.cast(); + return super.getCapability(cap, side); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java index a77c5d4e3..7707a07b4 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java @@ -25,104 +25,25 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.math.BigDecimal; -public class BlockEntityMatterDecomposer extends BlockEntityMatteryPoweredWorker implements IItemHandler, IMatterGridCell { +public class BlockEntityMatterDecomposer extends BlockEntityMatteryPoweredWorker implements IMatterGridCell { private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_decomposer"); private boolean valid = true; public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.EXTRACT, new BigDecimal("20")); private final LazyOptional matter_resolver = LazyOptional.of(() -> matter); - private final LazyOptional handler_resolver = LazyOptional.of(() -> this); // вход, выход - public MatteryContainer item_container = new MatteryContainer(this::setChanged, 2); + public final MatteryContainer item_container = new MatteryContainer(this::setChanged, 2); + + private final LazyOptional handler_resolver = LazyOptional.of(() -> item_container.handler( + (slot, stack) -> slot == 0 && MatterRegistry.hasMatterValue(stack), + (slot, amount, stack) -> slot == 1 + )); public BlockEntityMatterDecomposer(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.MATTER_DECOMPOSER, p_155229_, p_155230_); energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(400_000), new BigDecimal(2000), new BigDecimal(2000)); } - @Override - public int getSlots() { - return item_container.getContainerSize(); - } - - @Nonnull - @Override - public ItemStack getStackInSlot(int slot) { - return item_container.getItem(slot); - } - - @Nonnull - @Override - public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { - if (slot != 0) - return stack; - - if (!MatterRegistry.hasMatterValue(stack)) - return stack; - - ItemStack self_stack = item_container.getItem(slot); - - if (self_stack.isEmpty()) { - if (!simulate) { - item_container.setItem(slot, stack.copy()); - } - - return ItemStack.EMPTY; - } else if (self_stack.isStackable() && self_stack.getMaxStackSize() > self_stack.getCount() && ItemStack.isSameItemSameTags(self_stack, stack)) { - int new_count = Math.min(self_stack.getMaxStackSize(), self_stack.getCount() + stack.getCount()); - int diff = new_count - self_stack.getCount(); - - if (diff != 0) { - if (!simulate) { - self_stack.grow(diff); - item_container.setChanged(); - } - - ItemStack copy = stack.copy(); - copy.shrink(diff); - return copy; - } - } - - return stack; - } - - @Nonnull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (slot != 1 || amount == 0) - return ItemStack.EMPTY.copy(); - - if (amount < 0) - throw new IllegalArgumentException("Can not extract negative amount of items"); - - ItemStack self_stack = item_container.getItem(slot); - - if (self_stack.isEmpty()) - return ItemStack.EMPTY.copy(); - - int minimal = Math.min(amount, self_stack.getCount()); - ItemStack copy = self_stack.copy(); - copy.setCount(minimal); - - if (!simulate) { - self_stack.shrink(minimal); - item_container.setChanged(); - } - - return copy; - } - - @Override - public int getSlotLimit(int slot) { - return item_container.getMaxStackSize(); - } - - @Override - public boolean isItemValid(int slot, @Nonnull ItemStack stack) { - return slot == 0 && MatterRegistry.hasMatterValue(stack); - } - @Override protected Component getDefaultDisplayName() { return MACHINE_NAME; @@ -155,8 +76,7 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPoweredWorker if (nbt.contains("matter_capability") && nbt.get("matter_capability") instanceof CompoundTag tag) matter.deserializeNBT(tag); - if (nbt.contains("work_slots") && nbt.get("work_slots") instanceof CompoundTag tag) - item_container = MatteryContainer.of(this::setChanged, tag, item_container.getContainerSize()); + item_container.deserializeNBT(nbt.get("work_slots")); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java index 795b9f666..21f43438c 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.java @@ -14,6 +14,10 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; import ru.dbotthepony.mc.otm.IMatterGridCell; import ru.dbotthepony.mc.otm.MatterGrid; import ru.dbotthepony.mc.otm.MatterRegistry; @@ -32,13 +36,41 @@ import java.util.Collection; public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker implements IMatterGridCell { private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_scanner"); - public MatteryContainer input_slot = new MatteryContainer(this::setChanged, 1); + public final MatteryContainer input_slot = new MatteryContainer(this::setChanged, 1); + + private final LazyOptional handler_resolver = LazyOptional.of(() -> input_slot.handler( + (slot, stack) -> MatterRegistry.hasMatterValue(stack), + (slot, amount, stack) -> is_idling + )); public BlockEntityMatterScanner(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_); energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(40000), new BigDecimal(400), new BigDecimal(400)); } + private boolean valid = true; + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (valid && cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + return handler_resolver.cast(); + + return super.getCapability(cap, side); + } + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + valid = false; + } + + @Override + public void reviveCaps() { + super.reviveCaps(); + valid = true; + } + @Override public void notifyPatternsChanged() { is_idling = false; @@ -68,9 +100,7 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker im @Override public void load(CompoundTag nbt) { - if (nbt.get("work_slots") instanceof CompoundTag tag) - input_slot = input_slot.of(tag); - + input_slot.deserializeNBT(nbt.get("work_slots")); super.load(nbt); } @@ -194,7 +224,7 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker im @Override public boolean isValidMatterCell() { - return !isRemoved(); + return valid; } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityPatternStorage.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityPatternStorage.java index 980f00c7e..7df60758d 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityPatternStorage.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityPatternStorage.java @@ -31,12 +31,17 @@ import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.atomic.AtomicInteger; -public class BlockEntityPatternStorage extends BlockEntityMattery implements IMatterGridCell, IItemHandler, IPatternStorage { +public class BlockEntityPatternStorage extends BlockEntityMattery implements IMatterGridCell, IPatternStorage { public BlockEntityPatternStorage(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_); } - public MatteryContainer patterns = new MatteryContainer(this::setChangedPatterns, 3 * 3); + public final MatteryContainer patterns = new MatteryContainer(this::setChangedPatterns, 3 * 3) { + @Override + public int getMaxStackSize() { + return 1; + } + }; private void setChangedPatterns() { setChanged(); @@ -47,80 +52,6 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa private MatterGrid grid; - @Override - public int getSlots() { - return patterns.getContainerSize(); - } - - @Nonnull - @Override - public ItemStack getStackInSlot(int slot) { - return patterns.getItem(slot); - } - - @Nonnull - @Override - public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { - if (stack.getCapability(MatteryCapability.PATTERN).resolve().isEmpty()) - return stack; - - ItemStack self_stack = patterns.getItem(slot); - - if (self_stack.isEmpty()) { - if (!simulate) { - patterns.setItem(slot, stack.copy()); - } - - return ItemStack.EMPTY; - } else if (self_stack.isStackable() && self_stack.getMaxStackSize() > self_stack.getCount() && ItemStack.isSameItemSameTags(self_stack, stack)) { - int new_count = Math.min(self_stack.getMaxStackSize(), self_stack.getCount() + stack.getCount()); - int diff = new_count - self_stack.getCount(); - - if (diff != 0) { - if (!simulate) { - self_stack.grow(diff); - patterns.setChanged(); - } - - ItemStack copy = stack.copy(); - copy.shrink(diff); - return copy; - } - } - - return stack; - } - - @Nonnull - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (amount <= 0) - return ItemStack.EMPTY; - - ItemStack stack = patterns.getItem(slot); - - if (stack.isEmpty()) - return ItemStack.EMPTY; - - if (!stack.isStackable()) { - if (!simulate) { - patterns.setItem(slot, ItemStack.EMPTY); - } - - return stack.copy(); - } - - ItemStack copy = stack.copy(); - copy.setCount(Math.min(amount, stack.getCount())); - - if (!simulate) { - stack.shrink(copy.getCount()); - patterns.setChanged(); - } - - return copy; - } - @Override public CompoundTag save(CompoundTag nbt) { nbt.put("patterns", patterns.serializeNBT()); @@ -130,17 +61,7 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa @Override public void load(CompoundTag nbt) { super.load(nbt); - patterns = patterns.of(nbt.get("patterns")); - } - - @Override - public int getSlotLimit(int slot) { - return 1; - } - - @Override - public boolean isItemValid(int slot, @Nonnull ItemStack stack) { - return stack.getCapability(MatteryCapability.PATTERN).isPresent(); + patterns.deserializeNBT(nbt.get("patterns")); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainer.java b/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainer.java index e4c6e6b69..8d09eeb55 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainer.java @@ -6,6 +6,7 @@ import net.minecraft.nbt.Tag; import net.minecraft.world.SimpleContainer; import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.items.IItemHandler; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -13,6 +14,7 @@ import java.util.function.Consumer; public class MatteryContainer extends SimpleContainer { protected final Runnable watcher; + protected boolean ignore_change_notifications = false; public MatteryContainer(Runnable watcher, int i) { super(i); @@ -23,7 +25,35 @@ public class MatteryContainer extends SimpleContainer { if (tag == null) return this; - return MatteryContainer.of(watcher, tag, getContainerSize()); + MatteryContainer container = MatteryContainer.of(watcher, tag, getContainerSize()); + + if (handler != null) + container.handler = handler.cloneOf(container); + + return container; + } + + public void deserializeNBT(@Nullable CompoundTag tag) { + ignore_change_notifications = true; + + for (int i = 0; i < getContainerSize(); i++) { + setItem(i, ItemStack.EMPTY); + } + + if (tag == null) { + ignore_change_notifications = false; + return; + } + + // нам не интересен размер + + if (tag.get("items") instanceof ListTag list) + for (int i = 0; i < Math.min(list.size(), getContainerSize()); i++) + if (list.get(i) instanceof CompoundTag get_tag) + setItem(i, ItemStack.of(get_tag)); + + ignore_change_notifications = false; + setChanged(); } public MatteryContainer of(@Nullable Tag tag) { @@ -31,11 +61,20 @@ public class MatteryContainer extends SimpleContainer { return this; if (tag instanceof CompoundTag compound) - return MatteryContainer.of(watcher, compound, getContainerSize()); + return of(watcher, compound, getContainerSize()); return this; } + public void deserializeNBT(@Nullable Tag tag) { + if (tag == null) + return; + + if (tag instanceof CompoundTag compound) { + deserializeNBT(compound); + } + } + public MatteryContainer(Runnable watcher, ItemStack... p_19152_) { super(p_19152_); this.watcher = watcher; @@ -59,6 +98,9 @@ public class MatteryContainer extends SimpleContainer { @Override public void setChanged() { + if (ignore_change_notifications) + return; + super.setChanged(); watcher.run(); } @@ -102,4 +144,148 @@ public class MatteryContainer extends SimpleContainer { return false; } + + @FunctionalInterface + public interface MatteryContainerInsertValidator { + boolean apply(int slot, @Nonnull ItemStack stack); + } + + @FunctionalInterface + public interface MatteryContainerExtractValidator { + boolean apply(int slot, int amount, @Nonnull ItemStack stack); + } + + protected MatteryContainerHandler handler; + + public IItemHandler handler(MatteryContainerInsertValidator insert_validator, MatteryContainerExtractValidator extract_validator) { + if (handler != null) + return handler; + + return handler = new MatteryContainerHandler(this, insert_validator, extract_validator); + } + + public IItemHandler handler(MatteryContainerInsertValidator insert_validator) { + if (handler != null) + return handler; + + return handler = new MatteryContainerHandler(this, insert_validator); + } + + public IItemHandler handler() { + if (handler != null) + return handler; + + return handler = new MatteryContainerHandler(this); + } + + public int getMaxStackSize(int slot) { + return getMaxStackSize(); + } + + static class MatteryContainerHandler implements IItemHandler { + private final MatteryContainer container; + private final MatteryContainerInsertValidator insert_validator; + private final MatteryContainerExtractValidator extract_validator; + + MatteryContainerHandler(MatteryContainer container, MatteryContainerInsertValidator insert_validator, MatteryContainerExtractValidator extract_validator) { + this.container = container; + this.insert_validator = insert_validator; + this.extract_validator = extract_validator; + } + + MatteryContainerHandler(MatteryContainer container) { + this(container, (slot, stack) -> true, (slot, amount, stack) -> true); + } + + MatteryContainerHandler(MatteryContainer container, MatteryContainerInsertValidator insert_validator) { + this(container, insert_validator, (slot, amount, stack) -> true); + } + + @Override + public int getSlots() { + return container.getContainerSize(); + } + + @Nonnull + @Override + public ItemStack getStackInSlot(int slot) { + return container.getItem(slot); + } + + @Nonnull + @Override + public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { + if (!insert_validator.apply(slot, stack)) + return stack; + + ItemStack self_stack = container.getItem(slot); + + if (self_stack.isEmpty()) { + if (!simulate) { + container.setItem(slot, stack.copy()); + } + + return ItemStack.EMPTY; + } else if (self_stack.isStackable() && self_stack.getMaxStackSize() > self_stack.getCount() && ItemStack.isSameItemSameTags(self_stack, stack)) { + int new_count = Math.min(self_stack.getMaxStackSize(), self_stack.getCount() + stack.getCount()); + int diff = new_count - self_stack.getCount(); + + if (diff != 0) { + if (!simulate) { + self_stack.grow(diff); + container.setChanged(); + } + + ItemStack copy = stack.copy(); + copy.shrink(diff); + return copy; + } + } + + return stack; + } + + @Nonnull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (amount == 0) + return ItemStack.EMPTY; + + if (amount < 0) + throw new IllegalArgumentException("Can not extract negative amount of items"); + + ItemStack self_stack = container.getItem(slot); + + if (self_stack.isEmpty()) + return ItemStack.EMPTY; + + if (!extract_validator.apply(slot, amount, self_stack)) + return ItemStack.EMPTY; + + int minimal = Math.min(amount, self_stack.getCount()); + ItemStack copy = self_stack.copy(); + copy.setCount(minimal); + + if (!simulate) { + self_stack.shrink(minimal); + container.setChanged(); + } + + return copy; + } + + @Override + public int getSlotLimit(int slot) { + return container.getMaxStackSize(); + } + + @Override + public boolean isItemValid(int slot, @Nonnull ItemStack stack) { + return insert_validator.apply(slot, stack); + } + + MatteryContainerHandler cloneOf(MatteryContainer container) { + return new MatteryContainerHandler(container, insert_validator, extract_validator); + } + } }