diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 6c7f39037..fa6bc672e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -36,6 +37,8 @@ import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.storage.ItemStackWrapper; import ru.dbotthepony.mc.otm.storage.StorageObjectRegistry; +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -46,6 +49,8 @@ import java.util.stream.Collectors; // The value here should match an entry in the META-INF/mods.toml file @Mod(OverdriveThatMatters.MOD_ID) +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault public class OverdriveThatMatters { // Directly reference a log4j logger. public static final String MOD_ID = "overdrive_that_matters"; diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/BlockCargoCrate.java b/src/main/java/ru/dbotthepony/mc/otm/block/BlockCargoCrate.java index b0f5cfb0a..f49e99c2f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/BlockCargoCrate.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/BlockCargoCrate.java @@ -2,7 +2,6 @@ package ru.dbotthepony.mc.otm.block; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; -import net.minecraft.world.Container; import net.minecraft.world.Containers; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; @@ -47,7 +46,7 @@ public class BlockCargoCrate extends BlockMatteryRotatable implements EntityBloc BlockEntity blockentity = level.getBlockEntity(block_pos); if (blockentity instanceof BlockEntityCargoCrate crate) { - Containers.dropContents(level, block_pos, crate.slots); + Containers.dropContents(level, block_pos, crate.container); level.updateNeighbourForOutputSignal(block_pos, this); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java index 53a0c322d..d620f74df 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java @@ -53,29 +53,29 @@ public class BlockEntityAndroidStation extends BlockEntityMatteryPowered impleme if (tile.isBlockedByRedstone()) return; - BlockPos pos = tile.getBlockPos(); + final var pos = tile.getBlockPos(); List entities = tile.getLevel().getEntitiesOfClass(LivingEntity.class, new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1)); for (LivingEntity ent : entities) { - Optional resolver = ent.getCapability(MatteryCapability.ANDROID).resolve(); + final var resolver = ent.getCapability(MatteryCapability.ANDROID).resolve(); if (resolver.isEmpty()) continue; - IAndroidCapability capability = resolver.get(); + final var capability = resolver.get(); if (!capability.isAndroid()) continue; - BigDecimal missing = capability.getMissingPower(); + final var missing = capability.getMissingPower(); - if (missing.compareTo(BigDecimal.ZERO) == 1) { - BigDecimal extract = tile.energy.extractEnergyInner(missing, true); + if (missing.compareTo(BigDecimal.ZERO) > 0) { + final var extract = tile.energy.extractEnergyInner(missing, true); - if (extract.compareTo(BigDecimal.ZERO) == 1) { - BigDecimal received = capability.receiveEnergyOuter(extract, true); + if (extract.compareTo(BigDecimal.ZERO) > 0) { + final var received = capability.receiveEnergyOuter(extract, true); - if (received.compareTo(BigDecimal.ZERO) == 1) { + if (received.compareTo(BigDecimal.ZERO) > 0) { tile.energy.extractEnergyInner(extract, false); capability.receiveEnergyOuter(extract, false); } 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 d49602d17..ac4fae505 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 @@ -6,6 +6,7 @@ import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -66,21 +67,13 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { } - public static class BatteryBankEnergy implements IMatteryEnergyStorage { + public record BatteryBankEnergy(BlockEntityBatteryBank tile, BankMode mode) implements IMatteryEnergyStorage { public enum BankMode { RECEIVE, EXTRACT, BIDIRECTIONAL } - private final BlockEntityBatteryBank tile; - private final BankMode mode; - - BatteryBankEnergy(BlockEntityBatteryBank tile, BankMode mode) { - this.tile = tile; - this.mode = mode; - } - @Override public boolean canExtract() { return mode == BankMode.EXTRACT || mode == BankMode.BIDIRECTIONAL; @@ -246,13 +239,13 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { } public final BatteryBankEnergy energy_receiver = new BatteryBankEnergy(this, BatteryBankEnergy.BankMode.RECEIVE); - public final LazyOptional energy_receiver_resolver = LazyOptional.of(() -> energy_receiver); + private LazyOptional energy_receiver_resolver = LazyOptional.of(() -> energy_receiver); public final BatteryBankEnergy energy_extractor = new BatteryBankEnergy(this, BatteryBankEnergy.BankMode.EXTRACT); - public final LazyOptional energy_extractor_resolver = LazyOptional.of(() -> energy_extractor); + private LazyOptional energy_extractor_resolver = LazyOptional.of(() -> energy_extractor); public final BatteryBankEnergy energy = new BatteryBankEnergy(this, BatteryBankEnergy.BankMode.BIDIRECTIONAL); - public final LazyOptional energy_resolver = LazyOptional.of(() -> energy); + private LazyOptional energy_resolver = LazyOptional.of(() -> energy); protected boolean valid = true; @@ -289,12 +282,24 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { public void invalidateCaps() { super.invalidateCaps(); valid = false; + energy_receiver_resolver.invalidate(); + energy_extractor_resolver.invalidate(); + energy_resolver.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + energy_receiver_resolver = LazyOptional.of(() -> energy_receiver); + energy_extractor_resolver = LazyOptional.of(() -> energy_extractor); + energy_resolver = LazyOptional.of(() -> energy); + } + + @Override + public void setLevel(Level p_155231_) { + super.setLevel(p_155231_); + tickOnceServer(this::checkSurroundings); } @Nonnull @@ -315,34 +320,52 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { return super.getCapability(cap, side); } + protected LazyOptional output_cap_mte = LazyOptional.empty(); + protected LazyOptional output_cap_fe = LazyOptional.empty(); + + protected void _checkSurroundings() { + if (level instanceof ServerLevel level) + checkSurroundings(level); + } + + public void checkSurroundings(Level level) { + if (isRemoved()) + return; + + final var get_entity = level.getBlockEntity(getBlockPos().offset(getBlockState().getValue(BlockMatteryRotatable.FACING).getNormal())); + + if (get_entity == null) { + output_cap_mte = LazyOptional.empty(); + output_cap_fe = LazyOptional.empty(); + return; + } + + output_cap_mte = getAndBind(output_cap_mte, get_entity, MatteryCapability.ENERGY, getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite(), this::_checkSurroundings); + output_cap_fe = getAndBind(output_cap_fe, get_entity, CapabilityEnergy.ENERGY, getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite(), this::_checkSurroundings); + } + public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { if (t instanceof BlockEntityBatteryBank tile) { if (tile.isBlockedByRedstone()) return; - BlockEntity get_entity = level.getBlockEntity(blockPos.offset(tile.getBlockState().getValue(BlockMatteryRotatable.FACING).getNormal())); + if (tile.output_cap_mte.isPresent()) { + final var cap = tile.output_cap_mte.resolve().get(); - if (get_entity != null) { - Optional cap = get_entity.getCapability(MatteryCapability.ENERGY, tile.getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite()).resolve(); + if (cap.canReceive()) { + BatteryBankDistribution distribution = tile.energy.getDistribution(false); + BigDecimal diff = cap.receiveEnergyOuter(distribution.max_throughput, true); + diff = tile.energy.extractEnergyOuter(diff, false); + cap.receiveEnergyOuter(diff, false); + } + } else if (tile.output_cap_fe.isPresent()) { + final var cap = tile.output_cap_fe.resolve().get(); - if (cap.isPresent()) { - if (cap.get().canReceive()) { - BatteryBankDistribution distribution = tile.energy.getDistribution(false); - BigDecimal diff = cap.get().receiveEnergyOuter(distribution.max_throughput, true); - diff = tile.energy.extractEnergyOuter(diff, false); - cap.get().receiveEnergyOuter(diff, false); - } - } else { - Optional cap2 = get_entity.getCapability(CapabilityEnergy.ENERGY, tile.getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite()).resolve(); - - if (cap2.isPresent()) { - if (cap2.get().canReceive()) { - BatteryBankDistribution distribution = tile.energy.getDistribution(false); - BigDecimal diff = MatteryCapability.floodFE(cap2.get(), distribution.max_throughput, true); - diff = tile.energy.extractEnergyOuter(diff, false); - MatteryCapability.floodFE(cap2.get(), diff, false); - } - } + if (cap.canReceive()) { + BatteryBankDistribution distribution = tile.energy.getDistribution(false); + BigDecimal diff = MatteryCapability.floodFE(cap, distribution.max_throughput, true); + diff = tile.energy.extractEnergyOuter(diff, false); + MatteryCapability.floodFE(cap, diff, false); } } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityCargoCrate.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityCargoCrate.java index 2f4b6304f..609304bd8 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityCargoCrate.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityCargoCrate.java @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.block.entity; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; @@ -9,13 +10,17 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.level.block.Block; -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 ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.BlockCargoCrate; import ru.dbotthepony.mc.otm.container.MatteryContainer; +import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; import ru.dbotthepony.mc.otm.menu.CargoCrateMenu; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -37,22 +42,44 @@ public class BlockEntityCargoCrate extends BlockEntityMattery { } } - public final MatteryContainer slots = new MatteryContainer(this::setChanged, 9 * 6); + public final MatteryContainer container = new MatteryContainer(this::setChanged, 9 * 6); + public final MatteryContainerHandler item_handler = container.handler(); public BlockEntityCargoCrate(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.CARGO_CRATE, p_155229_, p_155230_); } + @Override + public void invalidateCaps() { + super.invalidateCaps(); + item_handler.invalidate(); + } + + @Override + public void reviveCaps() { + super.reviveCaps(); + item_handler.revive(); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + return item_handler.get().cast(); + + return super.getCapability(cap, side); + } + @Override public CompoundTag save(CompoundTag nbt) { - nbt.put("slots", slots.serializeNBT()); + nbt.put("slots", container.serializeNBT()); return super.save(nbt); } @Override public void load(CompoundTag nbt) { super.load(nbt); - slots.deserializeNBT(nbt.get("slots")); + container.deserializeNBT(nbt.get("slots")); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java index 2eefcc93f..8c1ad0345 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterBottler.java @@ -25,6 +25,7 @@ import ru.dbotthepony.mc.otm.capability.matter.IMatterGridCell; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability; import ru.dbotthepony.mc.otm.container.MatteryContainer; +import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu; @@ -71,6 +72,20 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen } }; + public final MatteryContainerHandler work_slots_handler = work_slots.handler((slot, stack) -> { + if (work_flow) { + return slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent(); + } + + return slot >= 3 && stack.getCapability(MatteryCapability.MATTER).isPresent(); + }, (slot, amount, stack) -> { + if (work_flow) { + return slot >= 3; + } + + return slot < 3; + }); + public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.BIDIRECTIONAL, new BigDecimal(4)) { @Nonnull @Override @@ -82,24 +97,7 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen private static final BigDecimal MATTER_EXCHANGE_RATE = new BigDecimal("0.04"); private static final BigDecimal ENERGY_CONSUMPTION = new BigDecimal(20); - private final LazyOptional matter_resolver = LazyOptional.of(() -> matter); - private final LazyOptional cell_resolver = LazyOptional.of(() -> this); - - private final LazyOptional handler_resolver = LazyOptional.of(() -> { - return work_slots.handler((slot, stack) -> { - if (work_flow) { - return slot < 3 && stack.getCapability(MatteryCapability.MATTER).isPresent(); - } - - return slot >= 3 && stack.getCapability(MatteryCapability.MATTER).isPresent(); - }, (slot, amount, stack) -> { - if (work_flow) { - return slot >= 3; - } - - return slot < 3; - }); - }); + private LazyOptional cell_resolver = LazyOptional.of(() -> this); protected BigDecimal initial_capacity; protected ItemStack last_work_stack; @@ -142,12 +140,18 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen public void invalidateCaps() { super.invalidateCaps(); valid = false; + work_slots_handler.invalidate(); + matter.invalidate(); + cell_resolver.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + work_slots_handler.revive(); + matter.revive(); + cell_resolver = LazyOptional.of(() -> this); } @Nonnull @@ -155,11 +159,11 @@ public class BlockEntityMatterBottler extends BlockEntityMatteryPowered implemen public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { if (valid) { if (cap == MatteryCapability.MATTER) { - return matter_resolver.cast(); + return matter.get().cast(); } if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { - return handler_resolver.cast(); + return work_slots_handler.get().cast(); } if (cap == MatteryCapability.MATTER_CELL) { diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCable.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCable.java index b9c3813db..b62fd575e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCable.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCable.java @@ -31,19 +31,21 @@ public class BlockEntityMatterCable extends BlockEntity implements IMatterGridCe private MatterGrid grid; - private final LazyOptional resolver_grid = LazyOptional.of(() -> this); + private LazyOptional resolver_grid = LazyOptional.of(() -> this); private boolean valid = true; @Override public void invalidateCaps() { super.invalidateCaps(); valid = false; + resolver_grid.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + resolver_grid = LazyOptional.of(() -> this); } @Nonnull diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java index 16fef6766..66be9ef05 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterCapacitorBank.java @@ -146,7 +146,7 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement } }; - private final LazyOptional resolver = LazyOptional.of(() -> matter); + private LazyOptional resolver = LazyOptional.of(() -> matter); public final MatteryContainer matter_container = new MatteryContainer(this::setChanged, 6 * 2) { @Override @@ -202,15 +202,19 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement public void invalidateCaps() { super.invalidateCaps(); valid = false; + resolver.invalidate(); + resolver_grid.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + resolver = LazyOptional.of(() -> matter); + resolver_grid = LazyOptional.of(() -> this); } - private final LazyOptional resolver_grid = LazyOptional.of(() -> this); + private LazyOptional resolver_grid = LazyOptional.of(() -> this); @Nonnull @Override 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 0951351ac..a2309b045 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 @@ -42,7 +42,7 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem 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 LazyOptional matter_resolver = LazyOptional.of(() -> matter); // вход, выход public final MatteryContainer item_container = new MatteryContainer(this::setChanged, 2); @@ -96,15 +96,19 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryWorker implem public void reviveCaps() { valid = true; super.reviveCaps(); + matter_resolver = LazyOptional.of(() -> matter); + resolver_grid = LazyOptional.of(() -> this); } @Override public void invalidateCaps() { valid = false; super.invalidateCaps(); + matter_resolver.invalidate(); + resolver_grid.invalidate(); } - private final LazyOptional resolver_grid = LazyOptional.of(() -> this); + private LazyOptional resolver_grid = LazyOptional.of(() -> this); @Nonnull @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterPanel.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterPanel.java index 887dd8592..06c8d7265 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterPanel.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterPanel.java @@ -63,15 +63,17 @@ public class BlockEntityMatterPanel extends BlockEntityMattery implements IMatte public void invalidateCaps() { super.invalidateCaps(); valid = false; + resolver.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + resolver = LazyOptional.of(() -> this); } - private final LazyOptional resolver = LazyOptional.of(() -> this); + private LazyOptional resolver = LazyOptional.of(() -> this); @Nonnull @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java index 260a1707c..5f37cb05f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.java @@ -15,7 +15,6 @@ 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.Registry; import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker; import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob; @@ -24,6 +23,7 @@ import ru.dbotthepony.mc.otm.block.entity.worker.WorkTickContext; import ru.dbotthepony.mc.otm.capability.*; import ru.dbotthepony.mc.otm.capability.matter.*; import ru.dbotthepony.mc.otm.container.MatteryContainer; +import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu; @@ -49,9 +49,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem // запросы от matter replicator interface public final MatteryContainer reserved_slots = new MatteryContainer(this::setChanged, 3); - private final LazyOptional resolve_handler = LazyOptional.of(() -> regular_slots.handler( - (slot, stack) -> false - )); + private final MatteryContainerHandler slots_handler = regular_slots.handler((slot, stack) -> false); private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_replicator"); @@ -231,15 +229,19 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem public void invalidateCaps() { super.invalidateCaps(); valid = false; + slots_handler.invalidate(); + resolver_self.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + slots_handler.revive(); + resolver_self = LazyOptional.of(() -> this); } - private final LazyOptional resolver_self = LazyOptional.of(() -> this); + private LazyOptional resolver_self = LazyOptional.of(() -> this); @Nonnull @Override @@ -249,7 +251,7 @@ public class BlockEntityMatterReplicator extends BlockEntityMatteryWorker implem return resolver_self.cast(); if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - return resolve_handler.cast(); + return slots_handler.get().cast(); } return super.getCapability(cap, side); 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 f6eef3132..cb4a6d2fd 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 @@ -21,6 +21,7 @@ import ru.dbotthepony.mc.otm.block.entity.worker.MachineJob; import ru.dbotthepony.mc.otm.block.entity.worker.MachineJobStatus; import ru.dbotthepony.mc.otm.capability.*; import ru.dbotthepony.mc.otm.capability.matter.*; +import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.matter.MatterRegistry; import ru.dbotthepony.mc.otm.Registry; @@ -41,10 +42,10 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement public final MatteryContainer input_slot = new MatteryContainer(this::setChanged, 1); - private final LazyOptional handler_resolver = LazyOptional.of(() -> input_slot.handler( + private final MatteryContainerHandler input_handler = input_slot.handler( (slot, stack) -> MatterRegistry.canDecompose(stack), (slot, amount, stack) -> is_idling - )); + ); public BlockEntityMatterScanner(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_); @@ -53,14 +54,14 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement private boolean valid = true; - private final LazyOptional resolver_grid = LazyOptional.of(() -> this); + private LazyOptional resolver_grid = LazyOptional.of(() -> this); @Nonnull @Override public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { if (valid) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - return handler_resolver.cast(); + return input_handler.get().cast(); if (cap == MatteryCapability.MATTER_CELL) return resolver_grid.cast(); @@ -73,12 +74,16 @@ public class BlockEntityMatterScanner extends BlockEntityMatteryWorker implement public void invalidateCaps() { super.invalidateCaps(); valid = false; + input_handler.invalidate(); + resolver_grid.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + input_handler.revive(); + resolver_grid = LazyOptional.of(() -> this); } @Override diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMattery.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMattery.java index 02ec1f3ba..4aa4b9509 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMattery.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMattery.java @@ -1,12 +1,15 @@ package ru.dbotthepony.mc.otm.block.entity; import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.StringTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; @@ -16,13 +19,20 @@ 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.minecraft.world.level.chunk.LevelChunk; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.LazyOptional; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import java.lang.ref.WeakReference; import java.util.UUID; +import java.util.function.Consumer; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault +@SuppressWarnings("unused") public abstract class BlockEntityMattery extends BlockEntity implements MenuProvider { protected Component display_name; protected RedstoneSetting redstone_setting = RedstoneSetting.LOW; @@ -38,6 +48,58 @@ public abstract class BlockEntityMattery extends BlockEntity implements MenuProv abstract protected Component getDefaultDisplayName(); + protected void tickOnce(Runnable func) { + if (level != null) + OverdriveThatMatters.tickOnce(level, func); + } + + protected void tickOnceServer(Runnable func) { + if (level instanceof ServerLevel level) + OverdriveThatMatters.tickOnce(level, func); + } + + protected void tickOnceClient(Runnable func) { + if (level instanceof ClientLevel level) + OverdriveThatMatters.tickOnce(level, func); + } + + protected void tickOnce(Consumer func) { + if (level != null) + OverdriveThatMatters.tickOnce(level, func); + } + + protected void tickOnceServer(Consumer func) { + if (level instanceof ServerLevel level) + OverdriveThatMatters.tickOnce(level, func); + } + + protected void tickOnceClient(Consumer func) { + if (level instanceof ClientLevel level) + OverdriveThatMatters.tickOnce(level, func); + } + + protected LazyOptional getAndBind(LazyOptional old, @Nullable ICapabilityProvider provider, Capability cap, @Nullable Direction side, Runnable invalidate) { + final var get = provider != null ? provider.getCapability(cap, side) : LazyOptional.empty(); + + if (old != get) { + if (get.isPresent()) { + final var ref = new WeakReference<>(invalidate); + + get.addListener((l) -> { + final var self = ref.get(); + + if (self != null) { + self.run(); + } + }); + } + + return get.cast(); + } + + return get.cast(); + } + @Override public Component getDisplayName() { return display_name != null ? display_name : getDefaultDisplayName(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java index 78bae28bd..bfbf93dca 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPowered.java @@ -26,7 +26,7 @@ import java.util.Optional; @ParametersAreNonnullByDefault abstract public class BlockEntityMatteryPowered extends BlockEntityMattery { protected MatteryMachineEnergyStorage energy = null; - protected final LazyOptional energy_resolver = LazyOptional.of(() -> energy);; + private LazyOptional energy_resolver = LazyOptional.of(() -> energy); private boolean valid = true; public MatteryContainer battery_container = new MatteryContainer(this::setChanged, 1); @@ -38,40 +38,40 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery { if (energy.getMissingPower().compareTo(BigDecimal.ZERO) <= 0) return; - BigDecimal demand = energy.getMissingPower(); + var demand = energy.getMissingPower(); + + if (demand.compareTo(BigDecimal.ZERO) == 0) + return; + demand = demand.min(energy.receiveEnergyOuter(demand, true)); for (int i = 0; i < battery_container.getContainerSize() && demand.compareTo(BigDecimal.ZERO) > 0; i++) { - ItemStack stack = battery_container.getItem(i); + final var stack = battery_container.getItem(i); if (!stack.isEmpty()) { - Optional mattery_storage = stack.getCapability(MatteryCapability.ENERGY).resolve(); + final var mattery_storage = stack.getCapability(MatteryCapability.ENERGY).resolve(); if (mattery_storage.isPresent()) { - IMatteryEnergyStorage storage = mattery_storage.get(); - - BigDecimal drain = storage.extractEnergyOuter(demand, true); + final var drain = mattery_storage.get().extractEnergyOuter(demand, true); if (drain.compareTo(BigDecimal.ZERO) != 0) { - BigDecimal receive = energy.receiveEnergyOuter(drain, true); + final var receive = energy.receiveEnergyOuter(drain, true); - storage.extractEnergyOuter(receive, false); + mattery_storage.get().extractEnergyOuter(receive, false); energy.receiveEnergyOuter(receive, false); demand = demand.subtract(receive, MatteryCapability.ROUND_RULES); } - } else if (demand.compareTo(BigDecimal.ONE) >= 0) { - Optional storage = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); + } else { + final var storage = stack.getCapability(CapabilityEnergy.ENERGY).resolve(); if (storage.isPresent()) { - IEnergyStorage energy_fe = storage.get(); - - BigDecimal drain = MatteryCapability.drainFE(energy_fe, demand, true); + final var drain = MatteryCapability.drainFE(storage.get(), demand, true); if (drain.compareTo(BigDecimal.ZERO) != 0) { - BigDecimal receive = energy.receiveEnergyOuter(drain, true); + final var receive = energy.receiveEnergyOuter(drain, true); - MatteryCapability.drainFE(energy_fe, receive, false); + MatteryCapability.drainFE(storage.get(), receive, false); energy.receiveEnergyOuter(receive, false); demand = demand.subtract(receive, MatteryCapability.ROUND_RULES); @@ -90,12 +90,14 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery { public void invalidateCaps() { super.invalidateCaps(); valid = false; + energy_resolver.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + energy_resolver = LazyOptional.of(() -> energy); } @Nonnull @@ -109,14 +111,16 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery { @Override public CompoundTag save(CompoundTag nbt) { - nbt.put("energy_cap", energy.serializeNBT()); + if (energy != null) + nbt.put("energy_cap", energy.serializeNBT()); + nbt.put("battery_container", battery_container.serializeNBT()); return super.save(nbt); } public void load(CompoundTag nbt) { - if (nbt.contains("energy_cap") && nbt.get("energy_cap") instanceof CompoundTag tag) + if (energy != null && nbt.get("energy_cap") instanceof CompoundTag tag) energy.deserializeNBT(tag); if (nbt.contains("battery_container") && nbt.get("battery_container") instanceof CompoundTag tag) 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 9a41af173..0dcc085bd 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 @@ -21,6 +21,7 @@ import net.minecraftforge.items.IItemHandler; import ru.dbotthepony.mc.otm.block.BlockPatternStorage; import ru.dbotthepony.mc.otm.capability.*; import ru.dbotthepony.mc.otm.capability.matter.*; +import ru.dbotthepony.mc.otm.container.MatteryContainerHandler; import ru.dbotthepony.mc.otm.matter.MatterGrid; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.container.MatteryContainer; @@ -78,9 +79,9 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa } } - private final LazyOptional resolver_item = LazyOptional.of(() -> patterns.handler( + private final MatteryContainerHandler resolver_item = patterns.handler( ((slot, stack) -> stack.getCapability(MatteryCapability.PATTERN).isPresent()) - )); + ); private MatterGrid grid; @@ -138,12 +139,14 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa public void invalidateCaps() { super.invalidateCaps(); valid = false; + resolver_item.invalidate(); } @Override public void reviveCaps() { super.reviveCaps(); valid = true; + resolver_item.revive(); } private final LazyOptional resolver = LazyOptional.of(() -> this); @@ -156,7 +159,7 @@ public class BlockEntityPatternStorage extends BlockEntityMattery implements IMa return resolver.cast(); if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - return resolver_item.cast(); + return resolver_item.get().cast(); } return super.getCapability(cap, side); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java index b0952e143..5164abcd0 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/matter/MatterHandlerCapability.java @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.capability.matter; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.nbt.CompoundTag; import net.minecraftforge.common.util.INBTSerializable; +import net.minecraftforge.common.util.LazyOptional; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.matter.MatterRegistry; @@ -45,6 +46,20 @@ public class MatterHandlerCapability implements IMatterHandler, INBTSerializable this.max_extract = max_extract; } + private LazyOptional handler = LazyOptional.of(() -> this); + + public void invalidate() { + handler.invalidate(); + } + + public void revive() { + handler = LazyOptional.of(() -> this); + } + + public LazyOptional get() { + return handler; + } + @Nonnull @Override public BigDecimal getStoredMatter() { 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 469bc9336..48c5544ce 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainer.java +++ b/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainer.java @@ -164,21 +164,21 @@ public class MatteryContainer implements Container, Iterable { protected MatteryContainerHandler handler; - public IItemHandler handler(MatteryContainerInsertValidator insert_validator, MatteryContainerExtractValidator extract_validator) { + public MatteryContainerHandler 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) { + public MatteryContainerHandler handler(MatteryContainerInsertValidator insert_validator) { if (handler != null) return handler; return handler = new MatteryContainerHandler(this, insert_validator); } - public IItemHandler handler() { + public MatteryContainerHandler handler() { if (handler != null) return handler; diff --git a/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.java b/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.java index 2a70337b4..df5d3eb72 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.java +++ b/src/main/java/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.java @@ -1,11 +1,12 @@ package ru.dbotthepony.mc.otm.container; import net.minecraft.world.item.ItemStack; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandler; import javax.annotation.Nonnull; -class MatteryContainerHandler implements IItemHandler { +public class MatteryContainerHandler implements IItemHandler { private final MatteryContainer container; private final MatteryContainerInsertValidator insert_validator; private final MatteryContainerExtractValidator extract_validator; @@ -24,6 +25,20 @@ class MatteryContainerHandler implements IItemHandler { this(container, insert_validator, (slot, amount, stack) -> true); } + private LazyOptional handler = LazyOptional.of(() -> this); + + public LazyOptional get() { + return handler; + } + + public void invalidate() { + handler.invalidate(); + } + + public void revive() { + handler = LazyOptional.of(() -> this); + } + @Override public int getSlots() { return container.getContainerSize(); diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/CargoCrateMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/CargoCrateMenu.java index ead196df6..e65a68d9e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/CargoCrateMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/CargoCrateMenu.java @@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.menu; import net.minecraft.world.SimpleContainer; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.block.entity.BlockEntity; import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.entity.BlockEntityCargoCrate; import ru.dbotthepony.mc.otm.menu.slot.MatterySlot; @@ -17,7 +16,7 @@ public class CargoCrateMenu extends MatteryMenu { public CargoCrateMenu(int p_38852_, Inventory inventory, BlockEntityCargoCrate tile) { super(Registry.Menus.CARGO_CRATE, p_38852_, inventory, tile); - var container = tile != null ? tile.slots : new SimpleContainer(9 * 6); + var container = tile != null ? tile.container : new SimpleContainer(9 * 6); for (int i = 0; i < container.getContainerSize(); i++) { crate_slots[i] = new MatterySlot(container, i);