Untitled
unknown
java
a year ago
19 kB
14
Indexable
package realmayus.youmatter.creator; 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.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.BucketItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FlowingFluid; import net.minecraft.world.level.material.Fluid; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.templates.FluidTank; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; import org.jetbrains.annotations.NotNull; import realmayus.youmatter.ModContent; import realmayus.youmatter.YMConfig; import realmayus.youmatter.replicator.ReplicatorBlockEntity; import realmayus.youmatter.util.GeneralUtils; import realmayus.youmatter.util.MyEnergyStorage; import realmayus.youmatter.util.json.filter.FluidFilterManager; import realmayus.youmatter.util.temperature.Status; import realmayus.youmatter.util.temperature.TemperatureUtils; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; import java.util.Objects; public class CreatorBlockEntity extends BlockEntity implements MenuProvider { public CreatorBlockEntity(BlockPos pos, BlockState state) { super(ModContent.CREATOR_BLOCK_ENTITY.get(), pos, state); } private static final int MAX_UMATTER = 16000; private static final int MAX_STABILIZER = 16000; private boolean isActivated = true; boolean isProducing = false; boolean isActivated() { return isActivated; } public void setActivated(boolean activated) { isActivated = activated; setChanged(); if (level != null && !level.isClientSide) { level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); } } @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { if (cap == ForgeCapabilities.ITEM_HANDLER) { return inventory.cast(); } if (cap == ForgeCapabilities.ENERGY) { return myEnergyStorage.cast(); } if (cap == ForgeCapabilities.FLUID_HANDLER) { return fluidHandler.cast(); } return super.getCapability(cap, side); } public LazyOptional<ItemStackHandler> inventory = LazyOptional.of(() -> new ItemStackHandler(5) { @Override protected void onContentsChanged(int slot) { CreatorBlockEntity.this.setChanged(); } }); private final FluidTank uTank = new FluidTank(MAX_UMATTER) { @Override protected void onContentsChanged() { BlockState state = level.getBlockState(worldPosition); level.sendBlockUpdated(worldPosition, state, state, 3); setChanged(); } }; private final FluidTank sTank = new FluidTank(MAX_STABILIZER) { @Override protected void onContentsChanged() { BlockState state = level.getBlockState(worldPosition); level.sendBlockUpdated(worldPosition, state, state, 3); setChanged(); } }; FluidTank getUTank() { return uTank; } FluidTank getSTank() { return sTank; } private final LazyOptional<IFluidHandler> fluidHandler = LazyOptional.of(() -> new IFluidHandler() { @Override public int getTanks() { return 2; } @Nonnull @Override public FluidStack getFluidInTank(int tank) { if (tank == 0) { return uTank.getFluid(); } else if (tank == 1) { return sTank.getFluid(); } return null; } @Override public int getTankCapacity(int tank) { if (tank == 0) { return MAX_UMATTER; } else if (tank == 1) { return MAX_STABILIZER; } return 0; } @Override @Deprecated public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { if (tank == 0) { return false; } else return tank == 1 && FluidFilterManager.getFluids().stream().anyMatch(s -> s.equals(stack.getFluid())); } @Override @Deprecated public int fill(FluidStack resource, FluidAction action) { if (FluidFilterManager.getFluids().stream().anyMatch(s -> s.equals(resource.getFluid()))) { if (MAX_STABILIZER - getSTank().getFluidAmount() < resource.getAmount()) { return sTank.fill(new FluidStack(resource.getFluid(), MAX_STABILIZER), action); } else { return sTank.fill(resource, action); } } return 0; } @Nonnull @Override public FluidStack drain(FluidStack resource, FluidAction action) { if (resource.getFluid().equals(ModContent.UMATTER.get())) { if (uTank.getFluidAmount() < resource.getAmount()) { uTank.drain(uTank.getFluid(), action); return uTank.getFluid(); } else { uTank.drain(resource, action); return resource; } } return null; } @Nonnull @Override public FluidStack drain(int maxDrain, FluidAction action) { if (uTank.getFluid().getFluid() != null) { return uTank.drain(uTank.getFluid(), action); } else { return null; } } }); public void setTemperature(float temperature) { temperatureUtils.resolve().get().setTemperature(temperature); } public double getTemperature() { return temperatureUtils.resolve().get().getTemperature(); } public double getMaxTemperature() { return temperatureUtils.resolve().get().getMaxTemperature(); } public Status getStatus() { return temperatureUtils.resolve().get().getStatus(getTemperature(), getMaxTemperature());} private final LazyOptional<TemperatureUtils> temperatureUtils = LazyOptional.of(() -> new TemperatureUtils(this, 0.0, 1.0, 2000.0)); public int getEnergy() { return myEnergyStorage.resolve().get().getEnergyStored(); } public void setEnergy(int energy) { myEnergyStorage.resolve().get().setEnergy(energy); } private final LazyOptional<MyEnergyStorage> myEnergyStorage = LazyOptional.of(() -> new MyEnergyStorage(this, 1000000, Integer.MAX_VALUE)); @Override public void setRemoved() { super.setRemoved(); inventory.invalidate(); myEnergyStorage.invalidate(); fluidHandler.invalidate(); } @Override public void load(CompoundTag compound) { super.load(compound); if (compound.contains("uTank")) { CompoundTag tagUTank = compound.getCompound("uTank"); uTank.readFromNBT(tagUTank); } if (compound.contains("sTank")) { CompoundTag tagSTank = compound.getCompound("sTank"); sTank.readFromNBT(tagSTank); } if (compound.contains("temperature")) { setTemperature(compound.getFloat("temperature")); } if (compound.contains("energy")) { setEnergy(compound.getInt("energy")); } if (compound.contains("isActivated")) { isActivated = compound.getBoolean("isActivated"); } if (compound.contains("inventory")) { inventory.resolve().get().deserializeNBT((CompoundTag) compound.get("inventory")); } } @Override public void saveAdditional(CompoundTag compound) { super.saveAdditional(compound); CompoundTag tagSTank = new CompoundTag(); CompoundTag tagUTank = new CompoundTag(); sTank.writeToNBT(tagSTank); uTank.writeToNBT(tagUTank); compound.put("uTank", tagUTank); compound.put("sTank", tagSTank); compound.putDouble("temperature", getTemperature()); compound.putInt("energy", getEnergy()); compound.putBoolean("isActivated", isActivated); if (compound.contains("inventory")) { inventory.resolve().get().deserializeNBT((CompoundTag) compound.get("inventory")); } } @Override public CompoundTag getUpdateTag() { return saveWithoutMetadata(); } @Override public ClientboundBlockEntityDataPacket getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } private int currentPartTick = 0; private void meltdown(Level level, BlockPos pos) { if (YMConfig.CONFIG.creatorExplodes.get()) { if (!level.isClientSide()) { level.destroyBlock(this.getBlockPos(), false); level.explode(null, pos.getX(), pos.getY(), pos.getZ(), 16.0F, Level.ExplosionInteraction.TNT); } } } public static void tick(Level level, BlockPos pos, BlockState state, CreatorBlockEntity be) { be.tick(level, pos, state); } @Deprecated public void tick(Level level, BlockPos pos, BlockState state) { if (currentPartTick == 20) { if (getStatus() == Status.MELTDOWN) { meltdown(level, pos); } isProducing = isActivated() && getEnergy() >= 0.3f * 1000000; if (isProducing) { temperatureUtils.ifPresent(temperatureUtils -> { temperatureUtils.heat(100.0F); int production = TemperatureUtils.calculateProduction(getTemperature()); if (uTank.getFluidAmount() + production <= MAX_UMATTER) { uTank.fill(new FluidStack(ModContent.UMATTER.get(), production), IFluidHandler.FluidAction.EXECUTE); myEnergyStorage.ifPresent(storage -> storage.extractEnergy(Math.round(getEnergy() / 3f), false)); } }); } //Auto-outputting U-Matter Object[] neighborTE = getNeighborTileEntity(pos); if (neighborTE != null) { if (uTank.getFluidAmount() >= 1000) { // set a maximum output of 500 mB (every two seconds) uTank.drain(level.getBlockEntity((BlockPos) neighborTE[0]).getCapability(ForgeCapabilities.FLUID_HANDLER, (Direction) neighborTE[1]).map(h -> h.fill(new FluidStack(ModContent.UMATTER.get(), 1000), IFluidHandler.FluidAction.EXECUTE)).orElse(0), IFluidHandler.FluidAction.EXECUTE); } else { uTank.drain(level.getBlockEntity((BlockPos) neighborTE[0]).getCapability(ForgeCapabilities.FLUID_HANDLER, (Direction) neighborTE[1]).map(h -> h.fill(new FluidStack(ModContent.UMATTER.get(), uTank.getFluidAmount()), IFluidHandler.FluidAction.EXECUTE)).orElse(0), IFluidHandler.FluidAction.EXECUTE); } } currentPartTick = 0; } else if ((currentPartTick % 5) == 0) { // every five ticks inventory.ifPresent(inventory -> { if (!(inventory.getStackInSlot(3).isEmpty()) && GeneralUtils.canAddItemToSlot(inventory.getStackInSlot(4), inventory.getStackInSlot(3), false)) { ItemStack item = inventory.getStackInSlot(3); if (item.getItem() instanceof BucketItem) { if (getUTank().getFluidAmount() >= 1000) { getUTank().drain(1000, IFluidHandler.FluidAction.EXECUTE); inventory.setStackInSlot(3, ItemStack.EMPTY); inventory.insertItem(4, new ItemStack(ModContent.UMATTER_BUCKET.get(), 1), false); } } else { item.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresent(h -> { if (h.getFluidInTank(0).getFluid().isSame(ModContent.UMATTER.get()) || h.getFluidInTank(0).isEmpty()) { if (h.getTankCapacity(0) - h.getFluidInTank(0).getAmount() < getUTank().getFluidAmount()) { //fluid in S-Tank is more than what fits in the item's tank getUTank().drain(h.fill(new FluidStack(ModContent.UMATTER.get(), h.getTankCapacity(0) - h.getFluidInTank(0).getAmount()), IFluidHandler.FluidAction.EXECUTE), IFluidHandler.FluidAction.EXECUTE); } else { //S-Tank's fluid fits perfectly in item's tank getUTank().drain(h.fill(getUTank().getFluid(), IFluidHandler.FluidAction.EXECUTE), IFluidHandler.FluidAction.EXECUTE); } } }); inventory.setStackInSlot(3, ItemStack.EMPTY); inventory.insertItem(4, item, false); } } if (!inventory.getStackInSlot(1).isEmpty()) { ItemStack item = inventory.getStackInSlot(1); if (item.getItem() instanceof BucketItem && GeneralUtils.canAddItemToSlot(inventory.getStackInSlot(2), new ItemStack(Items.BUCKET, 1), false)) { item.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresent(h -> { if (!h.getFluidInTank(0).isEmpty() && isFluidAllowed(h.getFluidInTank(0).getFluid())) { if (MAX_STABILIZER - getSTank().getFluidAmount() >= 1000) { if(getSTank().isEmpty() || getSTank().getFluidInTank(0).getFluid().isSame(h.getFluidInTank(0).getFluid())) { getSTank().fill(new FluidStack(h.getFluidInTank(0).getFluid(), 1000), IFluidHandler.FluidAction.EXECUTE); inventory.setStackInSlot(1, ItemStack.EMPTY); inventory.insertItem(2, new ItemStack(Items.BUCKET, 1), false); } } } }); } else if(GeneralUtils.canAddItemToSlot(inventory.getStackInSlot(2), inventory.getStackInSlot(1), false)) { item.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresent(h -> { if (isFluidAllowed(h.getFluidInTank(0).getFluid())) { if (h.getFluidInTank(0).getAmount() > MAX_STABILIZER - getSTank().getFluidAmount()) { //given fluid is more than what fits in the S-Tank if (getSTank().isEmpty() || getSTank().getFluidInTank(0).getFluid().isSame(h.getFluidInTank(0).getFluid())) { getSTank().fill(h.drain(MAX_STABILIZER - getSTank().getFluidAmount(), IFluidHandler.FluidAction.EXECUTE), IFluidHandler.FluidAction.EXECUTE); } } else { if (getSTank().isEmpty() || getSTank().getFluidInTank(0).getFluid().isSame(h.getFluidInTank(0).getFluid())) { //given fluid fits perfectly in S-Tank getSTank().fill(h.drain(h.getFluidInTank(0).getAmount(), IFluidHandler.FluidAction.EXECUTE), IFluidHandler.FluidAction.EXECUTE); } } } }); inventory.setStackInSlot(1, ItemStack.EMPTY); inventory.insertItem(2, item, false); } } }); currentPartTick++; } else { currentPartTick++; } } @Deprecated private boolean isFluidAllowed(Fluid fluid) { boolean matches = FluidFilterManager.getFluids().stream().anyMatch(s -> s.equals(fluid)); if (FluidFilterManager.getFilterMode() && matches) { return false; } else return FluidFilterManager.getFilterMode() || matches; } private Object[] getNeighborTileEntity(BlockPos creatorPos) { HashMap<BlockPos, Direction> foundPos = new HashMap<>(); for(Direction facing : Direction.values()) { BlockPos offsetPos = creatorPos.relative(facing); BlockEntity offsetBe = level.getBlockEntity(offsetPos); if(offsetBe != null) { offsetBe.getCapability(ForgeCapabilities.FLUID_HANDLER, facing).ifPresent(x -> foundPos.put(offsetPos, facing)); } } // Prioritize Replicator for (Map.Entry<BlockPos, Direction> entry : foundPos.entrySet()) { if (level.getBlockEntity(entry.getKey()) instanceof ReplicatorBlockEntity replicator) { if(replicator.getCapability(ForgeCapabilities.FLUID_HANDLER, entry.getValue()).map(h -> h.fill(new FluidStack(ModContent.UMATTER.get(), 1000), IFluidHandler.FluidAction.SIMULATE)).orElse(0) > 0) { //Replicator can take fluid return new Object[] {entry.getKey(), entry.getValue()}; // position, facing } } } // Replicator not found / can't take fluid, now trying other blocks for (Map.Entry<BlockPos, Direction> entry : foundPos.entrySet()) { if(Objects.requireNonNull(level.getBlockEntity(entry.getKey())).getCapability(ForgeCapabilities.FLUID_HANDLER, entry.getValue()).map(h -> h.fill(new FluidStack(ModContent.UMATTER.get(), 1000), IFluidHandler.FluidAction.SIMULATE)).orElse(0) > 0) { //Tile can take fluid return new Object[] {entry.getKey(), entry.getValue()}; // position, facing } } // found nothing return null; } @Override public Component getDisplayName() { return Component.translatable(ModContent.CREATOR_BLOCK.get().getDescriptionId()); } @Nullable @Override public AbstractContainerMenu createMenu(int windowID, Inventory playerInventory, Player playerEntity) { return new CreatorMenu(windowID, level, worldPosition, playerInventory, playerEntity); } }
Editor is loading...
Leave a Comment