Simplify and add item handler to everything

This commit is contained in:
DBotThePony 2021-08-16 12:29:57 +07:00
parent aedb169eca
commit 0cc978d1c2
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 252 additions and 186 deletions

View File

@ -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<IItemHandler> 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);
}

View File

@ -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<IMatterHandler> matter_resolver = LazyOptional.of(() -> matter);
private final LazyOptional<IItemHandler> 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<IItemHandler> 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

View File

@ -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<IItemHandler> 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 <T> LazyOptional<T> getCapability(@Nonnull Capability<T> 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

View File

@ -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

View File

@ -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);
}
}
}